From 84e33bd3de1c34d234b1e7400e2fa8dd0b0c71ce Mon Sep 17 00:00:00 2001 From: Frando Date: Mon, 28 Apr 2025 11:44:43 +0200 Subject: [PATCH 1/6] refactor: update to latest iroh-metrics branch --- Cargo.lock | 45 +++++--------------------------- iroh-dns-server/Cargo.toml | 2 +- iroh-dns-server/src/metrics.rs | 2 +- iroh-dns-server/src/server.rs | 6 ++--- iroh-relay/Cargo.toml | 2 +- iroh-relay/src/server/metrics.rs | 21 +++------------ iroh/Cargo.toml | 4 +-- iroh/bench/Cargo.toml | 2 +- iroh/src/endpoint.rs | 4 +-- iroh/src/magicsock/metrics.rs | 2 +- iroh/src/metrics.rs | 27 +++---------------- iroh/src/net_report/metrics.rs | 2 +- 12 files changed, 27 insertions(+), 92 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 972a27de9ee..808220e1e5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1037,12 +1037,6 @@ dependencies = [ "litrs", ] -[[package]] -name = "dtoa" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" - [[package]] name = "dyn-clone" version = "1.0.18" @@ -2398,14 +2392,13 @@ dependencies = [ [[package]] name = "iroh-metrics" version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d64b607e49f67fa42b3e780109cad0fa1fdb476b4a78d4cf8443499bbc1ad0a" +source = "git+https://github.com/n0-computer/iroh-metrics?branch=Frando/derive-metricsgroupset#f8a2a047fc9f4232e0920501150efddc11be7060" dependencies = [ "http-body-util", "hyper", "hyper-util", "iroh-metrics-derive", - "prometheus-client", + "itoa", "reqwest", "serde", "thiserror 2.0.11", @@ -2416,8 +2409,7 @@ dependencies = [ [[package]] name = "iroh-metrics-derive" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caaa484b5f192006b1cc39261712d65baf87342fc72a4acc1560355d1dc410d9" +source = "git+https://github.com/n0-computer/iroh-metrics?branch=Frando/derive-metricsgroupset#f8a2a047fc9f4232e0920501150efddc11be7060" dependencies = [ "heck", "proc-macro2", @@ -2980,7 +2972,7 @@ dependencies = [ [[package]] name = "netwatch" version = "0.4.0" -source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics#ef897c745d78dbd19429bdf6131f91c9563c2c1a" +source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2#640166ea310788a1fabca4ea99fc8cb0c6ae70f4" dependencies = [ "atomic-waker", "bytes", @@ -3477,7 +3469,7 @@ checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "portmapper" version = "0.4.1" -source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics#ef897c745d78dbd19429bdf6131f91c9563c2c1a" +source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2#640166ea310788a1fabca4ea99fc8cb0c6ae70f4" dependencies = [ "base64", "bytes", @@ -3487,7 +3479,7 @@ dependencies = [ "igd-next", "iroh-metrics", "libc", - "netwatch 0.4.0 (git+https://github.com/n0-computer/net-tools?branch=Frando/metrics)", + "netwatch 0.4.0 (git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2)", "num_enum", "rand 0.8.5", "serde", @@ -3613,29 +3605,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prometheus-client" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" -dependencies = [ - "dtoa", - "itoa", - "parking_lot", - "prometheus-client-derive-encode", -] - -[[package]] -name = "prometheus-client-derive-encode" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.98", -] - [[package]] name = "proptest" version = "1.6.0" @@ -5594,7 +5563,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/iroh-dns-server/Cargo.toml b/iroh-dns-server/Cargo.toml index 5ada6ed0fff..f70c8eef873 100644 --- a/iroh-dns-server/Cargo.toml +++ b/iroh-dns-server/Cargo.toml @@ -28,7 +28,7 @@ governor = "0.6.3" #needs new release of tower_governor for 0.7.0 hickory-server = { version = "0.25.1", features = ["https-ring"] } http = "1.0.0" humantime-serde = "1.1.1" -iroh-metrics = { version = "0.33.0", features = ["metrics", "service"] } +iroh-metrics = { git = "https://github.com/n0-computer/iroh-metrics", branch = "Frando/derive-metricsgroupset", features = ["service"] } lru = "0.12.3" n0-future = "0.1.2" pkarr = { version = "2.3.1", features = [ "async", "relay", "dht"], default-features = false } diff --git a/iroh-dns-server/src/metrics.rs b/iroh-dns-server/src/metrics.rs index c0041cf02bf..301336e8f10 100644 --- a/iroh-dns-server/src/metrics.rs +++ b/iroh-dns-server/src/metrics.rs @@ -3,7 +3,7 @@ use iroh_metrics::{Counter, MetricsGroup}; /// Metrics for iroh-dns-server -#[derive(Debug, Clone, MetricsGroup)] +#[derive(Debug, Default, MetricsGroup)] #[metrics(name = "dns_server")] pub struct Metrics { /// Number of pkarr relay puts that updated the state diff --git a/iroh-dns-server/src/server.rs b/iroh-dns-server/src/server.rs index 8f5698af213..8ee9ceb9e93 100644 --- a/iroh-dns-server/src/server.rs +++ b/iroh-dns-server/src/server.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use anyhow::Result; -use iroh_metrics::{service::start_metrics_server, MetricsGroup}; +use iroh_metrics::service::start_metrics_server; use tracing::info; use crate::{ @@ -62,8 +62,8 @@ impl Server { let metrics_task = tokio::task::spawn(async move { if let Some(addr) = metrics_addr { let mut registry = iroh_metrics::Registry::default(); - metrics.register(&mut registry); - start_metrics_server(addr, std::sync::Arc::new(registry)).await?; + registry.register(metrics); + start_metrics_server(addr, Arc::new(registry)).await?; } Ok(()) }); diff --git a/iroh-relay/Cargo.toml b/iroh-relay/Cargo.toml index 8b94305d11f..e11f1829193 100644 --- a/iroh-relay/Cargo.toml +++ b/iroh-relay/Cargo.toml @@ -33,7 +33,7 @@ http-body-util = "0.1.0" hyper = { version = "1", features = ["server", "client", "http1"] } hyper-util = "0.1.1" iroh-base = { version = "0.34.1", path = "../iroh-base", default-features = false, features = ["key", "relay"] } -iroh-metrics = { version = "0.33", default-features = false } +iroh-metrics = { git = "https://github.com/n0-computer/iroh-metrics", branch = "Frando/derive-metricsgroupset", default-features = false } n0-future = "0.1.2" num_enum = "0.7" pin-project = "1" diff --git a/iroh-relay/src/server/metrics.rs b/iroh-relay/src/server/metrics.rs index 8e61dd78648..d394d8f0a2b 100644 --- a/iroh-relay/src/server/metrics.rs +++ b/iroh-relay/src/server/metrics.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use iroh_metrics::{Counter, MetricsGroup, MetricsGroupSet}; /// Metrics tracked for the relay server -#[derive(Debug, Clone, MetricsGroup)] +#[derive(Debug, Default, MetricsGroup)] #[metrics(name = "relayserver")] pub struct Metrics { /* @@ -85,7 +85,7 @@ pub struct Metrics { } /// StunMetrics tracked for the relay server -#[derive(Debug, Clone, MetricsGroup)] +#[derive(Debug, Default, MetricsGroup)] #[metrics(name = "stun")] pub struct StunMetrics { /// Number of STUN requests made to the server. @@ -100,22 +100,9 @@ pub struct StunMetrics { pub failures: Counter, } -#[derive(Debug, Default, Clone)] +#[derive(Debug, Default, Clone, MetricsGroupSet)] +#[metrics(name = "relay")] pub struct RelayMetrics { pub stun: Arc, pub server: Arc, } - -impl MetricsGroupSet for RelayMetrics { - fn name(&self) -> &'static str { - "relay" - } - - fn groups(&self) -> impl Iterator { - [ - &*self.stun as &dyn MetricsGroup, - &*self.server as &dyn MetricsGroup, - ] - .into_iter() - } -} diff --git a/iroh/Cargo.toml b/iroh/Cargo.toml index 9b55e8b36bd..9cca0601a00 100644 --- a/iroh/Cargo.toml +++ b/iroh/Cargo.toml @@ -81,7 +81,7 @@ x509-parser = "0.16" z32 = "1.0.3" # metrics -iroh-metrics = { version = "0.33", default-features = false } +iroh-metrics = { git = "https://github.com/n0-computer/iroh-metrics", branch = "Frando/derive-metricsgroupset", default-features = false } # local-swarm-discovery swarm-discovery = { version = "0.3.1", optional = true } @@ -104,7 +104,7 @@ hickory-resolver = "0.25.1" igd-next = { version = "0.15.1", features = ["aio_tokio"] } netdev = { version = "0.31.0" } # portmapper = { version = "0.4.1", default-features = false } -portmapper = { git = "https://github.com/n0-computer/net-tools", branch = "Frando/metrics" } +portmapper = { git = "https://github.com/n0-computer/net-tools", branch = "Frando/metrics2" } quinn = { package = "iroh-quinn", version = "0.13.0", default-features = false, features = ["runtime-tokio", "rustls-ring"] } tokio = { version = "1", features = [ "io-util", diff --git a/iroh/bench/Cargo.toml b/iroh/bench/Cargo.toml index d9ceb07d722..d88cf055aaf 100644 --- a/iroh/bench/Cargo.toml +++ b/iroh/bench/Cargo.toml @@ -10,7 +10,7 @@ anyhow = "1.0.22" bytes = "1.7" hdrhistogram = { version = "7.2", default-features = false } iroh = { path = ".." } -iroh-metrics = "0.33" +iroh-metrics = { git = "https://github.com/n0-computer/iroh-metrics", branch = "Frando/derive-metricsgroupset" } n0-future = "0.1.1" quinn = { package = "iroh-quinn", version = "0.13" } rand = "0.8" diff --git a/iroh/src/endpoint.rs b/iroh/src/endpoint.rs index 1ce9593e7cd..56387c8bf84 100644 --- a/iroh/src/endpoint.rs +++ b/iroh/src/endpoint.rs @@ -2902,8 +2902,8 @@ mod tests { // test openmetrics encoding with labeled subregistries per endpoint fn register_endpoint(registry: &mut Registry, endpoint: &Endpoint) { - let id = endpoint.node_id().fmt_short().into(); - let sub_registry = registry.sub_registry_with_label(("id".into(), id)); + let id = endpoint.node_id().fmt_short(); + let sub_registry = registry.sub_registry_with_label("id", id); endpoint.metrics().register(sub_registry); } let mut registry = Registry::default(); diff --git a/iroh/src/magicsock/metrics.rs b/iroh/src/magicsock/metrics.rs index ae5703d7376..41fffe3d24d 100644 --- a/iroh/src/magicsock/metrics.rs +++ b/iroh/src/magicsock/metrics.rs @@ -3,7 +3,7 @@ use iroh_metrics::{Counter, MetricsGroup}; /// Enum of metrics for the module // TODO(frando): Add description doc strings for each metric. #[allow(missing_docs)] -#[derive(Debug, Clone, MetricsGroup)] +#[derive(Debug, Default, MetricsGroup)] #[non_exhaustive] #[metrics(name = "magicsock")] pub struct Metrics { diff --git a/iroh/src/metrics.rs b/iroh/src/metrics.rs index c0633ee5201..7e7cffc1576 100644 --- a/iroh/src/metrics.rs +++ b/iroh/src/metrics.rs @@ -1,7 +1,7 @@ //! Co-locating all of the iroh metrics structs use std::sync::Arc; -use iroh_metrics::{MetricsGroup, MetricsGroupSet}; +use iroh_metrics::MetricsGroupSet; #[cfg(feature = "test-utils")] pub use iroh_relay::server::Metrics as RelayMetrics; #[cfg(not(wasm_browser))] @@ -12,7 +12,8 @@ pub use crate::{magicsock::Metrics as MagicsockMetrics, net_report::Metrics as N /// Metrics collected by an [`crate::endpoint::Endpoint`]. /// /// See [`crate::endpoint::Endpoint::metrics`] for details. -#[derive(Default, Debug, Clone)] +#[derive(Default, Debug, Clone, MetricsGroupSet)] +#[metrics(name = "endpoint")] #[non_exhaustive] pub struct EndpointMetrics { /// Metrics collected by the endpoint's socket. @@ -23,25 +24,3 @@ pub struct EndpointMetrics { #[cfg(not(wasm_browser))] pub portmapper: Arc, } - -impl MetricsGroupSet for EndpointMetrics { - fn groups(&self) -> impl Iterator { - #[cfg(not(wasm_browser))] - return [ - &*self.magicsock as &dyn MetricsGroup, - &*self.net_report as &dyn MetricsGroup, - &*self.portmapper as &dyn MetricsGroup, - ] - .into_iter(); - #[cfg(wasm_browser)] - return [ - &*self.magicsock as &dyn MetricsGroup, - &*self.net_report as &dyn MetricsGroup, - ] - .into_iter(); - } - - fn name(&self) -> &'static str { - "endpoint" - } -} diff --git a/iroh/src/net_report/metrics.rs b/iroh/src/net_report/metrics.rs index 4be2adfeaed..3387c8c2d95 100644 --- a/iroh/src/net_report/metrics.rs +++ b/iroh/src/net_report/metrics.rs @@ -1,7 +1,7 @@ use iroh_metrics::{Counter, MetricsGroup}; /// Enum of metrics for the module -#[derive(Debug, Clone, MetricsGroup)] +#[derive(Debug, Default, MetricsGroup)] #[metrics(name = "net_report")] #[non_exhaustive] pub struct Metrics { From e5fcb57818ff99abe8600b0e4f9b3dd65d4ff210 Mon Sep 17 00:00:00 2001 From: Frando Date: Mon, 28 Apr 2025 13:30:27 +0200 Subject: [PATCH 2/6] update iroh-metrics ref --- Cargo.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 808220e1e5f..d804509cddc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2392,7 +2392,7 @@ dependencies = [ [[package]] name = "iroh-metrics" version = "0.33.0" -source = "git+https://github.com/n0-computer/iroh-metrics?branch=Frando/derive-metricsgroupset#f8a2a047fc9f4232e0920501150efddc11be7060" +source = "git+https://github.com/n0-computer/iroh-metrics?branch=Frando/derive-metricsgroupset#ff3c5270a5e5e6bd909e9cd0214d659f899f0073" dependencies = [ "http-body-util", "hyper", @@ -2409,7 +2409,7 @@ dependencies = [ [[package]] name = "iroh-metrics-derive" version = "0.1.0" -source = "git+https://github.com/n0-computer/iroh-metrics?branch=Frando/derive-metricsgroupset#f8a2a047fc9f4232e0920501150efddc11be7060" +source = "git+https://github.com/n0-computer/iroh-metrics?branch=Frando/derive-metricsgroupset#ff3c5270a5e5e6bd909e9cd0214d659f899f0073" dependencies = [ "heck", "proc-macro2", @@ -2972,7 +2972,7 @@ dependencies = [ [[package]] name = "netwatch" version = "0.4.0" -source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2#640166ea310788a1fabca4ea99fc8cb0c6ae70f4" +source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2#dae8cea85713f36a3880c40893c17ccb3f712af0" dependencies = [ "atomic-waker", "bytes", @@ -3469,7 +3469,7 @@ checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "portmapper" version = "0.4.1" -source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2#640166ea310788a1fabca4ea99fc8cb0c6ae70f4" +source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2#dae8cea85713f36a3880c40893c17ccb3f712af0" dependencies = [ "base64", "bytes", @@ -5563,7 +5563,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] From 1c787690c3a7486db246aebf26a3d62677587fec Mon Sep 17 00:00:00 2001 From: Frando Date: Mon, 28 Apr 2025 13:49:06 +0200 Subject: [PATCH 3/6] tests: add serde test for metrics --- Cargo.lock | 5 +++-- iroh-relay/src/server.rs | 3 +-- iroh/Cargo.toml | 1 + iroh/src/endpoint.rs | 6 +++--- iroh/src/magicsock/metrics.rs | 3 ++- iroh/src/metrics.rs | 18 +++++++++++++++++- iroh/src/net_report/metrics.rs | 3 ++- 7 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d804509cddc..6a3a64c598c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2266,6 +2266,7 @@ dependencies = [ "pin-project", "pkarr", "portmapper", + "postcard", "pretty_assertions", "rand 0.8.5", "rand_chacha 0.3.1", @@ -2972,7 +2973,7 @@ dependencies = [ [[package]] name = "netwatch" version = "0.4.0" -source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2#dae8cea85713f36a3880c40893c17ccb3f712af0" +source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2#647b31b2c4468b7fe8651f8a31d5fea5411ee549" dependencies = [ "atomic-waker", "bytes", @@ -3469,7 +3470,7 @@ checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "portmapper" version = "0.4.1" -source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2#dae8cea85713f36a3880c40893c17ccb3f712af0" +source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2#647b31b2c4468b7fe8651f8a31d5fea5411ee549" dependencies = [ "base64", "bytes", diff --git a/iroh-relay/src/server.rs b/iroh-relay/src/server.rs index 2756f507e64..eaf15c91d08 100644 --- a/iroh-relay/src/server.rs +++ b/iroh-relay/src/server.rs @@ -27,7 +27,6 @@ use hyper::body::Incoming; use iroh_base::NodeId; #[cfg(feature = "test-utils")] use iroh_base::RelayUrl; -use iroh_metrics::MetricsGroupSet; use metrics::RelayMetrics; use n0_future::{future::Boxed, StreamExt}; use tokio::{ @@ -288,7 +287,7 @@ impl Server { if let Some(addr) = config.metrics_addr { debug!("Starting metrics server"); let mut registry = iroh_metrics::Registry::default(); - metrics.register(&mut registry); + registry.register_all(&metrics); tasks.spawn( async move { iroh_metrics::service::start_metrics_server(addr, Arc::new(registry)).await?; diff --git a/iroh/Cargo.toml b/iroh/Cargo.toml index 9cca0601a00..d789e361823 100644 --- a/iroh/Cargo.toml +++ b/iroh/Cargo.toml @@ -128,6 +128,7 @@ time = { version = "0.3", features = ["wasm-bindgen"] } # target-common test/dev dependencies [dev-dependencies] +postcard = { version = "1.1.1", features = ["use-std"] } testresult = "0.4.0" tracing-subscriber = { version = "0.3", features = ["env-filter"] } diff --git a/iroh/src/endpoint.rs b/iroh/src/endpoint.rs index 56387c8bf84..c7404460c7d 100644 --- a/iroh/src/endpoint.rs +++ b/iroh/src/endpoint.rs @@ -2092,7 +2092,7 @@ mod tests { use std::time::Instant; - use iroh_metrics::{service::MetricsSource, MetricsGroupSet}; + use iroh_metrics::MetricsSource; use iroh_relay::http::Protocol; use n0_future::StreamExt; use rand::SeedableRng; @@ -2904,12 +2904,12 @@ mod tests { fn register_endpoint(registry: &mut Registry, endpoint: &Endpoint) { let id = endpoint.node_id().fmt_short(); let sub_registry = registry.sub_registry_with_label("id", id); - endpoint.metrics().register(sub_registry); + sub_registry.register_all(endpoint.metrics()); } let mut registry = Registry::default(); register_endpoint(&mut registry, &client); register_endpoint(&mut registry, &server); - let s = registry.encode_openmetrics()?; + let s = registry.encode_openmetrics_to_string()?; assert!(s.contains(r#"magicsock_nodes_contacted_directly_total{id="3b6a27bcce"} 1"#)); assert!(s.contains(r#"magicsock_nodes_contacted_directly_total{id="8a88e3dd74"} 1"#)); diff --git a/iroh/src/magicsock/metrics.rs b/iroh/src/magicsock/metrics.rs index 41fffe3d24d..b6d7fe5d44c 100644 --- a/iroh/src/magicsock/metrics.rs +++ b/iroh/src/magicsock/metrics.rs @@ -1,9 +1,10 @@ use iroh_metrics::{Counter, MetricsGroup}; +use serde::{Deserialize, Serialize}; /// Enum of metrics for the module // TODO(frando): Add description doc strings for each metric. #[allow(missing_docs)] -#[derive(Debug, Default, MetricsGroup)] +#[derive(Debug, Default, Serialize, Deserialize, MetricsGroup)] #[non_exhaustive] #[metrics(name = "magicsock")] pub struct Metrics { diff --git a/iroh/src/metrics.rs b/iroh/src/metrics.rs index 7e7cffc1576..f62f85a214c 100644 --- a/iroh/src/metrics.rs +++ b/iroh/src/metrics.rs @@ -6,13 +6,14 @@ use iroh_metrics::MetricsGroupSet; pub use iroh_relay::server::Metrics as RelayMetrics; #[cfg(not(wasm_browser))] pub use portmapper::Metrics as PortmapMetrics; +use serde::{Deserialize, Serialize}; pub use crate::{magicsock::Metrics as MagicsockMetrics, net_report::Metrics as NetReportMetrics}; /// Metrics collected by an [`crate::endpoint::Endpoint`]. /// /// See [`crate::endpoint::Endpoint::metrics`] for details. -#[derive(Default, Debug, Clone, MetricsGroupSet)] +#[derive(Default, Debug, Clone, Serialize, Deserialize, MetricsGroupSet)] #[metrics(name = "endpoint")] #[non_exhaustive] pub struct EndpointMetrics { @@ -24,3 +25,18 @@ pub struct EndpointMetrics { #[cfg(not(wasm_browser))] pub portmapper: Arc, } + +#[cfg(test)] +mod tests { + use super::EndpointMetrics; + #[test] + fn test_serde() { + let metrics = EndpointMetrics::default(); + metrics.magicsock.actor_link_change.inc(); + metrics.net_report.reports.inc_by(10); + let encoded = postcard::to_stdvec(&metrics).unwrap(); + let decoded: EndpointMetrics = postcard::from_bytes(&encoded).unwrap(); + assert_eq!(decoded.magicsock.actor_link_change.get(), 1); + assert_eq!(decoded.net_report.reports.get(), 10); + } +} diff --git a/iroh/src/net_report/metrics.rs b/iroh/src/net_report/metrics.rs index 3387c8c2d95..1698c1d8ae7 100644 --- a/iroh/src/net_report/metrics.rs +++ b/iroh/src/net_report/metrics.rs @@ -1,7 +1,8 @@ use iroh_metrics::{Counter, MetricsGroup}; +use serde::{Deserialize, Serialize}; /// Enum of metrics for the module -#[derive(Debug, Default, MetricsGroup)] +#[derive(Debug, Default, MetricsGroup, Serialize, Deserialize)] #[metrics(name = "net_report")] #[non_exhaustive] pub struct Metrics { From 13f50a5f49f55a34132d679300811ab1c1f6f530 Mon Sep 17 00:00:00 2001 From: Frando Date: Tue, 29 Apr 2025 09:49:53 +0200 Subject: [PATCH 4/6] fix: docs --- iroh/src/endpoint.rs | 77 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/iroh/src/endpoint.rs b/iroh/src/endpoint.rs index c7404460c7d..957373ee66b 100644 --- a/iroh/src/endpoint.rs +++ b/iroh/src/endpoint.rs @@ -1115,22 +1115,19 @@ impl Endpoint { /// You can access individual metrics directly by using the public fields: /// ```rust /// # use std::collections::BTreeMap; - /// # use iroh_metrics::{MetricsGroup, MetricValue, MetricsGroupSet}; /// # use iroh::endpoint::Endpoint; /// # async fn wrapper() -> testresult::TestResult { /// let endpoint = Endpoint::builder().bind().await?; - /// let metrics = endpoint.metrics(); - /// - /// assert_eq!(metrics.magicsock.recv_datagrams.get(), 0); + /// assert_eq!(endpoint.metrics().magicsock.recv_datagrams.get(), 0); /// # Ok(()) /// # } /// ``` /// /// [`EndpointMetrics`] implements [`MetricsGroupSet`], and each field - /// implements [`MetricsGroup`]. These trait provides various methods to iterate + /// implements [`MetricsGroup`]. These trait provides methods to iterate over /// the groups in the set, and over the individual metrics in each group, without having /// to access each field manually. With these methods, it is straightforward to collect - /// all metrics into a map or push their values to some other metrics collector. + /// all metrics into a map or push their values to a metrics collector. /// /// For example, the following snippet collects all metrics into a map: /// ```rust @@ -1153,15 +1150,69 @@ impl Endpoint { /// # } /// ``` /// - /// The metrics can also be used with the types from the [`prometheus_client`] crate. - /// With [`EndpointMetrics::register`], you can register all metrics onto a onto a - /// [`Registry`]. [`iroh_metrics`] provides functions to easily start services + /// The metrics can also be encoded into the OpenMetrics text format, as used by Prometheus. + /// To do so, use the [`iroh_metrics::Registry`], add the endpoint metrics to the + /// registry with [`Registry::register_all`], and encode the metrics to a string with + /// [`encode_openmetrics_to_string`]: + /// ```rust + /// # use iroh_metrics::{Registry, MetricsSource}; + /// # use iroh::endpoint::Endpoint; + /// # async fn wrapper() -> testresult::TestResult { + /// let endpoint = Endpoint::builder().bind().await?; + /// let mut registry = Registry::default(); + /// registry.register_all(endpoint.metrics()); + /// let s = registry.encode_openmetrics_to_string()?; + /// assert!(s.contains(r#"TYPE magicsock_recv_datagrams counter"#)); + /// assert!(s.contains(r#"magicsock_recv_datagrams_total 0"#)); + /// # Ok(()) + /// # } + /// ``` + /// + /// Through a registry, you can also add labels or prefixes to metrics with + /// [`Registry::sub_registry_with_label`] or [`Registry::sub_registry_with_prefix`]. + /// Furthermore, [`iroh_metrics::service`] provides functions to easily start services /// to serve the metrics with a HTTP server, dump them to a file, or push them - /// to a Prometheus gateway. See the `service` module in [`iroh_metrics`] for details. + /// to a Prometheus gateway. + /// + /// For example, the following snippet launches an HTTP server that serves the metrics in the + /// OpenMetrics text format: + /// ```no_run + /// # use std::{sync::{Arc, RwLock}, time::Duration}; + /// # use iroh_metrics::{Registry, MetricsSource}; + /// # use iroh::endpoint::Endpoint; + /// # async fn wrapper() -> testresult::TestResult { + /// // Create a registry, wrapped in a read-write lock so that we can register and serve + /// // the metrics independently. + /// let registry = Arc::new(RwLock::new(Registry::default())); + /// // Spawn a task to serve the metrics on an OpenMetrics HTTP endpoint. + /// let metrics_task = tokio::task::spawn({ + /// let registry = registry.clone(); + /// async move { + /// let addr = "0.0.0.0:9100".parse().unwrap(); + /// iroh_metrics::service::start_metrics_server(addr, registry).await + /// } + /// }); + /// + /// // Spawn an endpoint and add the metrics to the registry. + /// let endpoint = Endpoint::builder().bind().await?; + /// registry.write().unwrap().register_all(endpoint.metrics()); + /// + /// // Wait for the metrics server to bind, then fetch the metrics via HTTP. + /// tokio::time::sleep(Duration::from_millis(500)); + /// let res = reqwest::get("http://localhost:9100/metrics").await?.text().await?; + /// + /// assert!(res.contains(r#"TYPE magicsock_recv_datagrams counter"#)); + /// assert!(res.contains(r#"magicsock_recv_datagrams_total 0"#)); + /// # metrics_task.abort(); + /// # Ok(()) + /// # } + /// ``` /// - /// [`prometheus_client`]: https://docs.rs/prometheus-client/latest/prometheus_client/index.html - /// [`Registry`]: https://docs.rs/prometheus-client/latest/prometheus_client/registry/struct.Registry.html - /// [`EndpointMetrics::register`]: iroh_metrics::MetricsGroupSet::register + /// [`Registry`]: iroh_metrics::Registry + /// [`Registry::register_all`]: iroh_metrics::Registry::register_all + /// [`Registry::sub_registry_with_label`]: iroh_metrics::Registry::sub_registry_with_label + /// [`Registry::sub_registry_with_prefix`]: iroh_metrics::Registry::sub_registry_with_prefix + /// [`encode_openmetrics_to_string`]: iroh_metrics::MetricsSource::encode_openmetrics_to_string /// [`MetricsGroup`]: iroh_metrics::MetricsGroup /// [`MetricsGroupSet`]: iroh_metrics::MetricsGroupSet #[cfg(feature = "metrics")] From 3d22b7e9dca1467a9bf26689ca28ffe1d1393af0 Mon Sep 17 00:00:00 2001 From: Frando Date: Tue, 29 Apr 2025 10:16:44 +0200 Subject: [PATCH 5/6] chore: fmt --- iroh/src/endpoint.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/iroh/src/endpoint.rs b/iroh/src/endpoint.rs index 957373ee66b..164a49c00cd 100644 --- a/iroh/src/endpoint.rs +++ b/iroh/src/endpoint.rs @@ -1199,7 +1199,10 @@ impl Endpoint { /// /// // Wait for the metrics server to bind, then fetch the metrics via HTTP. /// tokio::time::sleep(Duration::from_millis(500)); - /// let res = reqwest::get("http://localhost:9100/metrics").await?.text().await?; + /// let res = reqwest::get("http://localhost:9100/metrics") + /// .await? + /// .text() + /// .await?; /// /// assert!(res.contains(r#"TYPE magicsock_recv_datagrams counter"#)); /// assert!(res.contains(r#"magicsock_recv_datagrams_total 0"#)); From e44aa54843f2228a533846eb56956bc16ec639d9 Mon Sep 17 00:00:00 2001 From: Frando Date: Wed, 30 Apr 2025 10:39:45 +0200 Subject: [PATCH 6/6] update to latest iroh-metrics main --- Cargo.lock | 33 +++++++++++++++++++++++++++------ iroh-dns-server/Cargo.toml | 2 +- iroh-relay/Cargo.toml | 2 +- iroh/Cargo.toml | 4 ++-- iroh/bench/Cargo.toml | 2 +- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a3a64c598c..8da4e7e23b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2393,7 +2393,7 @@ dependencies = [ [[package]] name = "iroh-metrics" version = "0.33.0" -source = "git+https://github.com/n0-computer/iroh-metrics?branch=Frando/derive-metricsgroupset#ff3c5270a5e5e6bd909e9cd0214d659f899f0073" +source = "git+https://github.com/n0-computer/iroh-metrics?branch=main#a589407937d851c5e9424431b86eee24e3dddd93" dependencies = [ "http-body-util", "hyper", @@ -2402,7 +2402,7 @@ dependencies = [ "itoa", "reqwest", "serde", - "thiserror 2.0.11", + "snafu", "tokio", "tracing", ] @@ -2410,7 +2410,7 @@ dependencies = [ [[package]] name = "iroh-metrics-derive" version = "0.1.0" -source = "git+https://github.com/n0-computer/iroh-metrics?branch=Frando/derive-metricsgroupset#ff3c5270a5e5e6bd909e9cd0214d659f899f0073" +source = "git+https://github.com/n0-computer/iroh-metrics?branch=main#a589407937d851c5e9424431b86eee24e3dddd93" dependencies = [ "heck", "proc-macro2", @@ -2973,7 +2973,7 @@ dependencies = [ [[package]] name = "netwatch" version = "0.4.0" -source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2#647b31b2c4468b7fe8651f8a31d5fea5411ee549" +source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics#ff9840322c1c57dc87010f2909f174c5bb8944b3" dependencies = [ "atomic-waker", "bytes", @@ -3470,7 +3470,7 @@ checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "portmapper" version = "0.4.1" -source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2#647b31b2c4468b7fe8651f8a31d5fea5411ee549" +source = "git+https://github.com/n0-computer/net-tools?branch=Frando/metrics#ff9840322c1c57dc87010f2909f174c5bb8944b3" dependencies = [ "base64", "bytes", @@ -3480,7 +3480,7 @@ dependencies = [ "igd-next", "iroh-metrics", "libc", - "netwatch 0.4.0 (git+https://github.com/n0-computer/net-tools?branch=Frando/metrics2)", + "netwatch 0.4.0 (git+https://github.com/n0-computer/net-tools?branch=Frando/metrics)", "num_enum", "rand 0.8.5", "serde", @@ -4505,6 +4505,27 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9" +[[package]] +name = "snafu" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" +dependencies = [ + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.98", +] + [[package]] name = "socket2" version = "0.5.8" diff --git a/iroh-dns-server/Cargo.toml b/iroh-dns-server/Cargo.toml index f70c8eef873..f1789df5674 100644 --- a/iroh-dns-server/Cargo.toml +++ b/iroh-dns-server/Cargo.toml @@ -28,7 +28,7 @@ governor = "0.6.3" #needs new release of tower_governor for 0.7.0 hickory-server = { version = "0.25.1", features = ["https-ring"] } http = "1.0.0" humantime-serde = "1.1.1" -iroh-metrics = { git = "https://github.com/n0-computer/iroh-metrics", branch = "Frando/derive-metricsgroupset", features = ["service"] } +iroh-metrics = { git = "https://github.com/n0-computer/iroh-metrics", branch = "main", features = ["service"] } lru = "0.12.3" n0-future = "0.1.2" pkarr = { version = "2.3.1", features = [ "async", "relay", "dht"], default-features = false } diff --git a/iroh-relay/Cargo.toml b/iroh-relay/Cargo.toml index e11f1829193..4a6d74a32af 100644 --- a/iroh-relay/Cargo.toml +++ b/iroh-relay/Cargo.toml @@ -33,7 +33,7 @@ http-body-util = "0.1.0" hyper = { version = "1", features = ["server", "client", "http1"] } hyper-util = "0.1.1" iroh-base = { version = "0.34.1", path = "../iroh-base", default-features = false, features = ["key", "relay"] } -iroh-metrics = { git = "https://github.com/n0-computer/iroh-metrics", branch = "Frando/derive-metricsgroupset", default-features = false } +iroh-metrics = { git = "https://github.com/n0-computer/iroh-metrics", branch = "main", default-features = false } n0-future = "0.1.2" num_enum = "0.7" pin-project = "1" diff --git a/iroh/Cargo.toml b/iroh/Cargo.toml index d789e361823..b8ad6d53c07 100644 --- a/iroh/Cargo.toml +++ b/iroh/Cargo.toml @@ -81,7 +81,7 @@ x509-parser = "0.16" z32 = "1.0.3" # metrics -iroh-metrics = { git = "https://github.com/n0-computer/iroh-metrics", branch = "Frando/derive-metricsgroupset", default-features = false } +iroh-metrics = { git = "https://github.com/n0-computer/iroh-metrics", branch = "main", default-features = false } # local-swarm-discovery swarm-discovery = { version = "0.3.1", optional = true } @@ -104,7 +104,7 @@ hickory-resolver = "0.25.1" igd-next = { version = "0.15.1", features = ["aio_tokio"] } netdev = { version = "0.31.0" } # portmapper = { version = "0.4.1", default-features = false } -portmapper = { git = "https://github.com/n0-computer/net-tools", branch = "Frando/metrics2" } +portmapper = { git = "https://github.com/n0-computer/net-tools", branch = "Frando/metrics" } quinn = { package = "iroh-quinn", version = "0.13.0", default-features = false, features = ["runtime-tokio", "rustls-ring"] } tokio = { version = "1", features = [ "io-util", diff --git a/iroh/bench/Cargo.toml b/iroh/bench/Cargo.toml index d88cf055aaf..d5f2d1d52de 100644 --- a/iroh/bench/Cargo.toml +++ b/iroh/bench/Cargo.toml @@ -10,7 +10,7 @@ anyhow = "1.0.22" bytes = "1.7" hdrhistogram = { version = "7.2", default-features = false } iroh = { path = ".." } -iroh-metrics = { git = "https://github.com/n0-computer/iroh-metrics", branch = "Frando/derive-metricsgroupset" } +iroh-metrics = { git = "https://github.com/n0-computer/iroh-metrics", branch = "main" } n0-future = "0.1.1" quinn = { package = "iroh-quinn", version = "0.13" } rand = "0.8"