aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-05 03:05:13 +0100
committertv <tv@krebsco.de>2026-11-05 03:05:13 +0100
commitd13f11afe9a303a78cd877db8328b2a69935e931 (patch)
tree04451915967f6d60830aafec8f3bee60c6a4fde4
parent34305caa35e75a7b6ae49adc616125cb631aee3d (diff)
dashboard: neaten up peers box
-rw-r--r--docs/dashboard.md4
-rw-r--r--src/api/dashboard/dashboard.html17
2 files changed, 14 insertions, 7 deletions
diff --git a/docs/dashboard.md b/docs/dashboard.md
index 3a92018..4c3f6e5 100644
--- a/docs/dashboard.md
+++ b/docs/dashboard.md
@@ -226,13 +226,13 @@ Every peer this node knows, with:
| peer | Alias, or a shortened node ID (the full one in the tooltip). |
| status | `active`, `dormant` (for how long: in the tooltip) or `unknown` (not heard from since this node started). |
| seen | How long ago this node last heard from it. |
-| via | The address this node sends to it at, and whether `direct` or `relayed`: its start, cut short with an ellipsis; all of it in the tooltip. |
+| via | The address this node sends to it at, and whether `direct` or `relayed`: as much as the box's width leaves, cut short with an ellipsis; all of it in the tooltip. |
| rtt | The round trip on that path. |
| hop | How long its sync and blob messages take to come, by its clock and this node's, its clock offset taken off (`hopDelay` in [`measurements.md`](measurements.md)): this minute's mean, then the last 15 minutes' means as bars, oldest first (a minute without messages blank). Good to half the round trip, but the trend exactly: bars growing mean the link, or a queue on it, gets slower. All figures in the tooltip. |
| clock | How far its clock is ahead of this node's (behind: `−`), give or take (in the tooltip); in orange beyond `--clock-skew-warn`, for sure ([`measurements.md`](measurements.md), Clocks). |
| neighbour | Whether this node keeps contact with it (HELLOs, keepalives, sync); others it only answers. |
| reaches | How many members besides this node it reaches, as it said ([`peers.md`](peers.md)); `(+n)`: of those, how many this node doesn't reach itself, which it is a way to. By name in the tooltip, those marked `+`. Blank until it said so in this session. |
-| same epoch | Whether it is on this node's epoch ([`remakes.md`](remakes.md)); blank while unknown. |
+| epoch | The epoch it last said it is on, by its generation ([`remakes.md`](remakes.md)); orange where it isn't this node's (they don't sync then); its ID in the tooltip; blank while unknown. |
The box is as tall as its rows, up to eight; then it scrolls.
diff --git a/src/api/dashboard/dashboard.html b/src/api/dashboard/dashboard.html
index 7be738c..5d49311 100644
--- a/src/api/dashboard/dashboard.html
+++ b/src/api/dashboard/dashboard.html
@@ -31,7 +31,7 @@
border-bottom: 1px solid var(--line); flex-wrap: wrap; }
header h1 { font-size: 16px; margin: 0; }
#connection { margin-left: auto; color: var(--muted); }
- #clock-warning, #peers .clock-off { color: var(--warn); }
+ #clock-warning, #peers .clock-off, #peers .epoch-off { color: var(--warn); }
/* A minute's bar each, the last 15: a link's trend at a glance. */
#peers .spark { font-family: ui-monospace, monospace; letter-spacing: 0; opacity: 0.7; }
#connection.live { color: var(--ok); }
@@ -240,7 +240,7 @@
#peers tr.focused td { background: var(--line); }
.id { font-family: ui-monospace, monospace; font-size: 12px; }
/* Where messages go: the start of the address, the rest in its tooltip. */
- #peers td.via { max-width: 12em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
+ #peers td.via { max-width: 0; min-width: 8em; width: 100%; overflow: hidden; text-overflow: ellipsis; }
/* A peer's status (not the legend's "dormant"). */
#peers .active { color: var(--ok); } #peers .dormant { color: var(--bad); }
#peers .unknown { color: var(--muted); }
@@ -500,7 +500,7 @@ function renderPeers() {
"this node's (its offset taken off): this minute's mean, and the last 15 minutes' as " +
"a line; good to half the round trip, but the trend exactly" };
const rows = [el("tr", {}, ...["peer", "status", "seen", "via", "rtt", "hop", "clock",
- "neighbour", "reaches", "same epoch"]
+ "neighbour", "reaches", "epoch"]
.map(h => el("th", { title: headers[h] || "" }, h)))];
// Whom this node reaches, to tell those a peer reaches and it doesn't.
const ours = new Set(state.peers.localReaches || []);
@@ -526,8 +526,7 @@ function renderPeers() {
peer.clock.withinMs + " ms" : "" }, peer.clock ? seconds(peer.clock.offsetMs) : ""),
el("td", {}, peer.neighbour ? "yes" : ""),
reachesCell(peer.reaches, ours, id),
- el("td", {}, peer.sameEpoch === null || peer.sameEpoch === undefined
- ? "" : peer.sameEpoch ? "yes" : "no"));
+ epochCell(peer.epoch, peer.sameEpoch));
rows.push(row);
}
morphChildren(table, rows);
@@ -537,6 +536,14 @@ function renderPeers() {
? (rows[8].offsetTop + rows[8].offsetHeight) + "px" : "";
}
+// The epoch a peer last said it is on: its generation, flagged where it isn't this
+// node's (they don't sync then); its ID in the tooltip.
+function epochCell(epoch, same) {
+ if (!epoch) return el("td", { title: "it hasn't said yet" }, "");
+ return el("td", { class: same === false ? "epoch-off" : "",
+ title: "epoch " + epoch.id + (same === false ? ": not this node's, so they don't sync" : "") },
+ String(epoch.generation));
+}
// How long a peer's sync messages take to come (`hopDelay`): the latest minute's mean,
// and the last 15 minutes' as a line of bars (a minute without messages blank), each
// figure in the tooltip.