status
Uptime and cron monitoring, incidents and public status pages. Host: status.<d>, public pages at
status.<d>/<slug> or a custom domain. Binary: statusd. Stage 7.
Concepts
- Monitor: HTTP(S) (status, keyword, JSON path, latency threshold), TCP, ping, DNS, TLS expiry,
domain expiry, and heartbeat (a cron job calls
https://status.<d>/ping/<id>, with /start and
/fail; missing pings within the schedule plus grace mean down). Interval, timeout, retries before
alerting, locations.
- Location: the control plane plus any
xvii-node with the probe role; a monitor is down when a
quorum of its locations agrees.
- Auto monitors:
apps endpoints and pages aliases with custom domains can get a monitor with one
switch.
- Incident: opened automatically on down or by hand; updates with text; maintenance windows.
- Status page: chosen monitors grouped into components, uptime bars (90 days), incidents history,
subscribe by e-mail or RSS. Rendered by
statusd as static HTML (cached), not the panel.
Data
Check results in a partitioned table (raw 7 days, 1-minute rollups 90 days, daily forever).
Events
monitor.down, monitor.up, monitor.degraded, heartbeat.missed, certificate.expiring,
incident.opened, incident.resolved.
As built (stage 7)
- Kinds: HTTP(S) (method, good status codes as
200-399,418, a keyword present or absent, a value read
from a JSON answer (gjson path; up, degraded or down by its value), a slow
threshold that marks it degraded, the certificate's end read on every check), TCP, DNS (A, AAAA, CNAME,
MX, NS, TXT, an expected value), heartbeat (/ping/<key>, /start, /fail with the reason in the
body; period and grace). Intervals 30 s to a day; down after retries failures in a row (2 by default),
failing monitors are checked again within 20 s.
- Locations: the control plane only for now; probes on nodes and a quorum come later.
- Checks reach the internet only: loopback, private, link-local and CGNAT addresses are refused when
dialing, and literal ones when saving.
- A state change opens or resolves an automatic incident and emits
monitor.down / heartbeat.missed,
monitor.up, monitor.degraded in the check's transaction; certificate.expiring at 14, 7, 3 and 1
days. Maintenance windows are incidents with impact maintenance (scheduled → in progress →
completed by their times) that keep their monitors quiet.
- Data:
checks kept 7 days; days (per monitor and UTC day: checks, up, degraded, response sum, down
seconds) kept for good. No partitioning yet.
- Status pages are the panel's public route
status.<d>/p/<slug> (React and shadcn like every panel,
not static HTML), fed by /api/v1/public/<slug>: labels, states, 90 days and the incidents of the
last 14 days — never addresses or ids. RSS at /p/<slug>/feed.xml.
- A page's look (tab Look): a logo (PNG, JPEG, WebP, GIF or SVG up to 256 KB, served at
/p/<slug>/logo sandboxed, also the favicon), an accent colour (the theme's primary), a fixed theme or
the visitor's, a notice on top, up to four header links, a footer line, and hiding "xvii status".
- A page's own host name comes from domains: Attach there with a status page as the target makes the
A record and the certificate, domains tells status (
POST /api/v1/pages/{id}/domains, its service
token only) and relays the name to statusd, which serves the page at the name's root (a meta tag in
index.html tells the panel which). Its links, feed and e-mails use that name from then on.
- E-mail subscriptions (a switch under Look; needs
SMTP_URL): a form on the page, a confirmation
message (10 an hour per visitor address), then every incident update of the page's monitors — sent
within half a minute, once (incident_updates.mailed_at) — in the subscriber's language, with a
one-click unsubscribe link (List-Unsubscribe). The team's developers see and remove subscribers.
- Automatic monitors: a team's switch; every production web app (apps, not previews or stopped ones,
https://<host><health path>) and production pages alias gets an HTTP monitor within 5 minutes, with
its address kept in step; removed when the app or alias goes or the switch goes off; one deleted by hand
isn't made again. status reads the lists with its own token (pages and apps let it list, nothing more).
- Limits
status.monitors, status.pages. Journal: monitor.*, incident.*, maintenance.schedule,
page.* (incl. page.logo, page.domain), subscriber.delete, auto.on, auto.off.
- xvii.network's own page:
https://status.xvii.network/p/xvii.