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
65 changes: 28 additions & 37 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion iroh-dns-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "main", features = ["service"] }
lru = "0.12.3"
n0-future = "0.1.2"
pkarr = { version = "2.3.1", features = [ "async", "relay", "dht"], default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion iroh-dns-server/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions iroh-dns-server/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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(())
});
Expand Down
2 changes: 1 addition & 1 deletion iroh-relay/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "main", default-features = false }
n0-future = "0.1.2"
num_enum = "0.7"
pin-project = "1"
Expand Down
3 changes: 1 addition & 2 deletions iroh-relay/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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?;
Expand Down
21 changes: 4 additions & 17 deletions iroh-relay/src/server/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
/*
Expand Down Expand Up @@ -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.
Expand All @@ -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<StunMetrics>,
pub server: Arc<Metrics>,
}

impl MetricsGroupSet for RelayMetrics {
fn name(&self) -> &'static str {
"relay"
}

fn groups(&self) -> impl Iterator<Item = &dyn MetricsGroup> {
[
&*self.stun as &dyn MetricsGroup,
&*self.server as &dyn MetricsGroup,
]
.into_iter()
}
}
3 changes: 2 additions & 1 deletion iroh/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "main", default-features = false }

# local-swarm-discovery
swarm-discovery = { version = "0.3.1", optional = true }
Expand Down Expand Up @@ -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"] }

Expand Down
2 changes: 1 addition & 1 deletion iroh/bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "main" }
n0-future = "0.1.1"
quinn = { package = "iroh-quinn", version = "0.13" }
rand = "0.8"
Expand Down
90 changes: 72 additions & 18 deletions iroh/src/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -1153,15 +1150,72 @@ 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")]
Expand Down Expand Up @@ -2092,7 +2146,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;
Expand Down Expand Up @@ -2902,14 +2956,14 @@ 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));
endpoint.metrics().register(sub_registry);
let id = endpoint.node_id().fmt_short();
let sub_registry = registry.sub_registry_with_label("id", id);
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"#));

Expand Down
Loading
Loading