Monitoring-Vertrag
Zwei Arten von Heartbeats. Diese Seite beschreibt das Monitoring einer registrierten Chrome-Erweiterung: Ihr Agent sendet seinen Bericht an POST /api/v1/monitoring/report. Umgebungen eines Webprojekts nutzen im Panel einen separaten Endpunkt POST /api/v1/heartbeat/report mit einem anderen Token. Der kleinste Umgebungsbericht ist {"overall":"ok"}; eine v2-Payload für eigene Metriken wird ebenfalls akzeptiert. Vertauschen Sie die beiden Endpunkte beim Einrichten eines Agenten nicht. Abschnitt 8b beschreibt den Heartbeat einer Umgebung.
Monitoring stellt Ihre Erweiterung unter ständige Beobachtung: eine Live-Ampel auf ihrer Karte in der Liste, den Basis-Tab monitoring in der Detailansicht und eine separate Telegram-Statusnachricht mit Flankenalarmen. Es kombiniert zwei unabhängig aktivierbare Komponenten: einen Push-Heartbeat (ein Agent auf dem Host Ihres Dienstes meldet sich nach einem festgelegten Zeitplan; Stille ist selbst ein Signal) und Uptime-Pings (das Panel prüft Ihre öffentlichen URLs auf Erreichbarkeit).
1. Funktionsweise (zwei Komponenten, eine Ampel)
- Push-Heartbeat: Ein Cron-Skript auf Ihrem Host (z. B. ein angepasstes
monitor.sh) sendet im deklarierten Intervall per POST einen v2-Metrikbericht an das Panel. Jeder Bericht muss das reservierte Urteiloverallenthalten. Verpasste Berichte eskalieren die Ampel (Totmannschalter): Fallen Host, Netzwerk oder Cron aus, sehen Sie es gerade daran, dass die Aufrufe ausbleiben. - Uptime-Pings: Das Panel ruft selbst regelmäßig die von Ihnen konfigurierten öffentlichen URLs ab (Site, API, Doku) und prüft nur die Erreichbarkeit, nie den Inhalt. Kein Agent nötig, eine URL genügt.
Eine Erweiterung ist „im Monitoring“, wenn das Monitoring aktiviert und mindestens eine Komponente konfiguriert ist. Andernfalls zeigt ihre Karte einen neutralen grauen Punkt.
1b. Heartbeats und der Slot-Pool
Monitoring ist auf der Erweiterungsebene angesiedelt, als zwei unabhängige flache Listen, die sich einen Slot-Pool teilen: Heartbeats (Push-Quellen, früher „Stands“) und
Uptime-Pings (Pull-Prüfungen). Eine Erweiterung kann mehrere Heartbeats haben – zum Beispiel einen Haupt-Host und einen kostenpflichtigen Worker. Jeder Heartbeat sendet Berichte mit seinem eigenen Bearer-Token und deklariert über sein label seine eigene Darstellung (Tabs, Abschnitte und Telegram-Zeilen). Uptime-Pings sind eine separate flache Liste, die zur Erweiterung gehört und unter keinem Heartbeat verschachtelt ist. Das Panel führt alles zu einer Gesamtampel (Worst-of), einer Detailansicht und einer zusammenfassenden Telegram-Nachricht zusammen.
Heartbeats und Pings teilen sich pro Erweiterung einen gemeinsamen Slot-Pool: Ein Heartbeat kostet einen Slot, ein aktiver Ping kostet einen Slot, und ihre Summe darf max_slots des Tarifs nicht überschreiten (Trial 3 · Studio 10 · Fleet 25). Wird der Pool überschritten, kommt 409 slot_limit zurück; nach einem Downgrade wird der Überschuss pausiert (zuerst Pings, zuletzt Heartbeats). Die Antwort enthält slots_used und max_slots, damit die Oberfläche das Budget anzeigen kann.
2. Die Ampel
Die Gesamtampel ergibt sich als Worst-of über die Komponente jedes aktivierten Heartbeats und die Ampel jedes aktiven Pings, wobei die Schweregrade als ok < warn < crit geordnet sind. Die Komponente eines Heartbeats ist max(reported, watchdog): reported ist der schlechtere Schweregrad aus der Metrik overall und den überschrittenen Schwellenwerten (6.2) aus dem letzten akzeptierten Bericht; watchdog ist eine Frische-Untergrenze, berechnet anhand der Empfangsuhr des Panels (eine abweichende Uhr des Agenten schadet nicht).
| Zustand | Farbe | Wann |
|---|---|---|
off | ⚪ grau | Monitoring nicht aktiviert oder keine Komponente konfiguriert. |
paused | ⚪ grau | Aktiviert, aber eingefroren (Tarifsperre oder manuelle Pause). Berichte werden weiterhin gespeichert. |
green | 🟢 | Alle Komponenten ok. |
yellow | 🟡 | Schlechteste Komponente warn. |
red | 🔴 | Schlechteste Komponente crit. |
Der Schweregrad ist kanonisch ok | warn | crit. Gängige Aliase werden bei der Annahme normalisiert: warning wird zu warn; error und critical werden zu crit.
3. Watchdog (verpasste Heartbeats)
Sie geben beim Aktivieren des Heartbeats das erwartete Berichtsintervall an (60 s bis 24 h). Der Watchdog setzt dann anhand der Frische eine Untergrenze für die Ampel, mit grace = max(60s, 25% of the interval), um Schwankungen von Cron und Netzwerk abzufangen:
| Alter des letzten akzeptierten Berichts | Watchdog-Untergrenze |
|---|---|
| bis Intervall + Karenzzeit | ok (grün) |
| 1 verpasster Bericht (bis 2 × Intervall + Karenzzeit) | warn (gelb) |
| 2 oder mehr verpasste Berichte | crit (rot) |
Ein abgelehnter Bericht (401 / 413 / 422 / 429) aktualisiert den Watchdog nie, daher eskaliert ein defekter Agent ehrlich; der letzte Ablehnungsgrund ist in den Monitoring-Einstellungen sichtbar. Die Erholung erfolgt sofort: Der erste akzeptierte Bericht berechnet die Ampel unmittelbar neu.
4. Uptime-Pings
Ein Ping ist eine benannte Erreichbarkeitsprüfung einer öffentlichen https-URL. Das Panel sendet GET mit einem 10-Sekunden-Timeout, folgt höchstens 5 Weiterleitungen, liest keinen Body über ein minimales Limit hinaus und wertet einen abschließenden Status der Klasse 2xx als Erfolg (auch 204 und 206 zählen). Ein abschließender 3xx-Status (Weiterleitungsschleife oder -limit), 4xx, 5xx, Timeout oder DNS-/TLS-/Netzwerkfehler gilt als Fehlschlag. Eine fehlgeschlagene Prüfung wird durch eine Wiederholung nach ca. 15 s bestätigt, bevor sie zählt; das fängt einzelne Netzwerkaussetzer ab.
| Aufeinanderfolgende bestätigte Fehler | Ping-Ampel |
|---|---|
| 0 | ok |
| 1 | warn |
| 2 oder mehr | crit |
Ping-Ergebnisse erscheinen als panel-eigene Metriken ping:<name> im Abschnitt
pings (Uptime) des Basis-Tabs
monitoring und als reservierte Telegram-Zeile pings: 🟢 api 210ms · 🟢 site 90ms · 🔴 docs (timeout). Die Anzahl der Pings pro Erweiterung und das Mindestintervall hängen vom Tarif ab:
| Tarif | Uptime-Pings pro Erweiterung | Min. Ping-Intervall |
|---|---|---|
| Trial | 3 | 5 Min. |
| Indie | 3 | 5 Min. |
| Studio | 10 | 1 Min. |
| Fleet | 25 | 1 Min. |
Ob Monitoring verfügbar ist und wie viele Slots es gibt, hängt von Ihrem Tarif ab; das minimale Heartbeat-Intervall beträgt 60s.
5. Eine Erweiterung ins Monitoring aufnehmen
In der Erweiterung unter Einstellungen, Block „Monitoring“:
- Schalten Sie das Monitoring ein, sofern Ihr Tarif es enthält.
- Heartbeat: Aktivieren Sie ihn und legen Sie das Berichtsintervall fest; das Panel erzeugt einen Bearer-Token, den Monitoring-Token, der genau einmal angezeigt wird (Sie können ihn jederzeit rotieren; der alte Token erhält sofort 401). Hinterlegen Sie den Token und die Endpunkt-URL in der Umgebung Ihres Agenten.
- Pings: Fügen Sie benannte öffentliche URLs hinzu (z. B.
site,api,docs), jeweils mit eigenem Ping-Intervall, bis zum Limit Ihres Tarifs. - Telegram: Aktivieren Sie die Zustellung des Monitorings und legen Sie optional eine separate Gruppe oder einen separaten Chat fest.
6. Das Berichtsformat
Der Bericht ist dieselbe metadatengesteuerte v2-Payload wie im
Vertrag für eigene Metriken (Tabs, Abschnitte, Telegram-Zeilen, Metriken), gesendet an POST /api/v1/monitoring/report mit Authorization: Bearer <monitoring token>. Monitoring ergänzt reservierte IDs:
| Reservierte ID | Status | Bedeutung |
|---|---|---|
overall | erforderlich | Metrik der Art status: das Urteil des Durchlaufs, Schweregrad ok | warn | crit. Fließt in die Gesamtampel ein. Ein Bericht ohne gültiges overall wird abgelehnt (422). |
issues | empfohlen | Metrik der Art list: die aktuellen Probleme, items auf der obersten Ebene der Metrik. Bis zu 5 Einträge werden in Alarmtexten zitiert. |
ping:* | verboten | Metrik-ID-Namespace der panel-eigenen Ping-Metriken; ein Senden wird abgelehnt (422). |
pings | verboten | Telegram-Zeilen-ID der panel-eigenen Ping-Zeile; ein Senden wird abgelehnt (422). |
monitoring | panel-eigener Tab | Basis-Tab-ID. Metriken können ihn adressieren (dashboard.tab: "monitoring"), ohne ihn in tabs zu deklarieren; eine Deklaration wird ignoriert. |
base | panel-eigener Tab | Die ID des Basic-Tabs, ebenso reserviert: eine Deklaration wird ignoriert. |
Limits: Payload höchstens 64 KB, höchstens 200 Metriken, höchstens 2 Berichte pro Minute pro Quelle (Überschuss erhält 429 und zählt nicht als Heartbeat).
Ein Body über 64 KB erhält 413 payload_too_large und wird nie gekürzt und als kürzerer Bericht gelesen. Ein Bericht, der gegen die obigen Regeln verstößt, erhält 422 invalid_report mit allen Problemen als Liste. Beide Gründe werden als letzter Fehler des Heartbeats gespeichert:
HTTP/1.1 413 Payload Too Large
{ "code": "payload_too_large", "message": "report is over 64 KB; send fewer metrics or split them across heartbeats",
"limit_bytes": 65536, "size_bytes": 71680 }
HTTP/1.1 422 Unprocessable Entity
{ "code": "invalid_report", "message": "report rejected",
"errors": [ "metric \"overall\" must have kind \"status\" (got \"text\")",
"metric id \"ping:x\" uses the reserved \"ping:\" namespace" ] }6.1. Beispielbericht
{
"schema_version": "2.0",
"generated_at": "2026-07-12T10:19:58Z",
"tabs": [ { "id": "stand", "title": "Stand", "order": 5, "icon": "server" } ],
"sections": [ { "tab": "stand", "id": "docker", "title": "Docker", "order": 0 },
{ "tab": "monitoring", "id": "host", "title": "Host", "order": 10 } ],
"telegram": { "header": "{sev} {name} monitoring",
"lines": [ { "id": "host", "order": 0, "prefix": "🖥 " },
{ "id": "docker", "order": 1, "prefix": "📦 " } ] },
"metrics": [
{ "id": "overall", "kind": "status", "state": "ok", "severity": "ok" },
{ "id": "issues", "kind": "list",
"items": [ { "text": "RAM 91% (7.1/7.8G)", "severity": "warn" } ],
"dashboard": { "show": true, "tab": "monitoring", "section": "host", "order": 0,
"render": "list", "name": "Issues" },
"telegram": { "show": false } },
{ "id": "ram", "kind": "percent", "label": "RAM", "value": 91, "severity": "warn",
"dashboard": { "show": true, "tab": "monitoring", "section": "host", "order": 1,
"render": "kpi" },
"telegram": { "show": true, "line": "host", "pos": 10,
"format": "RAM {value}%", "sep": " · " } }
]
}Erfolgreiche Antwort:
{ "accepted": true, "effective": "green", "next_expected_by": "2026-07-12T10:26:13Z" }6.2. Schwellenwerte auf Berichtsmetriken
Jede numerische Metrik eines Berichts außer overall kann thresholds enthalten (der Block des Custom-Metrics-Vertrags, Abschnitt 5.4). Das Panel berechnet die Severity einer solchen Metrik bei der Annahme, und das Licht des Heartbeats ist das Schlechteste aus overall und den überschrittenen Schwellenwerten: Eine Metrik über crit macht den Heartbeat rot, auch wenn overall ok ist. recover bezieht sich auf den vorigen angenommenen Bericht desselben Heartbeats. Ein fehlerhafter Block erhält 422 invalid_report mit dem Grund in der Liste. Ein Bericht ohne Schwellenwerte verhält sich wie bisher.
{ "id": "queue", "kind": "number", "label": "Mail queue", "value": 41,
"thresholds": { "direction": "above", "warn": 20, "crit": 100, "unit": "msgs", "recover": 15 },
"dashboard": { "show": true, "tab": "monitoring", "section": "host", "order": 2, "render": "kpi" },
"telegram": { "show": true, "line": "host", "pos": 20, "format": "queue {value}" } }Das Panel zeigt sie als 41 (threshold 20/100 msgs) auf einer gelben Kachel, und der Heartbeat ist gelb.
7. Ein Monitor-Skript einbinden (im Stil von monitor.sh)
Wenn Sie bereits ein Cron-Skript für Health-Checks betreiben, fügen Sie am Ende jedes Durchlaufs einen POST nach dem Best-Effort-Prinzip hinzu. Ein Zustellfehler darf den Durchlauf nicht abbrechen: Längere Stille fängt der Watchdog ohnehin ab.
# monitor.env
EXTOPS_REPORT_URL="https://extops.dev/api/v1/monitoring/report"
EXTOPS_REPORT_TOKEN="<monitoring token from Settings>"
# end of the tick: build the payload with jq from the values you already computed,
# then push it best-effort (never let delivery break the tick itself)
payload="$(jq -n --arg sev "$SEVERITY" '{
schema_version: "2.0",
generated_at: (now | todate),
metrics: [ { id: "overall", kind: "status", state: $sev, severity: $sev } ]
}')"
code="$(curl -sS -m 10 -o /tmp/extops-report.json -w '%{http_code}' -X POST "$EXTOPS_REPORT_URL" \
-H "Authorization: Bearer $EXTOPS_REPORT_TOKEN" \
-H "Content-Type: application/json" \
-d "$payload" || echo 000)"
# 413 payload_too_large: over 64 KB; 422 invalid_report: .errors lists every problem
case "$code" in 413|422) logger -t monitor "panel: $code $(jq -c . /tmp/extops-report.json)" ;; esac
Ordnen Sie die Schweregrade Ihres Skripts dem kanonischen Satz zu (critical wird akzeptiert und auf crit normalisiert) und speisen Sie Ihre bestehende Problemliste in die Metrik issues ein. Setzen Sie das deklarierte Intervall gleich der Cron-Periode.
8. Telegram: separate Statusnachricht und Alarme
- Monitoring-Daten gehen an Telegram als separate, bearbeitbare Statusnachricht, getrennt von der Statusnachricht der eigenen Metriken: Kopfzeile + die reservierte Zeile
pings+ die Zeilen, die Ihr Bericht deklariert. - Leiten Sie das Monitoring optional in eine separate Gruppe oder einen separaten Chat; ist nichts festgelegt, wird der Kanal-Chat der Erweiterung verwendet. Der Bot-Transport wird mit dem Kanal der Erweiterung geteilt.
- Flankenalarme werden bei jeder Änderung der Gesamtfarbe ausgelöst, in beide Richtungen, einschließlich der Erholung zurück zu Grün (mit Dauer des Vorfalls). Solange die Farbe stabil ist, herrscht Stille; Konfigurationsänderungen (Pausieren, Bearbeiten von Pings) lösen keinen Alarm aus.
8b. Heartbeats von Webprojekten
Ein Webprojekt hat eigene Heartbeats. Jeder gehört zu einer Umgebung (zum Beispiel Production) und hat ein eigenes Token hb_. Für den Bericht gelten die Regeln aus Abschnitt 6; unten steht, was abweicht.
POST /api/v1/heartbeat/report
Authorization: Bearer hb_<64 hex>
Content-Type: application/json
{"overall":"ok"}- Body: ein v2-Bericht mit der Pflichtmetrik
overallder Art status oder der schlanke Body{"overall":"ok"}mitok,warnodercrit. Das Panel macht aus dem schlanken Body einen v2-Bericht und speichert den normalisierten Body. - Limits: höchstens 64 KB pro Bericht, höchstens 4 Berichte pro Minute je Token und höchstens 200 Metriken. Ein Bericht mit mehr als 200 Metriken erhält 422, wie bei einer Erweiterung.
- Antworten:
200 {"accepted":true,"light":"green"},401bei unbekanntem Token,413 payload_too_large,422 invalid_report,429mitRetry-After: 60. Die Gründe für 413 und 422 erscheinen als Last error unter Setup, Monitoring. - Covers: ein Heartbeat deckt null oder mehr Oberflächen seiner Umgebung ab. Seine Ampel färbt jede abgedeckte Oberfläche; ein Heartbeat ohne Abdeckung färbt die Umgebung. Covers wird im Panel festgelegt, nicht im Bericht.
- Hell: grün bis interval + grace nach dem letzten angenommenen Bericht, gelb bis 2 × interval + grace, danach rot, mit
grace = max(60s, 25% of the interval). Das Intervall liegt zwischen 60s und 24h. - Waiting for first report: ein neuer Heartbeat bleibt grau bis zu seinem ersten angenommenen Bericht. Nach 24 Stunden ohne Bericht wird er gelb und sendet eine Benachrichtigung; vor seinem ersten Bericht ist er nie rot.
- Schwellenwerte: wie in Abschnitt 6.2. Das Licht in der 200-Antwort und im Panel ist das Schlechteste aus Aktualität,
overallund den überschrittenen Schwellenwerten, und über Covers erreicht es die abgedeckten Oberflächen. - Tabs: Metriken mit
tab:"monitoring"erscheinen auf dem ersten Tab des Monitoring-Bereichs des Projekts, undbaseist ebenfalls reserviert. Von Ihnen deklarierte Tabs werden eigene Tabs.
8c. Wer sich mit Ihren Diensten verbindet und wie
Ein Webprojekt kann einem Service, dessen Adresse ein Host ist, Port-Prüfungen hinzufügen, zum Beispiel einem Mailserver. Diese Prüfungen führt Ext Ops Panel selbst aus. Dieser Abschnitt sagt, wer sich verbindet, was gesendet wird, wie oft und wie ein Host widersprechen kann. Der Agent-Vertrag oben ändert sich nicht.
- Woher: eine Adresse,
89.117.144.124, mit dem Namenprobe.extops.dev. Der Name löst auf diese Adresse auf, und die Adresse löst zurück auf den Namen auf. Einen anderen Beobachtungspunkt gibt es nicht. - Nur bestätigte Hosts: Eine Prüfung läuft nur auf einem Host unter einer Domain, die der Inhaber des Projekts mit einem DNS-TXT-Eintrag oder einer Well-known-Datei bestätigt hat. Fällt der Nachweis weg, pausieren die Prüfungen.
- Ports: TCP 25, 110, 143, 465, 587, 993, 995; TLS 443, 465, 993, 995; SMTP 25 und 587; SMTPS 465; IMAP 143; IMAPS 993. Kein anderer Port wird je geprüft.
- TCP und TLS: verbinden und die Begrüßung lesen, die der Server sendet, oder einen TLS-Handshake abschließen und das Zertifikat lesen. Es wird nichts gesendet.
- SMTP: auf die Begrüßung
220warten,EHLO probe.extops.devsenden,STARTTLSsenden, wenn der Server es anbietet, und den Handshake abschließen, dannQUITsenden. SMTPS auf Port 465 macht dasselbe innerhalb von TLS, ohne STARTTLS. - IMAP: auf
* OKwarten,a1 CAPABILITYsenden, auf Port 143STARTTLSsenden, wenn es angeboten wird,ID ("name" "ExtOpsPanel-Probe" "support-url" "https://extops.dev/docs/monitoring#probes")nur senden, wenn der Server ID ankündigt, dannLOGOUTsenden. IMAPS auf Port 993 macht dasselbe innerhalb von TLS. - Nie gesendet:
AUTH,LOGIN,AUTHENTICATE,MAIL FROM,RCPT TO,DATA,VRFY,EXPN,SELECT. Die Probe meldet sich nie an, sendet nie Mails und öffnet nie ein Postfach. Jede Zeile durchläuft vor dem Schreiben eine feste Liste erlaubter Befehle, und ein Test schlägt fehl, wenn ein anderer Befehl einen Server erreicht. - Wie oft: Eine Mail-Prüfung läuft in jedem Tarif höchstens alle 5 Minuten, mit einer Streuung von 10% in beide Richtungen. Ein Host erhält höchstens eine Verbindung gleichzeitig und höchstens 40 Verbindungen pro Stunde, für alle Projekte zusammen. Darüber hinaus bleibt der Host bis zur nächsten Stunde unberührt.
- Wenn ein Server ablehnt: Ein SMTP
421stoppt alle Prüfungen dieses Hosts für eine Stunde. Ein SMTP554oder ein IMAP* BYEwird als Ablehnung erfasst und erst im nächsten Intervall erneut versucht. - Grenzen einer Prüfung: 5 Sekunden für den Verbindungsaufbau, 10 Sekunden für den ganzen Dialog, höchstens 4 KB gelesen.
- Was gespeichert wird: das Ergebnis, der Antwortcode, die Latenz, die erste Zeile der Begrüßung, auf 120 Zeichen gekürzt und ohne E-Mail-Adressen, eine kurze Liste von Fähigkeiten wie STARTTLS und IMAP4rev1 und die Daten des Zertifikats. Nicht die ganze Begrüßung, nicht die Antworten auf EHLO oder ID und keine Adressen.
- Widerspruch: Wenn Sie einen Host betreiben und diese Prüfungen nicht wollen, schreiben Sie an
support@extops.dev mit dem Hostnamen. Wir schließen den Host oder seine ganze Domain aus, danach verbindet sich nichts mehr mit ihm. Sie können auch mit
421antworten oder89.117.144.124sperren. Der Inhaber des Projekts kann eine Prüfung jederzeit unter Setup, Monitoring pausieren oder löschen.
9. Der maschinenlesbare Vertrag
Die formale Beschreibung des Berichtsendpunkts, des Payload-Schemas, der reservierten IDs und der Ampelsemantik ist die OpenAPI-3.1-Datei. Sie trägt dieselbe Vertragsversion (2.1.0).