my own status page
1import type { Env, Incident, ServicesManifest } from "./types";
2import { getManifest } from "./manifest";
3import { getAllLatestPings, getActiveIncidents } from "./db";
4import { getDeviceStatus } from "./tailscale";
5
6export type OverallGrade = "up" | "degraded" | "down";
7
8export interface OverallStatus {
9 grade: OverallGrade;
10 label: string;
11}
12
13export async function getOverallStatus(
14 env: Env,
15 prefetched?: {
16 manifest?: ServicesManifest;
17 latestPings?: Map<string, { status: string; latency_ms: number | null }>;
18 activeIncidents?: Incident[];
19 machineOnline?: Map<string, boolean>;
20 },
21): Promise<OverallStatus> {
22 const manifest = prefetched?.manifest ?? await getManifest(env);
23 const latestPings = prefetched?.latestPings ?? await getAllLatestPings(env.DB);
24 const activeIncidents = prefetched?.activeIncidents ?? await getActiveIncidents(env.DB);
25
26 const servers = Object.entries(manifest).filter(
27 ([, m]) => m.type === "server" && m.services.some((s) => s.health_url),
28 );
29
30 const statuses: string[] = [];
31 let anyServerOffline = false;
32
33 for (const [name, machine] of servers) {
34 const online = prefetched?.machineOnline?.get(name) ?? await getDeviceStatus(env, machine.tailscale_host);
35 if (!online) anyServerOffline = true;
36
37 for (const svc of machine.services.filter((s) => s.health_url)) {
38 const ping = latestPings.get(svc.name);
39 statuses.push(ping?.status ?? "unknown");
40 }
41 }
42
43 const downCount = statuses.filter(
44 (s) => s === "down" || s === "timeout",
45 ).length;
46 const downRatio = statuses.length > 0 ? downCount / statuses.length : 0;
47 const onFire = anyServerOffline || downRatio >= 0.4;
48 const hasDegraded = statuses.some(
49 (s) =>
50 s === "down" ||
51 s === "timeout" ||
52 s === "degraded" ||
53 s === "misconfigured",
54 );
55
56 const hasCritical = activeIncidents.some((i) => i.severity === "critical");
57 const hasMajor = activeIncidents.some((i) => i.severity === "major");
58
59 if (hasCritical || onFire) return { grade: "down", label: "On fire" };
60 if (hasMajor || hasDegraded) return { grade: "degraded", label: "Some systems degraded" };
61 return { grade: "up", label: "All systems operational" };
62}