Bei log4j handelt es sich um eine populäre JAVA Logging-API. Eine ihrer herausragenden Eigenschaften ist die Vererbung bei Loggern. Die Benutzung von Logger Hierarchien erlaubt eine feingranulare Kontrolle über die einzelnen Logausgaben. Hierdurch ist eine Reduzierung der Menge der Logausgaben bei gleichzeitiger Minimierung der Kosten für das Logging möglich. Der Verwaltungsaufwand ist dabei sehr gering. Sind die Log-Anweisungen einmal im Code, können sie einfach durch Konfigurationsdateien aktiviert resp. deaktiviert werden.
Die aktuelle Version, einschliesslich dem vollständigen Quellcode und der Dokumentation kann via URL kann von http://logging.apache.org/log4j frei herunter geladen werden. Um log4j zu installieren, genügt es, das herunter geladene und ausgepackte Java-Archiv in den Klassenpfad aufzunehmen.
log4j kennt drei Hauptkomponenten. Dies sind Loggers, Layouts und Appenders.
Loggers sind benannte Entitäten. Die Gross- und Kleinschreibung der Buchstaben wird berücksichtigt (Case sensitive). Die Namen folgen einer hierarchischen Namenskonvention. Die Geerationen oder Hierarchieebenen werden mit einem Punkt getrennt. Beispiel "org.apache" ist eine Obermenge von org.apache.log4j".
Oder anders ausgedrückt "org" ist der Vater von "org.apache".
Zu oberst einer Hierarchie ist immer der Root-Logger. Der Root-.Logger existiert immer und hat keinen Namen.
Eine Referenz auf die Instanz des Root-Loggers kann mit der statischen Funktion
Logger.getRootLooger() geholt werden.
Alle anderen Logger-Instanzen werden mit dem Namen mittels der statischen Funktion Logger.getLogger() geholt.
Nachfolgend eine Kurzübersicht der Klasse Logger:
package org.apache.log4j;
public class Logger {
// Creation & retrieval methods:
public static Logger getRootLogger();
public static Logger getLogger(String name);
// printing methods:
public void debug(Object message);
public void info(Object message);
public void warn(Object message);
public void error(Object message);
public void fatal(Object message);
// generic printing method:
public void log(Level l, Object message);
}
Einem Logger kann einen so genannter Level zugeordnet werden. Folgende Standard Levels sind verfügbare: DEBUG, INFO, WARN, ERROR und FATAL.
Alle Levels haben eine Rangordnung. Es gilt: DEBUG < INFO < WARN < ERROR < FATAL.
Dem Root-Logger ist immer einen Level zugeordnet. Wenn Kinder keinen Level zugeordnet haben, erben Sie den Level des direkten Vorfahren. Die Vererbung erfolgt vom Root-Logger aus. D. h. zugeordnete Levels eines direkten Vorgängers in der Hierarchie haben Priorität.
Das Loggen von Meldungen erfolgt über so genannte "Printing-Methods". Folgende Methoden sind verfügbar: debug, info, warn, error, fatal und log.
Beispiel:
// Logger-Instanz holen
Logger logger = Logger.getLogger("org.apache");
// Wir setzen den Level auf INFO.
// Dies wird in der Regel nie im Code gemacht sondern
// in einer Konfigurationsdatei.
logger.setLevel(Level.INFO);
Logger nlogger = Logger.getLogger("org.apache.log4j");
// Dieser Eintrag ist aktiviert, da WARN > INFO.
logger.warn("Wenig Speicher verfügbar.");
// Dieser Eintrag ist aktiviert, da DEBUG INFO.
logger.debug("Starte den Garbage-Collector.");
// Dieser Eintrag ist aktiviert, da DEBUG INFO
// und der Level INFO vererbt wurde.
nlogger.info("Neuen Datensatz angelegt");
// Dieser Eintrag ist deaktiviert, da DEBUG < INFO.
nlogger.debug("Die Grösse des Objektes beträgt 256 Bytes");
Die Fähigkeit Logger-Meldungen selektiv ein- oder auszuschalten ist nur einen Teil des Funktionsumfangs von log4j. Log4j erlaubt das versenden der Logger-Meldungen an verschiedene Destinationen. In log4j werden solche Destinationen Appenders genannt. Folgende werden zurzeit unterstützt:
Es kann mehr als einen Appender an einen Logger "angehängt" werden. Die gleiche Meldung kann also in die Logdatei sowie an einen Remote-Socket-Server gesendet werden.
Der Output eines Loggers L wird allen Appenders gesendet, welchen L zugeordnet sind plus allen Vorfahren. Diese Vererbung wird "Appender Additivity" genannt. Diese Vererbung ist standardmässig gesetzt und muss explizit ausgeschaltet werden, wenn sie nicht erwünscht ist.
| Name des Loggers | Konfigurierte Appenders | Additivity Flag | Output Targets | Kommentar |
|---|---|---|---|---|
| root | A1 | nicht anwendbar | A1 | |
| org | A-org1, A-org2 | true | A1, A-org1, A-org2 | Appenders von "org" und root. |
| org.apache | none | true | A1, A-org1, A-org2 | Appenders von "org" und root. |
| org.apache.log4j | A-log4j | true | A1, A-org1, A-org2 A-log4j | Appenders von "org.apache.log4j", "org" und root. |
| security | A-sec | false | A-sec | Nur Appender A-sec. Keine Appenders werden vererbt, da dass Additivity-Flag auf false gesetzt ist. |
| security.access | none | true | A-sec | Nur Appenders von "security". |
in vielen Anwendungen macht es Sinn, wenn nachträglich die Meldungen formatiert werden können. Solche Formatierungshilfen werden im form von Layouts, welche an Appenders angehängt werden, angeboten.
Layouts werden mir einem Pattern-Layout definiert.
Beispiel:
Folgendes Pattern-Layout "%r [%t] %-5p %c - %m%n" ergibt folgender Output
176 [main] INFO org.apache.log4j.Action - Der Prozess wurde gestartet
Hier die wichtigsten Layout-Patterns:
| Zeichen | Effekt |
|---|---|
| c | Category: Kategorie = Name org.apache |
| C | Class = Klassennamen |
| d | Date. Beispiel: %d{HH:mm:ss,SSS} |
| F | Filename |
| l | Location. Aufrufende Methode, Quelle, Dateiname und Zeilennummer |
| L | Line number |
| m | Meldung selbst |
| M | Methodennamen |
| n | Line-Separator (Plattformabhängig) |
| p | Priority: INFO, WARN, ERROR etc. |
| r | Anzahl der Millisekunden set dem Start der VM |
| t | Name des Threads |
Die Konfiguration für Log4J kann mittels XML oder mit Properties-Dateien gemacht werden.
Beispiel log4j.properties:
# Der Root-Logger hat den Level DEBUG log4j.rootLogger=DEBUG, A1 # Wir haben einen Appender mit der Destionation Konsole log4j.appender.A1=org.apache.log4j.ConsoleAppender # Für diesen Appender verwenden wir eine Layout log4j.appender.A1.layout=org.apache.log4j.PatternLayout # Datum im ISO-Format ISO-8601 anzeigen log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n # Für alle Klassen des Packages ch.scherer-it.xy den Level ERROR zuweisen log4j.logger.ch.scherer-it.xy=ERROR
Die Konfigurationsdatei wird mit dem System-Property "-Dlog4j.configuration" der VM bekannt gegeben. Wenn das Proprty nicht gesetzt ist, such das Logging System nach einer Konfigurationsdatei im Klasspfad, welche log4j.properties heisst.
Hier noch ein Beispiel mit zwei Appenders:
# Der Root-Logger hat den Level DEBUG log4j.rootLogger=DEBUG, stdout, file # Wir haben einen Appender mit der Destionation Konsole log4j.appender.stdout=org.apache.log4j.ConsoleAppender # Für diesen Appender verwenden wir eine Layout log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Datum im ISO-Format ISO-8601 anzeigen log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n # Für alle Klassen des Packages ch.scherer-it.xy den Level ERROR zuweisen log4j.logger.ch.scherer-it.xy=ERROR # Konfiguration der Log-Datei log4j.appender.file=org.apache.log4j.RollingFileAppender log4j.appender.file.File=c:/temp/log4j.log log4j.appender.file.MaxFileSize=100KB # Eine Backup-Datei behalten log4j.appender.file.MaxBackupIndex=1 log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%p %t %c - %m%n
Die Kosten bei ausgeschaltetem Level sind pro Call, je nach Prozessor, im kleinen Nanosekundenbereich (1-20ns).
Dabei sind aber die Kosten für die Konstruktion der Parameter nicht enthalten.
Wenn im Funktionsaufruf einen zusammengesetzten Parameter mitgegeben wird kann dies unnötig Zeit kosten.
Wenn Parameter extra konstruiert werden müssen, sollte man immer zuerst prüfen, ob der entsprechende Level eingeschaltet ist. Zumindest bei den Levels INFO und DEBUG ist es dringend empfohlen.
if( logger.isDebugEnabled()) {
logger.debug("Der aktuelle Wert ist " + x*y + " Einheiten" );
}
![]() |
Scherer Informatik GmbH | Tel 032 396 39 05 | ||
| Juchen 24A | Fax 032 396 39 06 | |||
| CH-2577 Siselen | info(at)scherer-informatik.ch |