← back to Domain Sniper
dashboard ui: per-log source band with health dots
24e477fa13886422190d7822b5727e7012e1cc8b · 2026-05-12 18:08:36 -0700 · steve
Renders the perLog payload from the WebSocket stats broadcast as a
horizontal strip above the feed: one chip per active CT source showing
log-name + emitted count + idle count + colored health dot.
green = healthy (emitted > 0)
yellow = alive but quiet (idle > 0, emitted == 0 this session)
red = stale (no tick/idle in 60s — wedged)
No dashboard restart needed; express.static serves the new HTML on
next page load. All 6 CT sources currently report green except Sectigo
elephant/tiger which sometimes show yellow during quiet bursts.
Files touched
Diff
commit 24e477fa13886422190d7822b5727e7012e1cc8b
Author: steve <steve@designerwallcoverings.com>
Date: Tue May 12 18:08:36 2026 -0700
dashboard ui: per-log source band with health dots
Renders the perLog payload from the WebSocket stats broadcast as a
horizontal strip above the feed: one chip per active CT source showing
log-name + emitted count + idle count + colored health dot.
green = healthy (emitted > 0)
yellow = alive but quiet (idle > 0, emitted == 0 this session)
red = stale (no tick/idle in 60s — wedged)
No dashboard restart needed; express.static serves the new HTML on
next page load. All 6 CT sources currently report green except Sectigo
elephant/tiger which sometimes show yellow during quiet bursts.
---
public/index.html | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/public/index.html b/public/index.html
index 50abeaa..efb0445 100644
--- a/public/index.html
+++ b/public/index.html
@@ -135,6 +135,10 @@
<span id="conn">connecting…</span>
</span>
</div>
+ <div id="perlog-band" style="display:flex; gap:14px; padding:6px 14px; border-bottom:1px solid #1a1a1a; background:#0a0a0a; font-size:11px; color:var(--dim); overflow-x:auto; white-space:nowrap;">
+ <span style="color:#4ec9b0;">CT sources:</span>
+ <span id="perlog-empty">waiting…</span>
+ </div>
<main id="feed"><div class="empty">waiting for the firehose…</div></main>
<div id="toast" class="toast">copied</div>
@@ -329,6 +333,19 @@
for (const el of [filterEl, showHot, showBrand]) el.addEventListener('input', scheduleRender);
for (const el of [filterEl, showHot, showBrand]) el.addEventListener('change', scheduleRender);
+ const perlogBand = document.getElementById('perlog-band');
+ function renderPerLog(p) {
+ const names = Object.keys(p).sort();
+ if (!names.length) return;
+ const parts = names.map((name) => {
+ const v = p[name];
+ const short = name.replace(/2026h1$/, '');
+ const stale = v.stale ? 'background:#ff3b3b;' : (v.idle > 0 && v.emitted === 0 ? 'background:#e0a050;' : 'background:#4ec9b0;');
+ const dot = `<span style="display:inline-block;width:7px;height:7px;border-radius:50%;margin-right:4px;vertical-align:middle;${stale}"></span>`;
+ return `<span title="${name}">${dot}<b style="color:#d4d4d4;">${short}</b> ${v.emitted}<span style="color:#5a5a5a;">/</span><span style="color:#5a5a5a;">i</span>${v.idle || 0}</span>`;
+ });
+ perlogBand.innerHTML = '<span style="color:#4ec9b0;">CT sources:</span>' + parts.join('');
+ }
function connect() {
const proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
const ws = new WebSocket(proto + '//' + location.host);
@@ -349,6 +366,7 @@
stat.brand.textContent = m.brand.toLocaleString();
startedAt = m.startedAt || startedAt;
stat.uptime.textContent = fmtUptime(Date.now() - startedAt);
+ if (m.perLog) renderPerLog(m.perLog);
}
};
}
← 7992d0c dashboard: per-log tracker + idle counter + /api/perlog endp
·
back to Domain Sniper
·
dashboard: /healthz liveness probe for pm2/launchd dfb3b86 →