···11# status
2233-my own status page
33+super simple cf worker based uptime / status dashboard running [infra.dunkirk.sh](https://infra.dunkirk.sh).
4455The canonical repo for this is hosted on tangled over at [`dunkirk.sh/status`](https://tangled.org/dunkirk.sh/status)
66+77+## API
88+99+```
1010+/api/status # overall summary (ok, status, uptime, counts)
1111+/api/status/overall # same as above
1212+/api/status/service/:id # single service status + latency + uptime
1313+/api/status/machine/:name # machine online status + all its services
1414+/api/uptime/:service_id # hourly uptime buckets for a service
1515+```
1616+1717+## Badges
1818+1919+```
2020+/badge # overall infra status
2121+/badge/overall # same as above
2222+/badge/service/:id # single service
2323+/badge/machine/:name # machine status
2424+```
2525+2626+**Query params:**
2727+2828+| Param | Description | Example |
2929+| -------- | ----------------------------------- | ---------------------- |
3030+| `style` | `flat` (default) or `for-the-badge` | `?style=for-the-badge` |
3131+| `colorA` | Label background (hex) | `?colorA=363a4f` |
3232+| `colorB` | Value background (hex) | `?colorB=b7bdf8` |
3333+| `label` | Override label text | `?label=my+service` |
3434+3535+## Setup
3636+3737+```bash
3838+bun install
3939+wrangler d1 create status-db
4040+wrangler kv namespace create KV
4141+# update wrangler.toml with the IDs
4242+bun run db:migrate:local
4343+wrangler secret put TAILSCALE_API_KEY
4444+bun run dev
4545+```
4646+4747+## Deploy
4848+4949+```bash
5050+bun run deploy
5151+bun run db:migrate
5252+```
653754<p align="center">
855 <img src="https://raw.githubusercontent.com/taciturnaxolotl/carriage/main/.github/images/line-break.svg" />
+8-11
src/index.ts
···33import { checkHealth } from "./health";
44import { insertPing, pruneOldPings } from "./db";
55import { refreshDevices } from "./tailscale";
66-import { handleStatus } from "./routes/status";
66+import { handleStatusRoute } from "./routes/status";
77import { handleUptime } from "./routes/uptime";
88-import { handleBadge, handleOverallBadge } from "./routes/badge";
88+import { handleBadgeRoute } from "./routes/badge";
99import { handleIndex } from "./routes/index";
10101111export default {
···1717 return handleIndex(env);
1818 }
19192020- if (path === "/api/status") {
2121- return handleStatus(env);
2020+ if (path.startsWith("/api/status")) {
2121+ const res = await handleStatusRoute(env, path);
2222+ if (res) return res;
2223 }
23242425 const uptimeMatch = path.match(/^\/api\/uptime\/(.+)$/);
···2627 return handleUptime(env, uptimeMatch[1], url);
2728 }
28292929- if (path === "/badge") {
3030- return handleOverallBadge(env);
3131- }
3232-3333- const badgeMatch = path.match(/^\/badge\/(.+)$/);
3434- if (badgeMatch) {
3535- return handleBadge(env, badgeMatch[1]);
3030+ if (path.startsWith("/badge")) {
3131+ const badge = await handleBadgeRoute(env, path, url);
3232+ if (badge) return badge;
3633 }
37343835 return new Response("Not Found", { status: 404 });