summaryrefslogtreecommitdiffstats
path: root/src/api/stats/prometheus.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/stats/prometheus.rs')
-rw-r--r--src/api/stats/prometheus.rs76
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(