feat(errors, watchdog): Fehler-Stream mit Ignore-Regeln, Metrik-Verlauf, Abhängigkeits-Alarme

Fehler-Schnittstelle
- Neuer schlanker Eingang POST /api/errors/v1/report für den globalen
  Exception-Handler einer Anwendung. Titel und Dringlichkeit leitet der Server
  ab; gespeichert wird in derselben Tabelle wie der Bugtracker. Ein zweiter
  Speicher wäre nur ein zweiter Ort, an dem man suchen müsste.
- error_level (fatal/error/warning) trennt die technische Art des Ereignisses
  von der geschäftlichen Dringlichkeit. Ein Duplicate-Entry ist technisch ein
  error, geschäftlich belanglos — beides zu vermischen war der Grund, warum
  solche Meldungen als Bug im Dashboard landeten.

Ignore-Regeln gegen bekanntes Rauschen
- bugtracker_ignore_rules mit contains/regex/exception_class, Pflichtfeld für
  die Begründung und optionaler Alarmschwelle.
- Ein Treffer bedeutet nicht "wegwerfen": Der Fehler wird weiterhin erfasst und
  hochgezählt, bleibt aber aus der Übersicht heraus und löst keine
  Benachrichtigung aus. Der Zähler ist der eigentliche Zweck — dass ein
  bekannter Fehler auftritt, ist normal; dass er plötzlich hundertmal so oft
  auftritt, ist ein Signal. Dafür das rollende Stundenfenster und
  error.rate_exceeded.
- Neue Regeln lassen sich rückwirkend auf bestehende Einträge anwenden.

Gruppierung überarbeitet
- Der Schlüssel nahm bisher 300 Zeichen Stacktrace auf. Derselbe Fehler
  zersplitterte dadurch, sobald ein Aufrufer den Stack einmal mitschickte und
  einmal nicht. Jetzt zählt der Ursprungsort: bevorzugt die Dateiangabe, sonst
  der erste Rahmen des Stacktrace.
- Die Normalisierung ersetzte nur Zahlen ab vier Stellen, wodurch
  'AA-1' und 'BB-2' getrennt blieben. Werte in Anführungszeichen, die Ziffern
  enthalten, gelten jetzt als veränderlich — der Schlüsselname bleibt erhalten,
  sodass verschiedene Unique-Keys unterscheidbar sind. Mit 9 Testfällen belegt.

Metrik-Verlauf
- watchdog_metrics speichert numerische Heartbeat-Werte mit Zeitstempel.
  Zuvor wurde metrics_json bei jedem Heartbeat überschrieben; damit ließ sich
  "die Platte läuft seit drei Tagen voll" nicht erkennen, nur "sie ist voll".
- GET /api/watchdog/v1/metrics liefert den verdichteten Verlauf und die
  Abweichung vom eigenen Sieben-Tage-Durchschnitt. Dieser relative Ansatz
  braucht keine projektspezifischen Schwellwerte.
- Aufbewahrung 14 Tage, Bereinigung stündlich durch den Evaluator.

Health-Checks per Push statt Abruf
- Der Heartbeat nimmt ein checks-Objekt entgegen, das die Anwendung selbst
  ermittelt. Das Deploymentcenter interpretiert die Namen nicht, es liest nur
  ok und message — was "gesund" bedeutet, entscheidet jede Anwendung selbst.
  Schlägt eine Prüfung fehl, wird ein als ok gemeldeter Heartbeat auf warning
  herabgestuft.
- Bewusst ausgehend: auf den Zielmaschinen müssen keine Ports geöffnet werden.

Abhängigkeitsbewusste Alarmierung
- Fällt ein Monitor aus, dessen Parent selbst unten ist, wird der Alarm
  unterdrückt. Der Zustand bleibt sichtbar. Vorher erzeugte ein ausgefallener
  Hypervisor mit zwölf VMs dreizehn Meldungen für ein Problem.
- Mehrere Ebenen und fehlerhafte Hierarchien (Zyklen, gelöschte Parents) sind
  abgesichert; mit 10 Testfällen belegt.

WebUI
- Neue Ansicht "Fehler-Stream" mit Filtern nach Projekt, Fehlerklasse,
  Umgebung, Zeitraum und Sichtbarkeit sowie Volltextsuche und Pagination.
  Stummgeschaltete Einträge sind standardmäßig ausgeblendet.
