Zurück zum Blog

Tote Alarme: Warum Monitoring, das nie auslöst, gefährlicher ist als keins

Tote Alarme: Warum Monitoring, das nie auslöst, gefährlicher ist als keins

Datum 15. Juli 2026
Kategorie Monitoring
Lesezeit 9 Minuten

Ein Alarm, der vier Tage zu spät kam

Es begann mit einer harmlosen Warnung: ein Container mit dauerhaft hoher CPU-Last. Ein Blick genügte, um zu sehen, dass die eigentliche Ursache ganz woanders lag – ein anderer Dienst hatte sich seit vier Tagen alle zwölf Sekunden selbst neu gestartet. Zehntausende Neustarts, unbemerkt.

Die unbequeme Frage war nicht „Warum ist das passiert?“, sondern „Warum hat das niemand gemeldet?“ Es gab schließlich einen Alarm für genau diesen Fall: „Container startet zu häufig neu.“ Er hat nie ausgelöst. Nicht weil er falsch eingestellt war, sondern weil er auf eine Kennzahl verwies, die es gar nicht gab. Ein Alarm, der strukturell nie feuern konnte – und der deshalb ein Problem tagelang unsichtbar hielt.

Das war der Anlass, die gesamte Alarmierung einmal gründlich zu prüfen. Das Ergebnis war ernüchternd: Von zwölf Alarmregeln waren sieben defekt. Manche konnten nie auslösen, andere feuerten ununterbrochen. Dieser Beitrag beschreibt die Muster, wie man sie findet – und warum ein toter Alarm schlimmer ist als gar keiner.

Zwei Arten, wie Monitoring versagt

Ausgefallene Überwachung fällt in zwei Kategorien, und beide sind tückisch:

Der falsch-negative Alarm feuert nie, obwohl das Problem eintritt. Er wiegt in falscher Sicherheit: „Es kommt ja keine Warnung, also läuft alles.“

Der falsch-positive Alarm feuert ständig, auch wenn nichts kaputt ist. Er erzieht zum Wegklicken – und wenn dann eine echte Warnung im selben Kanal ankommt, geht sie im Rauschen unter.

Zusammen ergeben sie eine perfide Kombination: Der Kanal, der täglich Fehlalarme schickt, wird ignoriert. Der Alarm, der das echte Problem melden würde, ist tot. So bleibt ein Ausfall vier Tage unsichtbar, obwohl „Monitoring“ auf dem Papier existiert.

Der Alarm, der nie feuern konnte

Der auffälligste Fund betraf die wichtigsten Regeln überhaupt: „Container ist ausgefallen“, „Kritischer Dienst ausgefallen“, „Datenbank ausgefallen“. Alle drei prüften nach demselben Muster, ob eine Statuszahl den Wert Null erreicht.

Der Haken steckt darin, wie der verwendete Metrik-Exporter den Zustand abbildet. Er führt den Status nicht als Wert, sondern als Beschriftung (Label). Läuft ein Container, existiert eine Zeitreihe mit der Beschriftung „running“ und dem Wert 1. Stoppt der Container, verschwindet diese Zeitreihe – und es entsteht eine neue mit der Beschriftung „exited“. Die alte springt nie auf Null, sie hört einfach auf zu existieren.

Kernproblem: Eine Regel der Form „running-Zeitreihe == 0“ kann niemals wahr werden. Ist der Container an, ist der Wert 1. Ist er aus, existiert die Zeitreihe gar nicht mehr – und über etwas, das nicht existiert, lässt sich kein Vergleich mit Null bilden. Der Alarm ist tot.

Der Beleg kam aus der Historie: über sieben Tage hinweg null Treffer, obwohl in genau diesem Zeitraum mehrere Container real gestoppt waren. Der Fix ist, den Vergleich auf die Zeitreihe zu legen, die tatsächlich entsteht, wenn ein Container ausfällt (die „exited“-Variante), und geplante Einmal-Container davon auszunehmen.

Ein zweiter Fehler steckte in denselben Regeln: Sie filterten auf Container-Namen, die es gar nicht gab – Tippfehler und veraltete Namen aus einer früheren Konfiguration. Selbst wenn das Null-Muster funktioniert hätte, wäre der Mailserver nie überwacht gewesen, weil der Filter auf einen nicht existierenden Namen zeigte.

Der Alarm auf der falschen Metrik

Am anderen Ende des Spektrums stand ein Alarm, der zu oft feuerte: „Speicher nahezu erschöpft“ für einen Objektspeicher-Dienst, der angeblich bei 98 % lag. In Wahrheit war er kerngesund.

