diff --git a/monitoring/prometheus/alerts.yml b/monitoring/prometheus/alerts.yml index 3c7d937..9d26d2c 100644 --- a/monitoring/prometheus/alerts.yml +++ b/monitoring/prometheus/alerts.yml @@ -104,8 +104,14 @@ groups: # Der CronJob plant gar nicht mehr (ausgesetzt, geloescht, Cluster-Problem). # 26h Toleranz fuer die taeglichen Laeufe um 03:00/03:15/03:30. + # Fallback auf die Anlagezeit: ein frisch (neu) angelegter CronJob hat noch + # keine last_schedule_time-Serie - ein Ausdruck ueber eine fehlende Serie + # liefert nichts, der Alarm koennte also nie feuern. max by(...) fasst beide + # Metriken zu EINER Serie je CronJob zusammen; ohne das wuerde die nie + # aktualisierte created-Serie nach Ablauf der Frist dauerhaft falsch feuern + # ('or' matcht inkl. __name__, ergibt also eine Vereinigung beider Serien). - alert: BackupNotRunning - expr: time() - kube_cronjob_status_last_schedule_time{cronjob=~"(synapse|authentik|wikijs)-backup"} > 93600 + expr: time() - max by (namespace, cronjob) (kube_cronjob_status_last_schedule_time{cronjob=~"(synapse|authentik|wikijs)-backup"} or kube_cronjob_created{cronjob=~"(synapse|authentik|wikijs)-backup"}) > 93600 labels: severity: critical annotations: @@ -114,9 +120,30 @@ groups: # Die monatliche Restore-Probe laeuft nicht mehr. Eine Sicherung, die nie # zurueckgespielt wurde, ist eine Vermutung — deshalb ist auch das Ausbleiben # der PRUEFUNG ein Alarm, nicht nur ihr Fehlschlag. 40 Tage = Monatsrhythmus + Puffer. + # Bis zum ersten REGULAEREN Lauf gibt es keine last_schedule_time-Serie (ein + # manuell ausgeloester Job setzt sie nicht) - ohne Fallback waere dieser + # Alarm bis dahin blind. Gleiche max-by-Konstruktion wie oben. - alert: RestoreDrillStale - expr: time() - kube_cronjob_status_last_schedule_time{cronjob="restore-drill"} > 3456000 + expr: time() - max by (namespace, cronjob) (kube_cronjob_status_last_schedule_time{cronjob="restore-drill"} or kube_cronjob_created{cronjob="restore-drill"}) > 3456000 labels: severity: warning annotations: summary: "Restore-Probe seit ueber 40 Tagen nicht gelaufen — Wiederherstellbarkeit ist wieder unbewiesen (Verfahren: notfallhandbuch)" + + # Ein Backup-CronJob existiert gar nicht mehr (geloescht, Kustomization + # entfernt, Namespace weg). Bei den Alarmen oben verschwindet dann die + # Serie - und eine verschwundene Serie ist in Prometheus kein Alarm, + # sondern Stille. Genau das war der Fehler, den dieses Regelwerk + # verhindern soll, also ist das Fehlen selbst der Alarm. + # for: 30m puffert kurze Luecken der Metrik-Pipeline ab. + - alert: BackupCronJobMissing + expr: >- + absent(kube_cronjob_info{namespace="matrix", cronjob="synapse-backup"}) + or absent(kube_cronjob_info{namespace="matrix", cronjob="wikijs-backup"}) + or absent(kube_cronjob_info{namespace="authentik", cronjob="authentik-backup"}) + or absent(kube_cronjob_info{namespace="matrix", cronjob="restore-drill"}) + for: 30m + labels: + severity: critical + annotations: + summary: "Ein Backup-/Probe-CronJob fehlt im Cluster — Sicherung oder Wiederherstellungs-Nachweis laeuft nicht mehr"