- Verwaltung der Ignore-Regeln inklusive Trefferzähler.
- Die Detailansicht zeigt Fehlerklasse, Stummschaltungsgrund und die Häufung
  im laufenden Stundenfenster.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Deploymentcenter Bot
2026-08-07 21:55:23 +02:00
co-authored by Claude Opus 5
parent a74c6fd990
commit 60e34b29f6
13 changed files with 2228 additions and 45 deletions
+74 -1
View File
@@ -171,7 +171,80 @@ Zusätzlich stichprobenartig im WebUI prüfen:
---
## 10. Optional: Webhooks
## 10. Fehler-Stream (Migration 007)
Neu ist eine eigene Schnittstelle für Laufzeitfehler, gedacht für den globalen
Exception-Handler einer Anwendung:
```
POST /api/errors/v1/report
```
Gespeichert wird in derselben Tabelle wie der Bugtracker — ein zweiter Speicher
wäre nur ein zweiter Ort, an dem man suchen müsste. Die Trennung von Rauschen
und Signal leisten stattdessen **Ignore-Regeln**.
### Bekannte, harmlose Fehler stummschalten
Im WebUI unter **Bugtracker → 🔇 Ignore-Regeln**. Ein Treffer bedeutet nicht
„wegwerfen": Der Fehler wird weiterhin erfasst und hochgezählt, bleibt aber aus
der Übersicht heraus und löst keine Benachrichtigung aus.
Der Zähler ist dabei der eigentliche Zweck. Zu jeder Regel lässt sich eine
Alarmschwelle hinterlegen — dass ein bekannter Fehler auftritt, ist normal;
dass er plötzlich hundertmal so oft auftritt, bedeutet, dass sich etwas
geändert hat.
Eine deaktivierte Vorlage für den Duplicate-Entry-Fall liegt bereits vor; sie
lässt sich im WebUI anpassen und einschalten.
### Gruppierung
Veränderliche Anteile werden beim Zusammenfassen ausgeblendet: Werte in
Anführungszeichen, die Ziffern enthalten, Speicheradressen, GUIDs, Zeitstempel
und Zeilennummern. `Duplicate entry 'MKT-88213'` und `Duplicate entry 'AA-1'`
landen damit in einer Gruppe — ein anderer Unique-Key dagegen nicht.
> **Hinweis:** Migration 007 ändert die Berechnung des Gruppenschlüssels.
> Bereits erfasste Einträge behalten ihren alten Schlüssel; ein erneut
> auftretender Fehler legt daher einmalig eine neue Gruppe an. Danach ist der
> Zustand wieder konsistent.
## 11. Metrik-Verlauf und Health-Checks
Numerische Werte aus dem Heartbeat-Feld `metrics` werden jetzt mit Zeitstempel
abgelegt (Aufbewahrung 14 Tage) und lassen sich über
`GET /api/watchdog/v1/metrics` abfragen. Zuvor wurde `metrics_json` bei jedem
Heartbeat überschrieben — es gab immer nur den letzten Moment.
Zusätzlich kann eine Anwendung ihren Gesundheitszustand selbst mitschicken:
```json
{ "source": "polytrader-worker", "status": "ok", "interval": 60,
"checks": {
"db": { "ok": true },
"market_feed": { "ok": false, "message": "Letzter Tick vor 14 min" }
} }
```
Das Deploymentcenter interpretiert die Namen nicht — es liest nur `ok` und
`message`. Schlägt eine Prüfung fehl, wird ein als `ok` gemeldeter Heartbeat auf
`warning` herabgestuft. **Es müssen keine Ports geöffnet werden**, der Weg ist
ausgehend.
## 12. Abhängigkeitsbewusste Alarmierung
Fällt ein Monitor aus, für den `parent_source` gesetzt ist, und ist der
übergeordnete Monitor selbst unten, wird der Alarm für das Kind unterdrückt.
Der Zustand bleibt im Dashboard sichtbar.
Vorher erzeugte ein ausgefallener Hypervisor mit zwölf VMs dreizehn Meldungen
für ein Problem.
Damit das greift, muss die Hierarchie gepflegt sein — im WebUI unter
**WatchDog → System-Hierarchie** über das Feld *Übergeordnete Entität*.
## 13. Optional: Webhooks
Ereignisgesteuerte Benachrichtigung statt Polling. Ziel direkt in der Datenbank
eintragen: