From 8feffa98bcaaccde8f364be58df14868d17f89a6 Mon Sep 17 00:00:00 2001 From: nate Date: Wed, 8 Apr 2026 16:58:00 +0400 Subject: [PATCH] update: fixes, add rss link --- apps/status/src/data.ts | 63 +++++++++++++++++++++++++++----- apps/status/src/static/expand.js | 11 ------ apps/status/src/views/page.ejs | 20 ++++++---- 3 files changed, 66 insertions(+), 28 deletions(-) diff --git a/apps/status/src/data.ts b/apps/status/src/data.ts index 29d05ce..e7f9dfc 100644 --- a/apps/status/src/data.ts +++ b/apps/status/src/data.ts @@ -58,6 +58,56 @@ export interface MonitorRow { latency_history: Array<{ region: string; latency_ms: number | null; ts: string }>; } +// Average latency of the *fastest* region per monitor over a given window. +// Status pages are customer-facing โ€” we want to show our best foot forward, +// not a noisy average that gets dragged down by a single distant region. +export async function loadFastestRegionLatency( + monitorIds: string[], + bucket: BucketType, + intervalLiteral: string, +): Promise> { + const out: Record = {}; + if (monitorIds.length === 0) return out; + for (const id of monitorIds) out[id] = null; + + const ids = sql.array(monitorIds); + let rows = await sql` + SELECT monitor_id, region, + (sum(avg_latency * total) / NULLIF(sum(total), 0))::float AS avg_lat + FROM monitor_uptime_rollup + WHERE monitor_id = ANY(${ids}::text[]) + AND bucket_type = ${bucket} + AND bucket_start > now() - ${intervalLiteral}::interval + AND avg_latency IS NOT NULL + GROUP BY 1, 2 + `; + + if (rows.length === 0) { + // Fallback while rollup is unpopulated. Bounded by the same window so cheap. + rows = await sql` + SELECT monitor_id, COALESCE(region, 'default') AS region, + avg(latency_ms)::float AS avg_lat + FROM pings + WHERE monitor_id = ANY(${ids}::text[]) + AND checked_at > now() - ${intervalLiteral}::interval + AND latency_ms IS NOT NULL + GROUP BY 1, 2 + `; + } + + // For each monitor, keep the region with the lowest average latency. + for (const r of rows) { + if (r.avg_lat == null) continue; + const cur = out[r.monitor_id]; + if (cur == null || r.avg_lat < cur) out[r.monitor_id] = r.avg_lat; + } + // Round to integer ms. + for (const id of Object.keys(out)) { + if (out[id] != null) out[id] = Math.round(out[id] as number); + } + return out; +} + // Single SQL pass that produces all four uptime windows for a set of monitors. // Reads only the rollup table; falls back to a pings aggregate when the rollup // has nothing for these monitors yet (same pattern as loadMonitors). @@ -226,18 +276,14 @@ export async function loadMonitors(pageId: string, window: Window, pageDisplayMo // Index actual rollup data by (monitor_id, isoBucketStart) so we can fill in // the missing slots below. const indexed: Record> = {}; - const latencyByMonitor: Record = {}; for (const r of rollupRows) { const startIso = r.bucket_start instanceof Date ? r.bucket_start.toISOString() : String(r.bucket_start); if (!indexed[r.monitor_id]) indexed[r.monitor_id] = {}; indexed[r.monitor_id]![startIso] = { total: r.total, up: r.up_count, avg_latency: r.avg_latency ?? null }; - if (r.avg_latency != null) { - const acc = latencyByMonitor[r.monitor_id] ?? { sum: 0, n: 0 }; - acc.sum += r.avg_latency * r.total; - acc.n += r.total; - latencyByMonitor[r.monitor_id] = acc; - } } + // Customer-facing latency = average of the fastest region for the page's + // window. Computed via a separate query that retains per-region info. + const fastestLatency = await loadFastestRegionLatency(ids, bucket, intervalLiteral); // Generate the full sequence of expected bucket timestamps so empty bars // render as "no data" instead of disappearing entirely. Truncate `now()` to @@ -305,8 +351,7 @@ export async function loadMonitors(pageId: string, window: Window, pageDisplayMo const upT = buckets.reduce((a, b) => a + b.up, 0); uptime_pct = tot > 0 ? +(100 * upT / tot).toFixed(2) : null; } - const latAcc = latencyByMonitor[m.id]; - const avg_latency = latAcc && latAcc.n > 0 ? Math.round(latAcc.sum / latAcc.n) : null; + const avg_latency = fastestLatency[m.id] ?? null; // Per-monitor display mode override โ†’ page default โ†’ 'expanded'. const display_mode = (m.spm_display_mode === 'compact' || m.spm_display_mode === 'expanded') ? m.spm_display_mode diff --git a/apps/status/src/static/expand.js b/apps/status/src/static/expand.js index 40d6573..2d98964 100644 --- a/apps/status/src/static/expand.js +++ b/apps/status/src/static/expand.js @@ -88,16 +88,6 @@ var barsHtml = renderBars(buckets); - var regionsHtml = ""; - if (m.region_states && m.region_states.length > 1) { - regionsHtml = '
'; - for (var r = 0; r < m.region_states.length; r++) { - var rs = m.region_states[r]; - regionsHtml += '' + escapeHtml(rs.region) + ""; - } - regionsHtml += "
"; - } - var latencyHtml = ""; if (showResponseTime && m.avg_latency != null) { latencyHtml = "" + m.avg_latency + "ms ยท "; @@ -119,7 +109,6 @@ html += '
30d
' + fmtUptime(u.d30) + "
"; html += '
90d
' + fmtUptime(u.d90) + "
"; html += ""; - html += regionsHtml; html += incidentsHtml; return html; } diff --git a/apps/status/src/views/page.ejs b/apps/status/src/views/page.ejs index 5dde360..129a90e 100644 --- a/apps/status/src/views/page.ejs +++ b/apps/status/src/views/page.ejs @@ -101,6 +101,10 @@ body { margin: 0; background: var(--bg); color: var(--fg); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif; line-height: 1.5; } main { max-width: 880px; margin: 0 auto; padding: 3rem 1.5rem; } h1 { font-size: 1.75rem; font-weight: 700; margin: 0 0 0.5rem; } + .title-row { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.5rem; } + .title-row h1 { margin: 0; } + .rss-link { color: var(--muted); display: inline-flex; align-items: center; transition: color 0.15s; } + .rss-link:hover { color: #f59e0b; } .muted { color: var(--muted); font-size: 0.875rem; } .overall { padding: 1.25rem 1.5rem; border-radius: 12px; color: var(--overall-fg); font-weight: 600; font-size: 1.05rem; margin: 1.5rem 0 2rem; display: flex; align-items: center; gap: 0.75rem; } .overall .dot { width: 12px; height: 12px; border-radius: 50%; background: var(--overall-fg); opacity: 0.9; } @@ -177,7 +181,14 @@
-

<%= page.title %>

+
+

<%= page.title %>

+ + + +
<% if (page.description) { %>
<%= page.description %>
<% } %>
@@ -284,13 +295,6 @@
30d
<%= fmtUptime(u.d30) %>
90d
<%= fmtUptime(u.d90) %>
- <% if (m.region_states && m.region_states.length > 1) { %> -
- <% m.region_states.forEach(function(r) { %> - <%= r.region %> - <% }); %> -
- <% } %> <% } %> <% }); %>