Zum Inhalt

Statusmodell

Komponenten und Status

Eine Komponente ist ein Service auf der Statusseite. Komponenten gehören zu einer Gruppe. Jede Komponente hat einen von fünf Status:

Status Bedeutung
operational Kein aktives Problem
degraded_performance Der Service funktioniert, ist aber langsamer oder eingeschränkt
partial_outage Ein Teil des Services ist nicht verfügbar
major_outage Der Service ist nicht verfügbar
under_maintenance Ein Wartungsfenster ist aktiv

Das Gesamtbanner leitet sich aus allen Komponenten ab: operational, maintenance, degraded, partial_outage oder major_outage, je nach schwerstem Zustand.

Lebenszyklus eines Services

Unabhängig vom Status hat jede Komponente einen Modus (components.service_status):

Modus Bedeutung
draft In Vorbereitung, nicht öffentlich sichtbar
active_public Aktiv und auf der öffentlichen Seite sichtbar (Standard)
active_internal Aktiv, aber nur für angemeldete Teammitglieder auf der Statusseite sichtbar
inactive Nicht mehr in Betrieb
archived Archiviert, nur noch in der Service-Verwaltung sichtbar und nicht mehr umbenennbar

Öffentlich sichtbar ist nur active_public. Angemeldete Nutzer sehen auf der Statusseite zusätzlich active_internal. Statusänderungen, neue Incidents und Wartungen sind nur für die beiden aktiven Modi möglich (lib/domain/service-status.ts).

Fenster statt Snapshots

Die Statushistorie wird als Fenster gespeichert, nicht als eine Zeile je Statuswechsel. Tabelle: component_status_events.

  • Eine Zeile besagt: Dieser Status gilt von created_at bis ended_at. ended_at = NULL bedeutet, dass das Fenster noch offen ist.
  • Ein nicht operativer Status öffnet ein Fenster. „Operational“ wird nie als Event gespeichert. Es ist der abgeleitete Zustand „kein offenes Fenster“ (currentStatusFromWindows).
  • Kehrt eine Komponente zu operational zurück, werden alle offenen Ausfall- und Wartungsfenster mit ended_at = jetzt geschlossen.

Dieses Modell macht zeitbezogene Fragen einfach: Uptime eines Tages, die Ausfallabschnitte im 90-Tage-Balken oder die Verfügbarkeit eines Monats werden aus den Fenstern berechnet, die den Zeitraum überlappen (buildDailyUptime, buildStatusSegments).

Die Cache-Spalte

components.status speichert den aktuellen Status als Cache. Die Invariante lautet: Der gecachte Status entspricht dem schwersten Status der offenen Fenster, sonst operational. Geschrieben wird die Spalte nur über setComponentsStatusTx, das Fenster und Cache in derselben Transaktion pflegt. Konfigurationsänderungen an der Komponente berühren die Spalte nicht.

Ein Einstiegspunkt für Änderungen

Statusänderungen laufen über applyComponentStatusChange in lib/domain/component-status.ts:

  • der manuell gesetzte Status in der Admin-Oberfläche (Service Status)
  • die API-Routen /api/outage/service und /api/outage/start
  • der Sweep der Uptime-Checks

Die Funktion öffnet eine Transaktion und liest den vorherigen Status mit SELECT … FOR UPDATE. Dadurch werden gleichzeitige Änderungen derselben Komponente serialisiert, und ein Benachrichtigungstyp wird nie aus einem veralteten Vorgängerstatus abgeleitet.

Es gibt zwei dokumentierte Ausnahmen:

  • /api/outage/end schließt das Fenster und schreibt den Cache-Wert operational in derselben Transaktion, um eine Race-Condition zwischen beiden Schritten zu vermeiden (Issue #95).
  • Incidents schreiben den Status der betroffenen Komponenten direkt über setComponentsStatusTx in einer eigenen Transaktion und benachrichtigen über den Incident-Weg.

Wartungen schreiben keinen Status. under_maintenance wird beim Lesen aus dem Zeitfenster abgeleitet und überlagert den gespeicherten Status (lib/domain/maintenance.ts). Wird under_maintenance manuell gesetzt, entsteht dagegen ein normales Fenster.

Nachträgliche Erfassung und Korrekturen

  • Incidents können rückdatiert werden. Ihre Fenster beginnen zum Auftrittszeitpunkt, spätere, noch offene Fenster bleiben unberührt.
  • Bei abgeschlossenen Incidents kann das exakte Ausfallfenster je Komponente korrigiert werden (incident_components.outage_start_at / outage_end_at). Diese Korrekturen ersetzen die ursprünglichen Fenster autoritativ (applyIncidentOutageCorrections).
  • Wartungsfenster bleiben ebenfalls in der Historie, zählen aber nie als aktiver Ausfall (siehe Incidents & Wartungen).

Öffentliche Status-API

/api/status liefert die aktuellen Status und die 90-Tage-Uptime je Komponente. Der Endpunkt wird 30 Sekunden gecacht. Die öffentlichen HTML-Seiten werden nicht gecacht, Besucher sehen also immer den aktuellen Stand.