log4j ist ein Framework zum Loggen von Anwendungsmeldungen in Java. Innerhalb vieler Open-Source- und kommerzieller Softwareprodukte hat es sich über die Jahre zu einem De-facto-Standard entwickelt. log4j gilt als Vorreiter für andere Logging-Frameworks, auch in anderen Programmiersprachen.
Geschichte
Das Projekt wurde von Ceki Gülcü 1996 während seiner Arbeit am IBM-Entwicklungslabor in Zürich gegründet. Heute ist es ein Teil des Logging-Projekts der Apache Software Foundation und steht unter der Apache-Lizenz 2.0. Es entstand zu einer Zeit, als es in den Java-Standardbibliotheken noch keine Logging-Mechanismen gab. Heutzutage ist es durch seine Ausgereiftheit und Konfigurierbarkeit für viele Softwareentwickler das Log-System der ersten Wahl.
Die Ausstrahlung der log4j-Konzepte auf andere Programmiersprachen bzw. Plattformen ist so groß, dass es mittlerweile etliche Adaptionen gibt. Einige werden vom Apache Logging Projekt selbst gepflegt. Zum Beispiel:
- log4cxx für C++ mit zu Log4J kompatiblen Konfigurationsdateien
- log4Net für .Net
- log4php für PHP
Viele Varianten werden jedoch außerhalb von Apache Logging entwickelt:
- log4C für C
- log4cplus für C++
- log4cpp für C++
- Log4Qt für Qt
- Log4js für JavaScript
- log4perl für Perl
- log4D für Delphi
- log4sh für Unix-Shells
- log4plsql für Oracle PL/SQL
- log4sas für SAS Institute
- AndroidLoggingLog4J
- Modul logging für Python
Das Apache-Logging-Projekt
Das Apache-Logging-Projekt versucht log4j-ähnliche Systeme für diverse Programmiersprachen zusammenzuführen. Bisher sind das log4j, log4cxx, log4net, log4php und Chainsaw (ein Logdatei-Betrachter und -Analysewerkzeug).
Außerdem werden sogenannte Companions entwickelt, die zusätzliche Funktionalität für Apache log4j bereitstellen.
Funktionsweise
Anstatt auftretende Fehler und Infomeldungen auf der Standardausgabe auszugeben, dient log4j dazu, die Meldungen über sogenannte Logger an das gewählte Loggingsystem weiterzuleiten („Appender“). Neben der Auswahl des Loggingsystems wird gleichzeitig aufgrund der Wichtigkeit („Log-Level“) der Meldung entschieden, ob diese überhaupt weitergeleitet wird. Der Programmierer muss sich beim Erstellen des Programms nur um die Wichtigkeit der Meldungen Gedanken machen. Die Filterung und Art der Ausgabe kann zur Laufzeit konfiguriert werden.
Log4j ist auf möglichst hohe Geschwindigkeit ausgelegt, damit das Loggen die Systemleistung nicht negativ beeinflusst. So dauert die Entscheidung, ob eine Meldung ausgegeben werden muss, auch auf einem veralteten System (AMD Duron mit 800 MHz, JDK 1.3.1) nur 5 Nanosekunden, die Ausgabe selbst – je nachdem welches Layout verwendet wird – zwischen 21 und 37 Mikrosekunden.
Konfiguration
Es gibt drei Arten, log4j zu konfigurieren: mittels einer Properties- oder einer XML-Datei oder im Programmcode. Es wird empfohlen, eine Properties- oder XML-Datei zu verwenden, damit ist die Konfiguration vom Code getrennt, was es ermöglicht, ohne Modifikation oder Neustart der Applikation das Loggen umzukonfigurieren. Somit kann beispielsweise eine Applikation so lange nur mit Log-Level FATAL betrieben werden, bis ein Fehler auftritt. Ab dann wird das Level WARN gesetzt, ohne die Applikation anzuhalten.
Die Konfigurationsdateien definieren mittels der folgenden Komponenten das Verhalten von log4j:
Appender
Diese bestimmen mittels Konfiguration der entsprechenden Appender-Klasse, wohin die Log-Ausgaben geschrieben werden sollen, und mittels Konfiguration des Layouts, wie dorthin geschrieben werden soll. Neben der reinen Nachricht können mittels Muster zusätzlich Wichtigkeit, Datum, Loggername, Klassenname und Methodenname bis hin zur genauen Codezeile ausgegeben werden.
Logger
Ein Logger ist ein Objekt, welches die Logging-Aufgaben einer Klasse übernimmt. Es wird über seinen Namen identifiziert. Üblicherweise wird der Klassenname als Name für den Logger verwendet. Es ist allerdings auch möglich, einen Fantasie-Namen zu verwenden, der von mehreren Klassen benutzt wird. Ein typisches Beispiel könnte so aussehen: Logger log = Logger.getLogger(org.wikipedia.MyClass). Damit kann das Logging-Verhalten einer Klasse gesteuert werden. Da der Logger auch die Paket-Informationen erhält, ist es auch möglich Logging für ganze (Super)-Pakete zu konfigurieren. Die Konfigurationsdatei kann dann eben den Logger-Namen – also z. B. "org.wikipedia.MyClass" – und auch das gewünscht Log-Level enthalten. Es ist wie bereits erwähnt möglich, eine Konfiguration für ein Paket wie "org.wikipedia" festzulegen. Darüber hinaus können entweder allgemein oder auch zu jedem Logger spezifisch ein oder mehrere Appender definiert werden. Somit ist es beispielsweise möglich, fatale Fehler nicht nur in eine Datei zu schreiben, sondern auch gleichzeitig per E-Mail an einen Administrator zu schicken. log4j 2.0 bietet neben diesen klassischen Konfigurationen auch modernere Möglichkeiten an in das Logging-Verhalten einzugreifen. Beispielsweise werden sogenannte Marker unterstützt. Ein weiteres nützliches Merkmal ist der Mapped Diagnostic Context. Dabei wird einer Kontextvariablen ein Wert zugewiesen und in der Konfigurationsdatei kann darauf referenziert werden. Dabei hat jeder Thread seinen eigenen Kontext und kann zusätzliche Informationen wie z. B. die Adresse des Clients bei einer Serveranwendung protokollieren.