Besser zentral: Professionelles Logging

Know-how  –  1 Kommentare
Anzeige
Besser zentral: Professionelles Logging

Logging hilft über alle Phasen von der Entwicklung bis in den Betrieb bei der Identifikation und Rückverfolgung von Fehlern; und auch für das Monitoring lässt es sich verwenden. Noch besser ist ein zentrales Logging: Es bringt Daten- und Kontrollflüsse über mehrere Schichten, Knoten und Systemkomponenten hinweg in einen Zusammenhang und eine homogene Struktur. Damit steht es wider die üblichen verstreuten Log-Dateien und für mehr Professionalität.

Logging beschreibt laut deutscher Wikipedia "generell das (automatische) Speichern von Prozessen oder Datenänderungen [...] in Logdateien". Diese eng gefasste Definition ist exemplarisch und verrät viel über dieses stiefmütterlich behandelte Thema.

Dabei schauen sich Entwickler täglich Logs an, und es ist gute Praxis, Anwendungssysteme von der Implementierung bis in den Abnahmetest über Logs kritisch zu betrachten. Mit der Übertragung der Verantwortung an den Produktivbetrieb passiert oft etwas Bemerkenswertes. Plötzlich werden Logs nicht mehr ohne Verdachtsmoment geprüft. Operatoren wissen möglicherweise noch nicht einmal, ob Logs überhaupt geschrieben wurden und wo sie liegen. Sofern die Operatoren nicht Teil eines DevOps-Teams waren, haben sie vermutlich nicht von den Entwicklern gelernt, was in den Log-Dateien steht und wie sie zu lesen sind. Die Entwickler wiederum haben womöglich nie geprüft, ob in den Logs auch die benötigten Informationen zu finden sind.

Melden Nutzer Probleme im Produktionssystem, sind Logs häufig das einzige Mittel, um Fehler nachzuvollziehen und ihren Ursachen auf den Grund zu gehen. Am Anfang der Analyse steht der Zugriff auf die Logs. Falls der Systemadministrator mit ihnen jedoch nicht vertraut ist, kann er seiner Verantwortung nicht nachkommen. Er ist gezwungen, die Entwickler zu kontaktieren, die eigentlich Second- oder Third-Level-Support leisten sollen. Die Entwickler haben (hoffentlich) keinen Zugriff auf die Produktionssysteme. Aus diesem Grund muss der Administrator sich führen lassen und Log-Datei für Log-Datei einsammeln. Schließlich stellt er noch die Frage, wie er die gesammelten Dateien verschlüsselt an die Entwickler senden kann.

Liegen die Dateien endlich lokal vor, kann die Analyse beginnen. Zum Data Mining in den Log-Dateien gehört, ihre Einträge in einen zeitlichen Zusammenhang zu bringen. In der Regel interessiert sich der Leser der Logs nicht für alle Einträge, sondern nur für bestimmte, zum Beispiel die einer Komponente, eines Nutzers oder eines Request. Er muss diese Einträge herausarbeiten, wobei das Finden, Korrelieren und Filtern schwierig ist, wenn Log-Einträge aus einfachen Textdateien mit Kommandozeilen-Werkzeugen gelesen werden.

Als Herausforderung kommt hinzu, dass viele Anwendungssysteme eine Mehrschichtenarchitektur aufweisen und jede Schicht dabei ein eigenes Log erstellt. Zur Nachverfolgung des Daten- und Kontrollflusses durch die Schichten sind Einträge aus verschiedenen Log-Dateien zunächst in die richtige zeitliche Abfolge zu bringen. Ein typisches Beispiel sind hier die Anfragen von Clients, deren Abarbeitung auf dem Server weitergeht, sodass sich ein Request-Response-Zyklus in den Logs von Client und Server niederschlägt.

Gängige Log-Bibliotheken lassen die Log-Einträge aller Komponenten üblicherweise in einer Log-Datei pro Anwendungsinstanz auflaufen. Bei horizontaler Skalierung des Anwendungssystems über Lastverteilung multipliziert sich so der Aufwand zur Bereitstellung und Analyse mit der Anzahl der Instanzen.

Zentrales Logging

