From 2b3c2c090f5c78f4add87566792c503d709307f3 Mon Sep 17 00:00:00 2001 From: Asmir Avdicevic Date: Mon, 10 Nov 2025 21:43:02 +0100 Subject: [PATCH] feat(metrics): add connection latency tracking --- .../magicsock/endpoint_map/path_validity.rs | 35 +++++++++++++++++++ iroh/src/magicsock/metrics.rs | 3 ++ 2 files changed, 38 insertions(+) diff --git a/iroh/src/magicsock/endpoint_map/path_validity.rs b/iroh/src/magicsock/endpoint_map/path_validity.rs index 3a33993c864..569b994377f 100644 --- a/iroh/src/magicsock/endpoint_map/path_validity.rs +++ b/iroh/src/magicsock/endpoint_map/path_validity.rs @@ -285,6 +285,9 @@ impl PathValidity { let quality = state.congestion_metrics.quality_score(); metrics.path_quality_score.observe(quality); + + let latency_ms = state.latency.as_secs_f64() * 1000.0; + metrics.connection_latency_ms.observe(latency_ms); } } @@ -395,4 +398,36 @@ mod tests { let quality = validity.quality_score(); assert!(quality < 0.9); // Should be penalized } + + #[tokio::test] + async fn test_connection_latency_histogram() { + use crate::magicsock::Metrics as MagicsockMetrics; + + let metrics = MagicsockMetrics::default(); + let mut validity = PathValidity::new(Instant::now(), Duration::from_millis(10)); + + validity.record_metrics(&metrics); + assert_eq!(metrics.connection_latency_ms.count(), 1); + + validity.update_pong(Instant::now(), Duration::from_millis(25)); + validity.record_metrics(&metrics); + assert_eq!(metrics.connection_latency_ms.count(), 2); + + validity.update_pong(Instant::now(), Duration::from_millis(50)); + validity.record_metrics(&metrics); + assert_eq!(metrics.connection_latency_ms.count(), 3); + + validity.update_pong(Instant::now(), Duration::from_millis(100)); + validity.record_metrics(&metrics); + assert_eq!(metrics.connection_latency_ms.count(), 4); + + let buckets = metrics.connection_latency_ms.buckets(); + assert!(!buckets.is_empty()); + + let p50 = metrics.connection_latency_ms.percentile(0.5); + assert!(p50 > 10.0 && p50 < 100.0); + + let p95 = metrics.connection_latency_ms.percentile(0.95); + assert!(p95 >= p50); + } } diff --git a/iroh/src/magicsock/metrics.rs b/iroh/src/magicsock/metrics.rs index c4ee2a331c1..e6f53d95c7c 100644 --- a/iroh/src/magicsock/metrics.rs +++ b/iroh/src/magicsock/metrics.rs @@ -77,6 +77,9 @@ pub struct Metrics { pub connection_handshake_success: Counter, /// Number of connections with a successful handshake that became direct. pub connection_became_direct: Counter, + /// Histogram of connection latency in milliseconds across all endpoint connections. + #[default(Histogram::new(vec![1.0, 5.0, 10.0, 25.0, 50.0, 100.0, 250.0, 500.0, 1000.0, f64::INFINITY]))] + pub connection_latency_ms: Histogram, /* * Path Congestion Metrics