diff options
Diffstat (limited to 'src/api/stats/prometheus.rs')
| -rw-r--r-- | src/api/stats/prometheus.rs | 76 |
1 files changed, 72 insertions, 4 deletions
diff --git a/src/api/stats/prometheus.rs b/src/api/stats/prometheus.rs index 11645a3..9a4f162 100644 --- a/src/api/stats/prometheus.rs +++ b/src/api/stats/prometheus.rs @@ -103,6 +103,11 @@ fn escape(value: &str) -> String { .replace('\n', "\\n") } +/// The transport of an address. +fn scheme(address: &str) -> &str { + address.split_once(':').map_or("", |(scheme, _)| scheme) +} + fn flag(value: bool) -> f64 { if value { 1.0 } else { 0.0 } } @@ -177,6 +182,7 @@ fn traffic_series(traffic: &PeerTraffic) -> Vec<(&'static str, &'static str, Cou (direction, "status_reply", by.status_reply), (direction, "blob", by.blob), (direction, "identity", by.identity), + (direction, "paths", by.paths), ] }; let mut series = Vec::new(); @@ -238,6 +244,40 @@ fn transports(out: &mut Out, stats: &TransportStats) { out.single(name, "counter", help, value as f64); } } + if let Some(paths) = &stats.paths { + let counts = &paths.counts; + out.family( + "paths_probes_total", + "counter", + "PINGs to paths of peers with several, by result.", + ); + for (result, count) in [ + ("sent", counts.probes_sent), + ("answered", counts.probes_answered), + ("unanswered", counts.probes_unanswered), + ] { + out.sample("paths_probes_total", &[("result", result)], count as f64); + } + for (name, help, value) in [ + ( + "paths_send_failures_total", + "Sends that failed on a path, each tried at the next.", + counts.send_failures, + ), + ( + "paths_failovers_total", + "Sends that went over another path after one failed.", + counts.failovers, + ), + ( + "paths_switches_total", + "Changes of the path in use for a faster one.", + counts.switches, + ), + ] { + out.single(name, "counter", help, value as f64); + } + } if let Some(libp2p) = &stats.libp2p { out.family( "libp2p_reachability", @@ -675,10 +715,7 @@ pub(super) async fn render(state: &AppState, stats: &StatsResponse) -> String { ); for peer in &peers { if let Some(destination) = &peer.destination { - let transport = destination - .address - .split_once(':') - .map_or("", |(scheme, _)| scheme); + let transport = scheme(&destination.address); out.sample( "peer_destination_info", &[ @@ -695,6 +732,37 @@ pub(super) async fn render(state: &AppState, stats: &StatsResponse) -> String { } } + out.family( + "peer_path_rtt_seconds", + "gauge", + "Smoothed round-trip time of the PINGs on each path to a peer with several.", + ); + for peer in &peers { + for path in peer.destination.iter().flat_map(|d| &d.paths) { + if let Some(ms) = path.rtt_ms { + out.sample( + "peer_path_rtt_seconds", + &[("peer", &peer.key), ("transport", scheme(&path.address))], + ms / 1000.0, + ); + } + } + } + out.family( + "peer_path_down", + "gauge", + "1 while a path to the peer is down (PINGs unanswered, or a send failed).", + ); + for peer in &peers { + for path in peer.destination.iter().flat_map(|d| &d.paths) { + out.sample( + "peer_path_down", + &[("peer", &peer.key), ("transport", scheme(&path.address))], + flag(path.down), + ); + } + } + out.family("peer_neighbour", "gauge", "1 if the peer is a neighbour."); for peer in &peers { out.sample( |