Abhilfe für diese Probleme vermag ein zentrales Logging zu schaffen, das durchgängig alle Teile des Anwendungssystems oder – besser noch – die gesamte Anwendungslandschaft nutzen. Die Grundidee ist einfach: Alle Logs fließen an einer Stelle zusammen, werden dort so lange wie nötig gespeichert und lassen sich von den Administratoren, Entwicklern und gegebenenfalls weiteren Beteiligten gleichzeitig strukturiert analysieren. Damit das möglich ist, muss eine zentrale Logging-Software folgende Herausforderungen bewältigen:

  • Zusammenstellung: Technische und fachliche Ereignisse werden aus allen Teilen des Anwendungssystems gesammelt, mit Lokalisierungsinformationen angereichert, in ein einheitliches Format gebracht und quasi sofort bereitgestellt. Das "Wegschreiben" der Logs darf nicht den regulären Anwendungsprozess blockieren und muss daher asynchron geschehen.
  • Transport: Log-Ereignisse müssen sich auch dann zuverlässig, sicher, zeitnah und ohne Beeinträchtigung des eigentlichen Systems übertragen lassen, wenn sie in hoher Frequenz und mit vielen Daten erzeugt werden.
  • Persistierung: Log-Daten sollen in der Regel sofort les- und suchbar sein. Sie können über die Zeit zu beachtlichen Volumina auflaufen, veralten jedoch nach einiger Zeit und sind dann zu löschen. Hinzu kommt, dass sich das Format von Log-Einträgen mit der Entwicklung der Anwendung ändern kann (z. B. neue Felder).
  • Analyse: Neben der klassischen Fehleranalyse lassen sich Logs auch zur Analyse weiterer Aspekte verwenden (bspw. Service-Nutzung und Lastaufkommen). Abhängig davon schauen die Leser der Logs auf Einträge der Vergangenheit, der Gegenwart oder eine Kombination daraus. Eine grafische Benutzeroberfläche stellt Operatoren und Entwicklern Werkzeuge zum Suchen, Filtern und Korrelieren bereit.
  • Alarmierung: Auf Basis definierbarer Regeln sollte ein zentrales Logging-System automatisch reagieren und zum Beispiel Benachrichtigungen an den Administrator versenden. Alarmereignisse lassen sich ergänzend oder integriert in einem Monitoring-System wie Nagios nutzen.

Zentrale Logging-Software lässt sich vor diesem Hintergrund in zwei Kategorien untergliedern: Cloud-basiert sowie selbstverwaltet. Die letzteren Techniken lassen sich weiter unterteilen. Hier existieren einige wenige integrierte Produkte, zum Beispiel Logfaces oder der ELK-Stack (Elasticsearch, Logstash, Kibana) von Elasticsearch.

Daneben gibt es Werkzeuge, die ein oder mehrere dieser Aufgabengebiete abdecken. Sie lassen sich zu vollwertigen zentralen Logging-Techniken kombinieren. Da sich viele Unternehmen strategisch für oder gegen die Nutzung von Cloud-Diensten aussprechen, erleichtert das die Auswahl einer geeigneten Software.

Für Anwendungssysteme in der (öffentlichen) Cloud ist die Geschichte schnell erzählt. Ein Logging auf die lokale Festplatte eines unbekannten Rechners ist wenig hilfreich. Das Bereitstellen eines eigenen Log-Servers in der Cloud widerspricht der Architekturentscheidung des eigentlichen Systems. Daher kann eine sinnige Entscheidung in einem solchen Szenario nur zugunsten einer Cloud-Logging-Technik fallen. Prominente Vertreter sind hier loggly, Papertrail oder logentries.

Für individuell entwickelte, unternehmenskritische Anwendungssysteme stellt sich die Lage oft anders dar. Sie werden überwiegend über eine eigene technische Infrastruktur betrieben. In einem solchen Umfeld bietet es sich an, eine wartungsarme selbstverwaltete Software einzusetzen. Es sei erwähnt, dass auch für diese Anwendungssysteme die Einbindung von Cloud-Techniken möglich ist. Die Lizenzkosten und die Abhängigkeit der Anwendung externer Services ist jedoch aufmerksam zu verfolgen.

