← back to Domain Sniper
brand-typo-watcher: idle counter + stale-log marker in per-log breakdown
fa1502da1759426c67c59da8f1a4c3760ddca999 · 2026-05-12 17:59:16 -0700 · steve
Taps the source's 'idle' status events (treeSize unchanged this poll)
and tracks lastSeenMs per log. Per-log breakdown now shows i=N for idle
polls and prepends a red ! when no event of either kind has arrived
in 60s. Distinguishes:
alive+busy (i=0, climbing emit)
alive+quiet (i high, emit low — e.g. Sectigo tiger)
wedged (no updates either way — red ! marker)
First minute post-bounce confirms: tiger=0(0x/0p i=10) — clearly alive
but Sectigo just isn't producing certs this minute. Previously this
looked indistinguishable from a stuck poller.
Files touched
Diff
commit fa1502da1759426c67c59da8f1a4c3760ddca999
Author: steve <steve@designerwallcoverings.com>
Date: Tue May 12 17:59:16 2026 -0700
brand-typo-watcher: idle counter + stale-log marker in per-log breakdown
Taps the source's 'idle' status events (treeSize unchanged this poll)
and tracks lastSeenMs per log. Per-log breakdown now shows i=N for idle
polls and prepends a red ! when no event of either kind has arrived
in 60s. Distinguishes:
alive+busy (i=0, climbing emit)
alive+quiet (i high, emit low — e.g. Sectigo tiger)
wedged (no updates either way — red ! marker)
First minute post-bounce confirms: tiger=0(0x/0p i=10) — clearly alive
but Sectigo just isn't producing certs this minute. Previously this
looked indistinguishable from a stuck poller.
---
brand-typo-watcher.js | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/brand-typo-watcher.js b/brand-typo-watcher.js
index 5cde839..4054fac 100644
--- a/brand-typo-watcher.js
+++ b/brand-typo-watcher.js
@@ -205,11 +205,16 @@ function connectCtLog() {
} else if (st.type === 'resumed') {
console.error(`[${ts()}] resumed ${st.log} at cursor=${st.position}`);
} else if (st.type === 'tick' && st.log) {
- const p = (perLog[st.log] = perLog[st.log] || { fetched: 0, x509: 0, precert: 0, emitted: 0 });
+ const p = (perLog[st.log] = perLog[st.log] || { fetched: 0, x509: 0, precert: 0, emitted: 0, idle: 0, lastSeenMs: 0 });
p.fetched = st.stats ? st.stats.fetched : p.fetched;
p.x509 = st.stats ? st.stats.x509 : p.x509;
p.precert = st.stats ? st.stats.precert : p.precert;
p.emitted = st.stats ? st.stats.emitted : p.emitted;
+ p.lastSeenMs = Date.now();
+ } else if (st.type === 'idle' && st.log) {
+ const p = (perLog[st.log] = perLog[st.log] || { fetched: 0, x509: 0, precert: 0, emitted: 0, idle: 0, lastSeenMs: 0 });
+ p.idle++;
+ p.lastSeenMs = Date.now();
}
},
});
@@ -223,11 +228,14 @@ function connect() {
setInterval(() => {
console.error(`[${ts()}] seen=${count.seen} hits=${count.hits} (substring=${count.substring} typo=${count.typo}) puny=${count.puny} noise=${count.noise}`);
const logs = Object.keys(perLog).sort();
+ const now = Date.now();
if (logs.length) {
const parts = logs.map((l) => {
const p = perLog[l];
const short = l.replace(/2026h1$/, '').slice(0, 8);
- return `${short}=${p.emitted}(${p.x509}x/${p.precert}p)`;
+ const stale = p.lastSeenMs && (now - p.lastSeenMs > 60_000);
+ const tag = stale ? '\x1b[31m!\x1b[0m' : '';
+ return `${short}=${p.emitted}(${p.x509}x/${p.precert}p i=${p.idle || 0})${tag}`;
});
console.error(`[${ts()}] per-log: ${parts.join(' ')}`);
}
← 44a0139 audit-noise: surface candidate NOISE_PATTERNS by suffix tall
·
back to Domain Sniper
·
dashboard: per-log tracker + idle counter + /api/perlog endp 7992d0c →