aboutsummaryrefslogtreecommitdiffstats
path: root/src/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/api')
-rw-r--r--src/api/peers.rs6
-rw-r--r--src/api/stats/prometheus.rs32
2 files changed, 38 insertions, 0 deletions
diff --git a/src/api/peers.rs b/src/api/peers.rs
index 020221b..3fe4c39 100644
--- a/src/api/peers.rs
+++ b/src/api/peers.rs
@@ -18,6 +18,7 @@ use crate::locks::MutexExt;
use crate::state::{AppState, HelloState, Incidents, Liveness};
use crate::swarm::peer::forgotten_path;
use crate::transport::Destination;
+use crate::transport::paths::ClockOffset;
use crate::transport::traffic::PeerTraffic;
#[derive(Debug, Serialize)]
@@ -66,6 +67,9 @@ pub(crate) struct PeerStatus {
/// Smoothed sync throughput (`swarm::throughput`); absent before the first large
/// exchange.
pub(crate) sync_throughput: Option<ThroughputInfo>,
+ /// How far its clock is ahead of ours, give or take (`Transport::clock_offset`);
+ /// absent before a PONG from it.
+ pub(crate) clock: Option<ClockOffset>,
}
#[derive(Debug, Serialize)]
@@ -141,6 +145,7 @@ pub(crate) async fn peer_list(state: &AppState) -> PeerListResponse {
let alias = aliases.remove(&peer);
let addresses = state.transport.addresses_of(&peer);
let destination = state.transport.destination(&peer);
+ let clock = state.transport.clock_offset(&peer);
peers.insert(
peer,
PeerStatus {
@@ -168,6 +173,7 @@ pub(crate) async fn peer_list(state: &AppState) -> PeerListResponse {
traffic,
incidents: ps.incidents,
sync_throughput,
+ clock,
},
);
}
diff --git a/src/api/stats/prometheus.rs b/src/api/stats/prometheus.rs
index 8f7538f..2f33bef 100644
--- a/src/api/stats/prometheus.rs
+++ b/src/api/stats/prometheus.rs
@@ -9,6 +9,7 @@ use crate::api::media_type;
use crate::api::peers::{PeerListResponse, PeerLivenessStatus};
use crate::state::Incidents;
use crate::transport::Destination;
+use crate::transport::paths::ClockOffset;
use crate::transport::stats::{Reachability, TransportStats};
use crate::transport::traffic::{ByKind, Counter, PeerTraffic};
@@ -151,6 +152,7 @@ struct Peer {
incidents: Incidents,
throughput: Option<f64>,
destination: Option<Destination>,
+ clock: Option<ClockOffset>,
}
/// The rows of `/peers` (`peers::peer_list`), as the series need them.
@@ -171,6 +173,7 @@ fn peers(list: &PeerListResponse) -> Vec<Peer> {
incidents: peer.incidents,
throughput: peer.sync_throughput.as_ref().map(|t| t.bytes_per_sec),
destination: peer.destination.clone(),
+ clock: peer.clock,
})
.collect()
}
@@ -928,6 +931,35 @@ pub(super) fn render(stats: &StatsResponse, list: &PeerListResponse) -> String {
}
out.family(
+ "peer_clock_offset_seconds",
+ "gauge",
+ "How far the peer's clock is ahead of ours (behind: negative), from its PONGs.",
+ );
+ for peer in &peers {
+ if let Some(clock) = peer.clock {
+ out.sample(
+ "peer_clock_offset_seconds",
+ &[("peer", &peer.key)],
+ clock.offset_ms as f64 / 1000.0,
+ );
+ }
+ }
+ out.family(
+ "peer_clock_offset_within_seconds",
+ "gauge",
+ "Give or take this much: half the round trip it was measured over.",
+ );
+ for peer in &peers {
+ if let Some(clock) = peer.clock {
+ out.sample(
+ "peer_clock_offset_within_seconds",
+ &[("peer", &peer.key)],
+ clock.within_ms as f64 / 1000.0,
+ );
+ }
+ }
+
+ out.family(
"peer_messages_total",
"counter",
"Messages by direction and kind.",