Zur Verdeutlichung, wie selbst verwaltetes zentrales Logging in der Praxis eingesetzt und angebunden wird, betrachtet dieser Artikel beispielhaft das kommerzielle Produkt Logfaces. Es ist einfach zu konfigurieren, zu integrieren und schlicht aufgebaut. Der Hersteller dieses Tools bietet eine zeitlich begrenzte Probeversion ohne Registrierung an, die sich zum Ausprobieren der hier beschriebenen Konzepte eignet. Wem der Umfang von Logfaces genügt, kann für den Produktiveinsatz Lizenzen pro Installation oder pro Standort beziehen. Wer mehr will als einfaches Logging operativer Anwendungsdaten oder eine Open-Source-Software sucht, findet möglicherweise mit dem ELK-Stack eine passendes Angebot.

Logfaces besteht aus drei Komponenten: Ein dedizierter Log-Server nimmt die Log-Ereignisse von den Anwendungskomponenten entgegen, eine Datenbank persistiert sie, und ein grafischer Client unterstützt beim Lesen, Suchen und Analysieren der Log-Einträge. Die folgende Abbildung zeigt anhand einer fiktiven 3-Schichten-Anwendung mit Lastverteilung, wie sich ein zentrales Logging implementieren ließe.

Alle Komponenten einer verteilten Anwendung übertragen ihre Logs an eine zentrale Stelle (Abb. 1).
Alle Komponenten einer verteilten Anwendung übertragen ihre Logs an eine zentrale Stelle (Abb. 1).

Im Beispielszenario greifen die Anwendungsclients über einen Load Balancer auf die Backend-Server zu. Hier liegt der rechenaufwendige Anwendungskern. Die Datenhaltung ist einfach, sodass die Backend-Server auf eine gemeinsame Datenbank zugreifen können. Darüber hinaus sind die Server zustandslos, und der Load Balancer kann pro Anfrage entscheiden, an welchen Backend-Server er einen Client verweist.

Im gelben Rechteck rechts unten ist der Log-Server abgebildet. Die grünen Linien markieren den Fluss der Log-Einträge. Sowohl die Client- als auch die Server-Komponenten der Anwendung senden ihre Log-Einträge an den Log-Server. In der Regel bildet die eingesetzte Log-Bibliothek die Schnittstelle zwischen den Anwendungsteilen und dem Log-Server. Meist findet sich hier log4j oder ein anderes Mitglied der log4x-Familie (z. B. log4net, slf4j), Logback oder NLog. Für die gängigsten Bibliotheken bietet Logfaces Ausgabe-Plug-ins an. Bei log4x werden diese in Form eines sogenannten Appender bereitgestellt. Die Plug-ins stellen jeweils sicher, dass die Ereignisse gepuffert und asynchron übertragen werden. Bricht die Verbindung zum Log-Server ab, versucht der Appender die erneute Übermittlung der Ereignisse und schreibt sie gegebenenfalls in eine lokale Datei.

Neben diesen Bibliotheken existiert eine Schnittstelle auf Basis des aus Unix bekannten Syslog-Protokolls. Sie lässt sich im Beispielszenario zur Anbindung der Datenbank sowie des Load Balancer verwenden. Im Ergebnis liegen alle Log-Einträge chronologisch sortiert an einem Ort: der Datenbank des Log-Servers.

Beispiel

Wie die konkrete Anbindung funktioniert, ist im Folgenden auf Basis eines einfachen Beispiels zu sehen: Auf einen FTP-Server greifen mehrere FTP-Clients zu. Die Zugriffe sollen so geloggt werden, dass die Nutzeranfragen durchgängig nachvollziehbar sind. Das Beispiel verwendet den Apache FTP Server und den Netzwerk-Browser JFtp auf der Client-Seite. Für das Logging arbeiten die beiden quelloffenen Anwendungen mit log4j.

Um die Zusammenstellung der Logs und ihren Transport zum Log-Server kümmert sich ein passender log4j-Appender (AsyncSocketAppender). Dieser wird von der Herstellerseite heruntergeladen und im Klassenpfad der Anwendung bekannt gemacht. Damit log4j den Appender verwenden kann, wird es über eine ebenfalls im Klassenpfad liegende log4j-Konfiguration so eingerichtet wie im folgenden Code-Beispiel im Properties-Stil abgebildet.