Die Regel maß die vom Kernel gemeldete Gesamt-Speichernutzung eines Containers – und die enthält den Seiten-Cache. Jeder Dienst, der viel mit Dateien arbeitet (Objektspeicher, Datenbanken), füllt seinen zugewiesenen Speicher zwangsläufig bis fast an die Grenze mit Cache. Das ist kein Mangel, sondern gewünschtes Verhalten: Der Kernel gibt diesen Cache jederzeit wieder frei, wenn er den Platz braucht.

Faustregel: Für Alarme zählt nicht die rohe Speichernutzung, sondern das Working Set – der Speicher abzüglich des rückgewinnbaren Caches. Das ist auch der Wert, den die üblichen Container-Werkzeuge als „Verbrauch“ anzeigen.

Die Gegenprobe machte den Fehler unübersehbar: Über fünf Tage lag die rohe Nutzung im Schnitt bei 80 % mit Spitzen auf 100 %, das Working Set dagegen bei maximal 80 %. Der tatsächlich belegte Speicher (ohne Cache) war stabil bei einem Viertel der Grenze. Es gab nie einen tatsächlichen Speicher-Engpass – aber Dutzende Fehlalarm-Mails pro Tag, weil der Container um die 95-%-Schwelle herum pendelte.

Nebenbei war die Regel doppelt fehleranfällig: Sie teilte durch das Speicherlimit, ohne zu prüfen, ob überhaupt eines gesetzt war. Container ohne Limit erzeugten so eine Division durch Null und meldeten „unendlich Prozent“.

Der Report, der zum Wegklicken erzog

Ein tägliches Health-Skript verschickte jeden Morgen einen Statusbericht – und meldete zuverlässig „drei Fehler“. Alle drei waren Fehlalarme.

  • Zwei betrafen einen Dienst, der bewusst abgeschaltet worden war. Das Skript führte ihn aber noch in seiner Liste der „erwarteten Container“.
  • Der dritte meldete einen VPN-Knoten als „offline“ – und widersprach sich dabei selbst: Direkt darunter standen erfolgreiche Verbindungstests zum selben Knoten. Die Prüfung suchte nach einem Hostnamen, der zu einem ganz anderen (meist ausgeschalteten) Gerät gehörte, während der eigentliche Zielrechner unter einem anderen Namen lief.

Nach der Korrektur meldete der Report sauber „null Fehler“ – und wird dadurch wieder ernst genommen. Genau das ist der Punkt: Ein Report, der jeden Tag „Probleme“ schreit, obwohl keine da sind, trainiert seine Empfänger darauf, ihn zu ignorieren. Der Tag, an dem ein echtes Problem darin steht, ist dann der Tag, an dem niemand hinsieht.

Wenn der Datenlieferant selbst ausfällt

Der heikelste Fund war ein blinder Fleck. Es gab Alarme für „Metrik-Sammler X ist ausgefallen“ – aber nur für drei von fünf Datenquellen. Ausgerechnet der Container, der die Kennzahlen für die Neustart- und Speicher-Alarme liefert, hatte keine eigene Ausfall-Regel.

Die Historie zeigte, dass genau dieser Sammler einmal fast drei Tage am Stück ausgefallen war. In dieser Zeit waren mehrere Alarme still blind – sie beruhen auf seinen Daten, und ohne Daten werten sie nichts aus. Niemand wurde gewarnt, denn der Wächter selbst wurde nicht bewacht.

Prinzip: Überwache die Überwachung. Eine einzige generische Regel („irgendein Scrape-Ziel liefert keine Daten mehr“) über alle Datenquellen ist robuster als eine Handvoll Einzelregeln, die man leicht zu ergänzen vergisst – und sie deckt automatisch auch künftige Datenquellen ab.

Ein verwandter Denkfehler: der Alarm „Das Monitoring-System selbst ist ausgefallen“. Das ist ein Placebo. Ein totes Monitoring-System wertet keine Regeln mehr aus und kann sich nicht selbst melden. Diesen Fall deckt nur ein externer Wächter ab, der von außen anklopft.

Die Methode: gegen echte Daten messen

Der rote Faden durch all diese Fehler ist eine Erkenntnis: Die Syntaxprüfung der Regel-Engine sagt nichts über ihre Tauglichkeit aus. Sie bestätigt nur, dass die Regel formal korrekt ist und ohne Absturz ausgewertet werden kann – nicht, ob die Metrik existiert oder das Richtige misst. Alle sieben defekten Regeln galten als „gesund“.

Die zuverlässige Prüfung ist eine andere. Für jede Regel drei Fragen, jeweils gegen die echte Zeitreihen-Historie:

Frage Was sie aufdeckt
Existiert die abgefragte Metrik überhaupt? Tippfehler im Namen, nie befüllte Metriken, umbenannte Kennzahlen
Wie oft hätte die Regel in den letzten Tagen ausgelöst? Null Treffer trotz echter Vorfälle = toter Alarm. Dauerfeuer = Fehlalarm.
Deckt sich das mit dem, was real passiert ist? Ein bekannter Ausfall, der keine Auslösung erzeugte, entlarvt die Regel.

