So gut wie jeder im IT-Umfeld kennt sie. Meldungen wie:
- „[ERROR] 12.05.2022/11:59 – ErrorHandler kann nicht gefunden werden“
- „[WARN] 11.03.2022/17:12 – Activity nicht gefunden, refresh() nicht möglich“
- „[ERROR] 18.10.2022/13:37 – Directory index forbidden by options directive: /opt/daten/logs/“
- „[INFO] 13.01.2022/04:20 – Could not reach external service“
Sehr aktive Anwendungen können zigtausende solcher Logs pro Stunde generieren. Diese werden dann fein säuberlich im Logstash, Splunk oder wo auch immer abgelegt, damit man diese analysieren kann, Alerts bekommt und fabelhafte Statistiken erstellen kann.
Und dann? Entweder schaut sich das nach einiger Zeit keiner mehr (freiwillig) an oder es wird normal, dass eine Anwendung pro Tag bis zu eine Millionen Logs im Level ERROR und WARN schreibt. An manchen Tagen vielleicht ein paar mehr. Warum die Anzahl von Tag zu Tag mehr oder minder stark variiert, weiß meistens auch keiner so genau. Funktioniert eines Tages tatsächlich mal etwas nicht, darf man den Sprung ins kalte Logmessage-Meer wagen.
Warum sind Logs oft schlecht?
Logs werden während der Softwareentwicklung meist als selbstverständliches Nebenprodukt verstanden. In Anforderungen wird nicht festgelegt, was und in welchem Log-Level geloggt werden soll oder für wen die Logmessage überhaupt gedacht ist. Und wir wissen, was beim Programmieren passiert, wenn es keine klaren Vorgaben gibt… Schließlich hat jeder seine eigene Vorstellung davon was gut und richtig ist.
Dass es keinen Spaß macht, mit dem Ergebnis zu arbeiten, können sich die meisten sicher vorstellen. Gründe dafür sind unter anderem:
- Es wird aus einer Logmessage nicht klar, ob überhaupt Handlungsbedarf besteht.
- Der falsche Log-Level wird genutzt – zum Beispiel ERROR, obwohl die Anwendung weiterhin funktioniert.
- Anweisungen, wie ein Problem zu lösen ist, sind unvollständig oder nicht vorhanden.
- Es fehlen wichtige Informationen, um herauszufinden, was genau das Problem ist.
Wie macht man Logs besser?
Ich appelliere an jeden, wenn er das nächste Mal mit Logs in Berührung kommt, sich folgende Fragen zu stellen:
- Brauchen wir diese Logmessage?
- Für welche Audienz ist diese Logmessage?
- Wenn jemand diesen Log sieht, weiß die Person was zu tun ist?
- Sind alle Informationen vorhanden, um mehr zu erfahren? Zum Beispiel eindeutige IDs von Requests?
Alternativ lässt sich folgende Ausarbeitung als Leitfaden nutzen:
Log-Level ERROR
Im Log-Level ERROR sollten ausschließlich Fehler geloggt werden, auf die sofort oder zeitnah reagiert werden muss.
Zu Loggen | Good Practice | Primäre Audienz |
Nicht (automatisch) korrigierbare Fehler ohne ausreichende Behandlung Beispiele Die Java Virtual Machine meldet einen „OutOfMemoyError“ Zum Betrieb notwendiger Service (z.B. Datenbank, Service) nicht erreichbar Unbehandelte Ausnahme im Programmablauf | Zustände als Error loggen, die dazu führen, dass das System gar nicht oder inhaltlich falsch funktioniert Kritische Performance-Probleme als ERROR ausgeben (Service benötigt deutlich mehr Zeit als geplant) Zusatzinformationen liefern, wie das Problem entstanden ist bzw. behoben werden kann Hier können Stacktraces hilfreich sein, sollten aber mit Vorsicht verwendet werden | Operatoren bzw. Verantwortliche und Monitoring-Systeme |
Aus regulatorischer Sicht: Eine Dienstleistung steht für eine Gruppe von Personen nicht zur Verfügung, was diese Gruppe einschränkt oder nachhaltig an der Ausübung ihrer Arbeit hindert. Der Schaden für das Geschäft ist hoch bis kritisch, die Priorität entsprechend hoch bis sehr hoch. Solche Fehler sollten innerhalb von ein bis zwei Stunden behoben werden.
Log-Level WARN
Am besten loggt man im Log-Level WARN irreguläre Vorkommnisse, die bei unerwünschtem oder häufigem Auftreten Handlungsbedarf nach sich ziehen.
Zu Loggen | Good Practice | Primäre Audienz |
Ein Service erkennt einen Fehler und startet eine automatische Korrektur Beispiele Eine Konfigurationsdatei wurde nicht gefunden, stattdessen wird eine Standardkonfiguration benutzt Unerwartet hohe Latenz beim Aufruf von Datenbanken oder Services Serviceaufruf funktionierte erst im zweiten Anlauf Unkritische aber dennoch fehlerhafte Daten | Im Vorfeld bestimmen, wie lange die Ausführung einer bestimmten Operation dauern darf und bei Überschreitung dieses Wertes eine Warnung ausgeben Falls nötig, Zusatzinformationen liefern, wie das Problem entstanden ist (oder sein kann) bzw. behoben werden kann | Operatoren bzw. Verantwortliche, automatisierte Systeme und Administratoren |
Aus regulatorischer Sicht: Eine Dienstleistung oder Teilbereiche dieser steht für eine einzelne Person oder einige wenige Personen nicht zur Verfügung, was den Hilfesuchenden teilweise oder vollständig an seiner Arbeit hindert. Schaden für das Geschäft niedrig bis mittel. Hier auftretende Probleme sollten beobachtet werden und, falls notwendig, zeitnah behoben werden.
Log-Level INFO
Wichtige, planmäßige Zustandswechsel einer Softwarekomponente.
Zu Loggen | Good Practice | Primäre Audienz |
Konfigurationsdetails Beispiele Start der Vorgänge: Service fährt hoch / runter Hochfahren ist abgeschlossen / Service ist betriebsbereit Erreichen wichtiger (Zwischen)-Stände Start bestimmter Services Aufrufe wichtiger Datenbanken, APIs oder Services Kurz vor dem endgültigen Abschalten | Alle Informationen liefern, die beim Starten, Neustarten oder Herunterfahren eines Services wichtig sind Besonderer Augenmerk auf Operatoren und Administratoren – gegebenenfalls nachfragen, was sich die Zielgruppe für Ausgaben wünscht | Operatoren bzw. Verantwortliche und Administratoren |
Log-Level DEBUG
Im Log-Level DEBUG sollten Informationen ausgegeben werden, die die Fehleranalyse unterstützen. Dabei gilt: Zwischen zwei Debug-Ausgaben sollte ein Kontrollelement (if, for, while, …) liegen. Der Übergang zwischen den Log-Levels DEBUG und TRACE kann fließend sein. Eine klare Abgrenzung besteht jedoch: DEBUG-Nachrichten sind eher für den Betrieb (Fehleranalyse- und behebung) und TRACE-Nachrichten mehr für die Entwicklung gedacht.
Zu Loggen | Best Practice | Primäre Audienz |
Beispiele Eingabewerte Zustandswechsel innerhalb der Software Resultate / Zwischenergebnisse Einstieg in nichttriviale Methoden Einstieg in Entrypoints von Schnittstellen Wichtige Entscheidungspunkte im Programmablauf | Informationen, die tatsächlich zur Fehlerbehebung beitragen Sollte möglichst knapp sein, aber lieber mehr Informationen liefern als zu wenig Zeigen wo und, falls möglich, warum ein Fehler aufgetreten ist (Stacktraces, falls nicht unbedingt hier nötig, lieber im Level TRACE loggen) | Administratoren und Support |
Log-Level TRACE
Für feingranulare Informationen, die dazu dienen, Abläufe zu verfolgen, sollten der LOG-Level TRACE genutzt werden. Dieser dient zur Unterstützung der Entwicklung oder falls DEBUG-Logs bei der Analyse von komplexen Problemen nicht ausreichen.
Zu Loggen | Best Practice | Primäre Audienz |
Ähnlich wie DEBUG (meist ausführlicher) Kann genutzt werden, um Datenflüsse zu verfolgen (Aufruf von Methoden, Verlassen von Methoden) Detaillierte Daten zur Applikationsperformance | StackTraces sind explizit erlaubt Sollten beim Entwickeln unterstützen | Senior Support und Entwickler |