01: log4j.rootLogger=DEBUG, LFS
02: log4j.appender.LFS = com.moonlit.logfaces.appenders.AsyncSocketAppender
03: log4j.appender.LFS.remoteHost = logserver-demo.accso.de
04: log4j.appender.LFS.port = 55200
05: log4j.appender.LFS.reconnectionDelay = 5000
06: log4j.appender.LFS.offerTimeout = 0
07: log4j.appender.LFS.queueSize = 200
08: log4j.appender.LFS.threshold = ALL
09: log4j.appender.LFS.locationInfo = true
10: log4j.appender.LFS.backupFile = c:/logs/ftpd.log.xml
11: log4j.appender.LFS.application = apache-ftpserver-dev

Zeile 1 stellt den in Zeile 2 referenzierten Logfaces-Appender (LFS) als Standardausgabe von log4j ein. Sie definiert außerdem, dass Log-Ereignisse ab Level DEBUG über diese Ausgabe protokolliert werden sollen. Die Zeilen 3 bis 7 bestimmen die Verbindungsparameter. Sie geben an, wohin die Ereignisse übermittelt werden (logserver-demo.accso.de:55200), wie lange nach einem Verbindungsabbruch bis zum nächsten Verbindungsversuch gewartet wird (5000 ms), ob und wie lange bei einem beständig langsamen Log-Server auf diesen gewartet werden soll (0 ms) und wie viele Log-Einträge in der lokalen Warteschlange auflaufen können (200 Stück). Zeile 8 definiert noch auf Appender-Ebene das Log-Level, unterhalb dessen Ereignisse verworfen und oberhalb dessen sie übertragen werden; im Beispiel werden alle übertragen.

log4j spickt einige Log-Ereignisse mit Lokalisierungsinformationen wie Klassen- und Methodennamen sowie Zeilennummern. So stellen insbesondere Log-Ereignisse zu Exceptions über Stack Traces einen genauen Bezug zu den beteiligten Quelltextstellen her. Die Definition locationInfo=true sorgt dafür, dass der Appender die Informationen überträgt. Falls der Log-Server nicht erreichbar ist, werden die Ereignisse in eine lokale Datei im log4j-XML-Format geschrieben. Aus dieser Rückfallebene lassen sie sich später bei Bedarf im Log-Server importieren. Abschließend ordnet die Konfiguration den Appender einer Anwendung zu (apache-ftpserver-dev). Er wird den Lesern bei der Analyse der Log-Dateien erneut begegnen.

Inhaltlich besteht ein Anwendungslog-Eintrag klassisch aus den Attributen Zeitstempel, Name des Loggers, Thread-Kennung, Log-Level, einer Nachricht und gegebenenfalls einem Stack Trace. Die Inhalte stellt bereits log4j bereit. Der Logfaces-Appender ergänzt, zu welcher Anwendung (siehe Konfiguration) und auf welcher Maschine ein Log-Ereignis erzeugt wurde.

Damit es im Beispiel eindrucksvoll knallt, kann man etwa den Server-Code des STOR-Befehls manipulieren (vgl. Abb. 2). Die Log-Ausgabe mit anhängiger NullPointerException ist gleich weiter unten zu sehen (vgl. Abb. 6).

Das Beispiel lässt es krachen: Error-Log-Ausgabe mit angehängter NullPointerException (Abb. 2)
Das Beispiel lässt es krachen: Error-Log-Ausgabe mit angehängter NullPointerException (Abb. 2)

Der Logfaces-Server nimmt die Einträge entgegen und schreibt sie wahlweise in eine beliebige relationale Datenbank oder eine MongoDB als dokumentenorientierte NoSQL-Datenbank. In der Praxis ist die Verwendung einer dokumentenorientierten Persistierung von Log-Einträgen aus folgenden Gründen ratsam: Zum einen lassen sich Logs um weitere Datenfelder ergänzen (siehe unten), wodurch sich das Datenbankschema dynamisch ändert. Zum anderen sind oft nur einige Datenfelder eines Log-Ereignisses gefüllt, sodass eine schemalose Speicherung ökonomischer ist. Für den Start empfiehlt sich die Installation von Log-Server und -Datenbank auf derselben Maschine. Bei Logfaces findet der Server die MongoDB-Installation automatisch.

Zum Einrichten stellt der Logfaces-Server eine Weboberfläche bereit. Nach dem Hochladen der Lizenzdatei funktioniert der Server dann. Die Voreinstellungen sind weitgehend sinnvoll getroffen. Insbesondere ist der Empfang von Log-Ereignissen über log4j-Appender bereits standardmäßig aktiviert (vgl. Abb. 3).