Diese Messung ist der eigentliche Test. Eine neue Alarmregel wird nicht dadurch vertrauenswürdig, dass die Syntaxprüfung „OK“ sagt, sondern dadurch, dass man ihr gegen die Historie beweist: Sie hätte den letzten echten Vorfall erkannt – und im Normalbetrieb geschwiegen. Wo es geht, ist der Königsweg der scharfe Test: einen unkritischen Dienst kontrolliert stoppen und beobachten, ob der Alarm tatsächlich anschlägt und danach von selbst zurückgeht.

Beim scharfen Test entdeckt: Der verwendete Exporter hat einen Cache-Nachlauf von rund zwei Minuten – in beide Richtungen. Nach einem Stopp dauert es kurz, bis der Ausfall in den Daten steht; nach einem Neustart bleibt der „exited“-Zustand ähnlich lange stehen. Gut zu wissen, denn es bestimmt die reale Reaktionszeit: ungefähr zwei Minuten plus die konfigurierte Wartezeit der Regel.

Alarme müssen ankommen, wo man sie sieht

Die beste Regel nützt nichts, wenn ihre Meldung im Nirwana landet. Ein Beispiel aus derselben Aufräumaktion: Die Zugangsverwaltung (SSO) warf über einen Tag lang einen Konfigurationsfehler – sichtbar ausschließlich in ihrer eigenen Weboberfläche, in keinem zentralen Kanal.

Die Ursache war ein Netzwerk-Detail mit großer Wirkung. Der Hintergrund-Arbeiter des Dienstes, der die Benachrichtigungen verschickt, hing in einem abgeschotteten internen Netz ohne Namensauflösung nach außen. Er konnte weder den Push-Dienst noch das Mail-Relay erreichen. Pikant: Der Hauptprozess erreichte beide problemlos – nur macht er den Versand nicht. Ein Erreichbarkeitstest von der falschen Komponente aus war also grün und führte in die Irre.

Doppelter Boden: Zusätzlich fehlten dem Hintergrund-Arbeiter die Mail-Konfigurationswerte komplett – sie waren nur beim Hauptprozess hinterlegt. Der Mail-Transport war also seit jeher angebunden, konnte aber nie eine einzige Nachricht zustellen. Zwei unabhängige Fehler, die sich gegenseitig verdeckten.

Nach dem Anbinden an die richtigen Netze und dem Ergänzen der Konfiguration lief beides: Push-Benachrichtigung und E-Mail. Zwei Details, die sich bewährt haben:

  • Eine eigene Push-Anwendung pro Quelle (SSO, Update-Melder, Backups), damit sich die Meldungen nicht vermischen und man Prioritäten pro Quelle vergeben kann.
  • „Nur einmal senden“ aktivieren, sonst erzeugt ein einzelnes Ereignis eine Nachricht pro Administrator-Konto – und aus einem Alarm werden drei.
  • Intern zustellen (direkt an den Dienst) statt über den öffentlichen Reverse-Proxy – das spart TLS-Aufwand, umgeht Ratelimits und ist unabhängig von der Außen-Erreichbarkeit.

Der überzeugendste Beweis war am Ende kein Test, sondern ein echtes Ereignis, das während der Einrichtung von selbst durchlief und sauber als Push-Nachricht ankam.

Lessons Learned

Die wichtigsten Erkenntnisse:
  • Ein Alarm, der nie feuern kann, ist schlimmer als kein Alarm – er erzeugt falsche Sicherheit.
  • Die Syntaxprüfung bestätigt nur die Form, nicht die Funktion. Regeln müssen gegen echte Daten gemessen werden.
  • Für Speicher-Alarme zählt das Working Set, nicht die rohe Nutzung – sonst schlägt der Seiten-Cache jeden Dateidienst in den roten Bereich.
  • Statuszustände als Label statt als Wert sind eine klassische Falle: „== 0“ trifft eine Zeitreihe, die beim Ausfall gar nicht mehr existiert.
  • Überwache die Überwachung. Der Datenlieferant braucht eine eigene Ausfall-Regel, sonst werden ganze Alarmgruppen still blind.
  • Alarme müssen dort ankommen, wo man hinsieht. Prüfe den Zustellweg von der Komponente aus, die tatsächlich versendet – nicht von der bequemsten.
  • Ein Report, der täglich grundlos „Problem“ meldet, erzieht zum Wegklicken und verdeckt so den echten Vorfall.

Von zwölf Regeln waren sieben defekt. Nach der Aufräumaktion feuert keine mehr grundlos, und keine bleibt bei einem echten Ausfall stumm. Das Beruhigende daran: Man muss dafür nichts Neues bauen. Es reicht, jede vorhandene Regel einmal ehrlich gegen die Realität zu halten.