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>
102 lines
5.4 KiB
SQL
102 lines
5.4 KiB
SQL
-- Migration 007: Fehler-Stream, Ignore-Regeln, Metrik-Verlauf, Health-Checks
|
|
--
|
|
-- Additive Migration. Der Migrator toleriert 1050/1060/1061/1062.
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- 1. Fehlerklasse getrennt vom Schweregrad
|
|
-- ---------------------------------------------------------------------------
|
|
-- severity beschreibt die geschaeftliche Dringlichkeit (low ... critical),
|
|
-- error_level die technische Art des Ereignisses. Ein "Duplicate entry" ist
|
|
-- technisch ein error, geschaeftlich aber belanglos - beides zu vermischen
|
|
-- war der Grund, warum solche Meldungen bisher als Bug im Dashboard landeten.
|
|
ALTER TABLE bugtracker_items
|
|
ADD COLUMN error_level ENUM('fatal','error','warning') NULL AFTER severity;
|
|
|
|
-- Status "ignored": bekannt, harmlos, wird weiter gezaehlt, aber nicht gemeldet.
|
|
ALTER TABLE bugtracker_items
|
|
MODIFY COLUMN status ENUM('open','planned','in_progress','resolved','closed','rejected','ignored')
|
|
NOT NULL DEFAULT 'open';
|
|
|
|
-- Rollendes Stundenfenster fuer die Ratenerkennung. Interessant ist nicht,
|
|
-- DASS ein bekannter Fehler auftritt, sondern wenn er ploetzlich viel
|
|
-- haeufiger auftritt.
|
|
ALTER TABLE bugtracker_items ADD COLUMN rate_window_start DATETIME NULL AFTER occurrence_count;
|
|
ALTER TABLE bugtracker_items ADD COLUMN rate_window_count INT NOT NULL DEFAULT 0 AFTER rate_window_start;
|
|
ALTER TABLE bugtracker_items ADD COLUMN rate_alerted_at DATETIME NULL AFTER rate_window_count;
|
|
|
|
-- Welche Regel hat dieses Item stummgeschaltet?
|
|
ALTER TABLE bugtracker_items ADD COLUMN ignore_rule_id INT NULL AFTER error_level;
|
|
|
|
ALTER TABLE bugtracker_items ADD KEY ix_bt_error_level (error_level, last_seen_at);
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- 2. Ignore-Regeln
|
|
-- ---------------------------------------------------------------------------
|
|
CREATE TABLE IF NOT EXISTS bugtracker_ignore_rules (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
project_slug VARCHAR(64) NULL, -- NULL = gilt fuer alle Projekte
|
|
match_type ENUM('contains','regex','exception_class') NOT NULL DEFAULT 'contains',
|
|
pattern VARCHAR(255) NOT NULL,
|
|
-- Warum ist das harmlos? Pflichtfeld, damit in sechs Monaten noch
|
|
-- nachvollziehbar ist, weshalb hier weggeschaut wird.
|
|
reason TEXT NOT NULL,
|
|
-- Ab wie vielen Vorkommnissen pro Stunde soll trotzdem alarmiert werden?
|
|
-- NULL = nie alarmieren.
|
|
alert_on_rate INT NULL,
|
|
enabled TINYINT(1) NOT NULL DEFAULT 1,
|
|
match_count BIGINT NOT NULL DEFAULT 0,
|
|
last_match_at DATETIME NULL,
|
|
created_by VARCHAR(100) NOT NULL DEFAULT 'admin',
|
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
KEY ix_ignore_project (project_slug, enabled)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- 3. Metrik-Verlauf
|
|
-- ---------------------------------------------------------------------------
|
|
-- Bisher wurde metrics_json bei jedem Heartbeat ueberschrieben - es gab immer
|
|
-- nur den letzten Moment. Damit laesst sich "Platte laeuft seit drei Tagen
|
|
-- voll" nicht erkennen, sondern nur "Platte ist voll".
|
|
CREATE TABLE IF NOT EXISTS watchdog_metrics (
|
|
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
|
source VARCHAR(100) NOT NULL,
|
|
instance VARCHAR(100) NOT NULL DEFAULT 'default',
|
|
metric_key VARCHAR(64) NOT NULL,
|
|
metric_value DOUBLE NOT NULL,
|
|
recorded_utc DATETIME NOT NULL,
|
|
KEY ix_metric_lookup (source, instance, metric_key, recorded_utc),
|
|
KEY ix_metric_time (recorded_utc)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- 4. Health-Checks per Push
|
|
-- ---------------------------------------------------------------------------
|
|
-- Die Anwendung sendet ihren Gesundheitszustand im Heartbeat mit. Das
|
|
-- Deploymentcenter interpretiert die Namen der Pruefungen nicht - es liest
|
|
-- nur ok und message. Damit muessen auf den Zielmaschinen keine Ports
|
|
-- geoeffnet werden.
|
|
ALTER TABLE watchdog_monitors ADD COLUMN health_json JSON NULL AFTER metrics_json;
|
|
ALTER TABLE watchdog_monitors ADD COLUMN failing_checks VARCHAR(255) NULL AFTER health_json;
|
|
|
|
-- Alarme fuer Kinder unterdruecken, solange der Parent unten ist.
|
|
ALTER TABLE watchdog_monitors ADD COLUMN alert_suppressed_by VARCHAR(100) NULL AFTER failing_checks;
|
|
|
|
-- Aufraeumauftrag fuer den Metrik-Verlauf
|
|
INSERT INTO watchdog_cron_jobs (name, interval_sec, enabled) VALUES
|
|
('metrics_cleanup', 86400, 1)
|
|
ON DUPLICATE KEY UPDATE interval_sec = VALUES(interval_sec);
|
|
|
|
-- ---------------------------------------------------------------------------
|
|
-- 5. Beispielregel, damit der Aufbau sofort erkennbar ist
|
|
-- ---------------------------------------------------------------------------
|
|
-- Bewusst deaktiviert (enabled = 0): sie dient als Vorlage und greift erst,
|
|
-- wenn sie im WebUI bewusst eingeschaltet wird.
|
|
INSERT INTO bugtracker_ignore_rules
|
|
(project_slug, match_type, pattern, reason, alert_on_rate, enabled, created_by)
|
|
SELECT 'polytrader', 'contains', 'Duplicate entry',
|
|
'Marktdaten kommen doppelt aus dem Feed. Der Eintrag wird ohnehin nur einmal benoetigt, die Verarbeitung laeuft normal weiter. Alarm erst bei auffaelliger Haeufung.',
|
|
500, 0, 'system:vorlage'
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM bugtracker_ignore_rules WHERE project_slug = 'polytrader' AND pattern = 'Duplicate entry'
|
|
);
|