Log-Einträge lassen sich aus Quellen unterschiedlicher Art empfangen (Abb. 3).
Log-Einträge lassen sich aus Quellen unterschiedlicher Art empfangen (Abb. 3).

Abhängig von verfügbarem Speicherplatz und betrieblichen Vorgaben sollte noch ein Blick auf die Verwahrdauer (Retention) der persistierten Einträge geworfen werden (vgl. Abb. 4).

Logging benötigt temporäre Persistenz - eine Datenbank im Hintergrund hilft dabei (Abb. 4).
Logging benötigt temporäre Persistenz - eine Datenbank im Hintergrund hilft dabei (Abb. 4).

In Szenarien, bei denen Server viele Clients (quasi-)parallel bedienen, ist der Einsatz eines Nested oder Mapped Diagnostic Context (NDC, MDC) zu empfehlen, um den Log-Einträgen kontextabhängige Zusatzinformationen wie eine Session-ID sowie eine Nutzer- oder Client-Kennung mitzugeben (siehe Kasten).

Diagnostic Context

Nahezu alle Log-Bibliotheken unterstützen zwei Arten diagnostischer Kontexte: Nested Diagnostic Contexts (NDC) sowie Mapped Diagnostic Contexts (MDC). Sie erlauben es der Anwendung, spezifische Informationen zum Ausführungskontext zu sammeln, wie Session-IDs, Übergabeparameter oder Zwischenergebnisse (vgl. hier). Diese Informationen bleiben innerhalb eines Thread erhalten und werden beim Erzeugen von Log-Ereignissen automatisch beigefügt.

Ein NDC implementiert einen Stack. Typischerweise, werden ihm beim Abstieg in der Aufrufhierarchie der Anwendung Daten hinzugefügt, die bei der Rückkehr wieder entfernt werden. Ein MDC ist eine Map mit Schlüssel-Wert-Paaren. Er nimmt eine Menge "benannter" Werte auf.

Auch für das Beispiel lässt sich von der Annahme ausgehen, dass der FTP-Server mehrere Clients zeitgleich bedient und die Übermittlung einiger benutzerdefinierter Felder bei der späteren Analyse hilfreich sein wird (vgl. Abb. 5).

Über definierbare Felder kann man anwendungsspezifische Kontextinformation bekannt machen (Abb. 5).
Über definierbare Felder kann man anwendungsspezifische Kontextinformation bekannt machen (Abb. 5).

Zur Autorisierung der an den Logs interessierten Nutzer lässt sich noch eine LDAP-Anbindung konfigurieren. Bei der Anmeldung mit dem Logfaces-Client wird diese dann berücksichtigt. Abschließend können Anwender noch Benachrichtigungen konfigurieren. Hierüber kann der Log-Server die Operatoren alarmieren oder Reports an Interessierte ausliefern.

Beispiel, Teil 2

Der Logfaces-Client wird von der Website des Herstellers heruntergeladen. Er baut auf Eclipse RCP auf. Beim ersten Start interessiert er sich für die URL und den Port des Log-Servers. Beim Einsatz von LDAP fragt er noch nach Nutzername und Kennwort.

Einmal gestartet, wählt der Nutzer zunächst die passende Sicht auf die Daten. Abbildung 6 zeigt, wie mehrere Anwendungen (rechts oben) ausgewählt wurden, um deren Log-Einträge in einer Ansicht anzeigen zu lassen (Mitte). Dort taucht auch der apache-ftpserver-dev mit dem zuvor konfigurierten log4j auf.

In Farbe und aufs Wesentliche reduziert, so werden Zusammenhänge und Details verständlich (Abb. 6).
In Farbe und aufs Wesentliche reduziert, so werden Zusammenhänge und Details verständlich (Abb. 6).

Die Liste enthält pro Zeile einen Log-Eintrag. Sie gibt dem Nutzer vor allem einen zeitlichen Überblick. Er kann definieren, welche Spalten er sehen möchte sowie in welcher Reihenfolge und Breite diese dargestellt werden sollen. In der Abbildung sind zwischen zahlreichen Log-Ereignissen auf Info-Level auch zwei Warnungen sowie ein Error-Eintrag zu sehen. Letzterer ist ausgewählt, und so wird der Stack Trace in der Detail-Ansicht "Exception" (Mitte unten) angezeigt. Über die Ansicht "Event Details" rechts davon kann sich der Anwender weitere Details anzeigen lassen, für die die Übersichtsliste keinen Platz bietet.

