Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions crates/mysten-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ edition = "2021"
publish = false

[dependencies]
snap.workspace = true
tokio.workspace = true
futures.workspace = true
parking_lot.workspace = true
reqwest.workspace = true
fastcrypto.workspace = true
mysten-metrics.workspace = true
sui-tls.workspace = true
sui-types.workspace = true
tracing.workspace = true
prometheus.workspace = true
anyhow.workspace = true
1 change: 1 addition & 0 deletions crates/mysten-common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

pub mod metrics;
pub mod sync;
97 changes: 97 additions & 0 deletions crates/mysten-common/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use mysten_metrics::RegistryService;
use prometheus::Encoder;
use std::time::{SystemTime, UNIX_EPOCH};
use tracing::{debug, error, info};

pub struct MetricsPushClient {
certificate: std::sync::Arc<sui_tls::SelfSignedCertificate>,
client: reqwest::Client,
}

impl MetricsPushClient {
pub fn new(metrics_key: sui_types::crypto::NetworkKeyPair) -> Self {
use fastcrypto::traits::KeyPair;
let certificate = std::sync::Arc::new(sui_tls::SelfSignedCertificate::new(
metrics_key.private(),
sui_tls::SUI_VALIDATOR_SERVER_NAME,
));
let identity = certificate.reqwest_identity();
let client = reqwest::Client::builder()
.identity(identity)
.build()
.unwrap();

Self {
certificate,
client,
}
}

pub fn certificate(&self) -> &sui_tls::SelfSignedCertificate {
&self.certificate
}

pub fn client(&self) -> &reqwest::Client {
&self.client
}
}

pub async fn push_metrics(
client: &MetricsPushClient,
url: &reqwest::Url,
registry: &RegistryService,
) -> Result<(), anyhow::Error> {
info!(push_url =% url, "pushing metrics to remote");

// now represents a collection timestamp for all of the metrics we send to the proxy
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis() as i64;

let mut metric_families = registry.gather_all();
for mf in metric_families.iter_mut() {
for m in mf.mut_metric() {
m.set_timestamp_ms(now);
}
}

let mut buf: Vec<u8> = vec![];
let encoder = prometheus::ProtobufEncoder::new();
encoder.encode(&metric_families, &mut buf)?;

let mut s = snap::raw::Encoder::new();
let compressed = s.compress_vec(&buf).map_err(|err| {
error!("unable to snappy encode; {err}");
err
})?;

let response = client
.client()
.post(url.to_owned())
.header(reqwest::header::CONTENT_ENCODING, "snappy")
.header(reqwest::header::CONTENT_TYPE, prometheus::PROTOBUF_FORMAT)
.body(compressed)
.send()
.await?;

if !response.status().is_success() {
let status = response.status();
let body = match response.text().await {
Ok(body) => body,
Err(error) => format!("couldn't decode response body; {error}"),
};
return Err(anyhow::anyhow!(
"metrics push failed: [{}]:{}",
status,
body
));
}

debug!("successfully pushed metrics to {url}");

Ok(())
}
3 changes: 1 addition & 2 deletions crates/sui-bridge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ edition = "2021"

[dependencies]
ethers = "2.0"
snap = "1.1.0"
tokio = { workspace = true, features = ["full"] }
sui-types.workspace = true
sui-authority-aggregation.workspace = true
Expand All @@ -26,7 +25,6 @@ mysten-metrics.workspace = true
sui-sdk.workspace = true
sui-keys.workspace = true
sui-config.workspace = true
sui-tls.workspace = true
clap.workspace = true
tracing.workspace = true
bin-version.workspace = true
Expand All @@ -46,6 +44,7 @@ rand.workspace = true
lru.workspace = true
shared-crypto.workspace = true
backoff.workspace = true
mysten-common.workspace = true
enum_dispatch.workspace = true
sui-json-rpc-api.workspace = true
sui-test-transaction-builder.workspace = true
Expand Down
95 changes: 3 additions & 92 deletions crates/sui-bridge/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
// SPDX-License-Identifier: Apache-2.0

