aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-05 00:56:39 +0100
committertv <tv@krebsco.de>2026-11-05 00:56:39 +0100
commit4da17a5e40e34aea27a34241b4f692ae0c827f57 (patch)
treedf4260a9b912957a3f5e7908dca31810c9a3a88f /src
parent4c6604db27f26998b72fd815b6bd1de5a3b08780 (diff)
neigbours by transport
Diffstat (limited to 'src')
-rw-r--r--src/api/stats.rs3
-rw-r--r--src/api/stats/prometheus.rs12
-rw-r--r--src/swarm/topology/mod.rs22
3 files changed, 36 insertions, 1 deletions
diff --git a/src/api/stats.rs b/src/api/stats.rs
index 3851ef7..306b6a2 100644
--- a/src/api/stats.rs
+++ b/src/api/stats.rs
@@ -187,6 +187,8 @@ struct TopologyView {
stable: usize,
neighbours: usize,
stable_neighbours: usize,
+ /// Neighbours by our transports (`topology::Summary`).
+ neighbours_by_transport: std::collections::BTreeMap<String, usize>,
/// Our own writer's tree (`swarm::tree::own_shape`); absent while we aren't in the
/// member list's graph.
own_tree: Option<OwnTree>,
@@ -382,6 +384,7 @@ pub(crate) async fn collect(state: &AppState, list: &PeerListResponse) -> StatsR
stable: s.stable,
neighbours: s.neighbours,
stable_neighbours: s.stable_neighbours,
+ neighbours_by_transport: s.neighbours_by_transport,
own_tree,
}),
},
diff --git a/src/api/stats/prometheus.rs b/src/api/stats/prometheus.rs
index db3cef3..ffe6593 100644
--- a/src/api/stats/prometheus.rs
+++ b/src/api/stats/prometheus.rs
@@ -713,6 +713,18 @@ pub(super) fn render(stats: &StatsResponse, list: &PeerListResponse) -> String {
"Current neighbours with the stable tier.",
view.stable_neighbours as f64,
);
+ out.family(
+ "neighbours_on",
+ "gauge",
+ "Current neighbours with an address on one of this node's transports, by transport.",
+ );
+ for (transport, neighbours) in &view.neighbours_by_transport {
+ out.sample(
+ "neighbours_on",
+ &[("transport", transport)],
+ *neighbours as f64,
+ );
+ }
if let Some(tree) = &view.own_tree {
out.single(
"own_tree_members",
diff --git a/src/swarm/topology/mod.rs b/src/swarm/topology/mod.rs
index afa13ee..37b2f71 100644
--- a/src/swarm/topology/mod.rs
+++ b/src/swarm/topology/mod.rs
@@ -117,7 +117,7 @@ pub(crate) fn is_full_mesh(state: &AppState) -> bool {
}
/// The current view in numbers, once known.
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone)]
pub(crate) struct Summary {
/// Registered members, us included.
pub(crate) members: usize,
@@ -126,6 +126,10 @@ pub(crate) struct Summary {
pub(crate) stable: usize,
pub(crate) neighbours: usize,
pub(crate) stable_neighbours: usize,
+ /// For each of our transports (address scheme), the neighbours the member list
+ /// gives an address on it: one on two transports counts on both, one it gives none
+ /// for (not listed yet, or only connecting out) on none.
+ pub(crate) neighbours_by_transport: BTreeMap<String, usize>,
}
pub(crate) fn summary(state: &AppState) -> Option<Summary> {
@@ -148,6 +152,22 @@ pub(crate) fn summary(state: &AppState) -> Option<Summary> {
.iter()
.filter(|m| view.stable.contains(*m))
.count(),
+ neighbours_by_transport: view
+ .local_transports
+ .iter()
+ .map(|transport| {
+ let on_it = view
+ .neighbours
+ .iter()
+ .filter(|m| {
+ view.transports
+ .get(*m)
+ .is_some_and(|theirs| theirs.contains(transport))
+ })
+ .count();
+ (transport.clone(), on_it)
+ })
+ .collect(),
})
}