Allein die gemeinsame Sicht auf zeitlich zusammenhängende Log-Einträge der Clients und des Servers vereinfacht das Auffinden und Lesen schon wesentlich. Die farbliche Kategorisierung hilft beim Auffinden wichtiger Ereignisse. Insbesondere ist die einheitliche Auflistung der Einträge deutlich übersichtlicher als die homogenen Textmassen herkömmlicher Log-Dateien (vgl. Abb. 7).

In herkömmlichen Log-Dateien sind wichtige Informationen nicht offensichtlich (Abb. 7).
In herkömmlichen Log-Dateien sind wichtige Informationen nicht offensichtlich (Abb. 7).

Auf Grundlage der angezeigten Einträge kann der Nutzer eine Reihe weiterer praktischer Filtermöglichkeiten nutzen (vgl. Abb. 8). Im Beispiel könnte interessieren, was im Zeitfenster plusminus eine Minute um das Ereignis passiert ist. Dabei könnten alle Ereignisse interessant sein oder etwa bloß jene, die laut dem MDC-Feld userName denselben Nutzer betreffen.

Mit Textdateien schier undenkbar: Filtern um ein Ereignis herum (Abb. 8)
Mit Textdateien schier undenkbar: Filtern um ein Ereignis herum (Abb. 8)

Auf diese Weise lassen sich zeitlich und kontextuell zusammengehörige Einträge schnell und einfach herausarbeiten. Neben den gezeigten Analysewerkzeugen existieren noch weitere zur Suche, Filterung und grafischen Auswertung.

Es ist möglich und sinnvoll, ein Anwendungslogging zu einem zentralen Logging auszubauen. Nicht nur sind Logs auf diese Weise ohne nennenswerten Aufwand zu jeder Phase im Lebenszyklus der Anwendung zugänglich, sie sind auch einfach lesbar. Als gemeinsames Werkzeug von Betrieb und Entwicklung baut das zentrale Logging eine Brücke, die zu einer frühen gemeinsamen Abstimmung einlädt. Dennoch kann das zentrale Logging lediglich ein Vehikel sein. Was zählt, sind die passenden Inhalte.