use crate::config::MetricsConfig;
use mysten_common::metrics::{push_metrics, MetricsPushClient};
use mysten_metrics::RegistryService;
use prometheus::{
register_histogram_vec_with_registry, register_int_counter_vec_with_registry,
register_int_counter_with_registry, register_int_gauge_vec_with_registry,
register_int_gauge_with_registry, Encoder, HistogramVec, IntCounter, IntCounterVec, IntGauge,
register_int_gauge_with_registry, HistogramVec, IntCounter, IntCounterVec, IntGauge,
IntGaugeVec, Registry,
};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::time::Duration;
use sui_types::crypto::NetworkKeyPair;
use tracing::error;

const FINE_GRAINED_LATENCY_SEC_BUCKETS: &[f64] = &[
0.001, 0.005, 0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.6, 0.7, 0.8, 0.9,
Expand All @@ -20,39 +20,6 @@ const FINE_GRAINED_LATENCY_SEC_BUCKETS: &[f64] = &[
200., 250., 300., 350., 400.,
];

pub struct MetricsPushClient {
certificate: std::sync::Arc<sui_tls::SelfSignedCertificate>,
client: reqwest::Client,
}

impl MetricsPushClient {
pub fn new(metrics_key: sui_types::crypto::NetworkKeyPair) -> Self {
use fastcrypto::traits::KeyPair;
let certificate = std::sync::Arc::new(sui_tls::SelfSignedCertificate::new(
metrics_key.private(),
sui_tls::SUI_VALIDATOR_SERVER_NAME,
));
let identity = certificate.reqwest_identity();
let client = reqwest::Client::builder()
.identity(identity)
.build()
.unwrap();

Self {
certificate,
client,
}
}

pub fn certificate(&self) -> &sui_tls::SelfSignedCertificate {
&self.certificate
}

pub fn client(&self) -> &reqwest::Client {
&self.client
}
}

/// Starts a task to periodically push metrics to a configured endpoint if a metrics push endpoint
/// is configured.
pub fn start_metrics_push_task(
Expand Down Expand Up @@ -80,62 +47,6 @@ pub fn start_metrics_push_task(

let mut client = MetricsPushClient::new(metrics_key_pair.copy());

// TODO (johnm) split this out into mysten-common
async fn push_metrics(
client: &MetricsPushClient,
url: &reqwest::Url,
registry: &RegistryService,
) -> Result<(), anyhow::Error> {
// now represents a collection timestamp for all of the metrics we send to the proxy
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis() as i64;

let mut metric_families = registry.gather_all();
for mf in metric_families.iter_mut() {
for m in mf.mut_metric() {
m.set_timestamp_ms(now);
}
}

let mut buf: Vec<u8> = vec![];
let encoder = prometheus::ProtobufEncoder::new();
encoder.encode(&metric_families, &mut buf)?;

let mut s = snap::raw::Encoder::new();
let compressed = s.compress_vec(&buf).map_err(|err| {
error!("unable to snappy encode; {err}");
err
})?;

let response = client
.client()
.post(url.to_owned())
.header(reqwest::header::CONTENT_ENCODING, "snappy")
.header(reqwest::header::CONTENT_TYPE, prometheus::PROTOBUF_FORMAT)
.body(compressed)
.send()
.await?;

if !response.status().is_success() {
let status = response.status();
let body = match response.text().await {
Ok(body) => body,
Err(error) => format!("couldn't decode response body; {error}"),
};
return Err(anyhow::anyhow!(
"metrics push failed: [{}]:{}",
status,
body
));
}

tracing::debug!("successfully pushed metrics to {url}");

Ok(())
}

tokio::spawn(async move {
tracing::info!(push_url =% url, interval =? interval, "Started Metrics Push Service");

Expand Down
1 change: 0 additions & 1 deletion crates/sui-node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ tower.workspace = true
reqwest.workspace = true
tap.workspace = true
serde.workspace = true
snap.workspace = true
bin-version.workspace = true
url.workspace = true
humantime.workspace = true
Expand Down
Loading
Loading