Vor diesem Hintergrund stellt sich die eher grundsätzliche Frage: Wo sollte man was loggen? Die Antwort auf diese Frage ist natürlich abhängig von der Anwendung. Dennoch lassen sich einige Best Practices aufzählen:

  • Wer erwartet was: Einen guten Einstieg bereitet das Erstellen einer kurzen Liste von Stakeholdern, die einen Nutzen aus den Logs ziehen wollen. Zu ihnen gehören meistens Operatoren/Systemadministratoren, gegebenenfalls aber auch Auditoren oder Analysten z. B. aus dem Marketing. Zu jeder Rolle sollte deutlich werden, welche Erkenntnisse sie aus den aufgezeichneten Daten gewinnen möchte. Beispiele sind fachliche Protokollierungen, wer wann was mit welchen Daten gemacht hat, eine Heartbeat-Ausgabe für das Monitoring oder wann, wie oft und wo auf der Welt welche Produktseiten angesehen werden.
  • Abbildung der Struktur: Jede Dimension physischer, logischer und dynamischer Aufteilung sollte sich in jedem Log-Eintrag widerspiegeln. Zur physischen Aufteilung zählt, um welches System es sich handelt (z. B. Backend, Datenbank) und auf welcher Maschine es läuft. Hinsichtlich der logischen Aufteilung sollten Verweise auf die Komponente sowie die Klasse innerhalb eines Systems existieren. Dynamische Aufteilungen ergeben sich bei parallel arbeitenden Systemen (etwa Mehrnutzersysteme und parallele Berechnungen). Diese Aufteilungen bestehen nur zur Laufzeit und machen das Lesen von Log-Einträgen oft besonders kniffelig. Aus dem Ausführungskontext sollten die Log-Einträge daher eine möglichst durchgängige Information anzeigen, die den Kontrollfluss identifiziert und ihn nachvollziehbar macht. Bewährte Beispiele sind hier Session- und User-IDs oder Nutzer-Pseudonyme, Request-IDs sowie die eindeutige Nummer eines Worker aus einem Pool. Das Mittel der Wahl sind hier diagnostische Kontexte (siehe oben).
  • DRY (Don't repeat yourself): Was für den Code der Anwendung gilt, trifft auch für das Logging zu. Der Code zum Sammeln von Strukturinformationen für die Log-Einträge und zum Schreiben der Logs verunreinigt den eigentlichen Code, der eine fachliche oder technische Aufgabe erledigt. Daher sollte ein Großteil des Logging-Codes nach Möglichkeit zentral an einer Stelle platziert werden. Abhängig von der konkreten Architektur der Anwendung kann das in Aspekten, selbst definierten Annotationen, Interzeptoren oder in einer Oberklasse geschehen.
  • Einheitlichkeit: Die Entwickler sollten sich darüber verständigt haben, wann, was und mit welchem Level protokolliert wird. Nur für gleichartige Belange lässt sich der Code für das Logging nach dem DRY-Prinzip zentralisieren. An vielen Stellen müssen Log-Einträge so erzeugt werden, dass sie eine individuelle Information, Warnung oder ein Zwischenergebnis wiedergeben sollen. Damit Logs über alle Teile des Anwendungssystems hinweg konsistent bleiben, lohnt sich ein Logging-Konzept. In der Regel braucht es dazu nicht mehr als eine Handvoll einfacher Regeln. Eine könnte beispielsweise lauten: "An jedem Zweig im Programm (bei Fallunterscheidungen und vor Schleifen) wird auf Level DEBUG geloggt, welcher Pfad durchlaufen wird."
  • Werkzeug der Wahl: Das Lesen und Analysieren zentraler Logs auch zusammen mit den Kollegen aus dem Betrieb sollte früh zur Gewohnheit werden. Zentrales Logging sollte sich bereits zur Entwicklungszeit zum Debugging und der Fehlerverfolgung etablieren. Auf diese Weise fallen fehlende Informationen auf und das Logging lässt sich sukzessive verbessern. Die Entwickler lernen typische Fehlermuster ihrer Anwendung kennen. Diese Erkenntnisse können sie direkt oder in einem Betriebshandbuch an die Administratoren weitergeben. Diese Operatoren erhalten ihrerseits einen echten Mehrwert, wenn ihre Anforderungen berücksichtigt werden und ihnen das zentrale Logging die für das Monitoring relevanten Daten passend serviert.

Logging ist so wichtig, dass es in keiner Anwendung fehlt. Beim professionellen Logging haben sich Entwickler und Administratoren vor der Inbetriebnahme Gedanken darüber gemacht, was in ihren Logs steht und was mit ihnen geschieht. Sie wissen, wo Logs gespeichert, wie viele beziehungsweise wie lange sie gespeichert sind und ob sie sicher übermittelt werden. Außerdem ist geklärt, wer sie sichten darf, wann Benachrichtigungen versandt werden und wie die zu protokollierenden Inhalte strukturiert sind.

Techniken für zentrales Logging forcieren die frühe Beantwortung dieser Fragen. Mehr noch, sie bewahren die Beteiligten davor, fortwährend Log-Dateien unter Stress und schwierigen Randbedingungen wie fehlenden Zugangsberechtigungen von verschiedenen Maschinen zusammenklauben zu müssen.

Während für Cloud-Anwendungen nur Cloud-basierte Logging-Angebote infrage kommen, lassen sich in der eigenen IT-Infrastruktur selbstverwaltete einsetzen. Sie werden wahlweise aus mehreren Komponenten komponiert oder als integriertes Produkt bezogen. Die Einbindung in die neue oder bestehende Anwendung erfolgt idealerweise über die ohnehin eingesetzte Log-Bibliothek durch einfache Konfiguration.

Eine vollständige Software enthält dabei stets grafische Analysewerkzeuge, mit denen sich Vorgänge einfacher verstehen und Muster besser erkennen lassen als mit herkömmlichen Textdateien. Die grafischen Oberflächen schaffen eine gemeinsame Sicht auf die Log-Ereignisse der Quellen und stellen Details nur soweit benötigt dar. (ane)

Markus L. Dechert
ist seit August 2013 als Managing Consultant bei der Accso – Accelerated Solutions GmbH – und beschäftigt sich mit agilem Projektmanagement, betrieblichen Themen sowie Java- und .NET-Entwicklung.

Anzeige