Montag, 5. Juli 2010

Logging in Java

Mittels des Apache Pakets log4j 1.2 kann man bequem Log Meldungen im Code unterbringen, die unterschiedlich gewichtet sind. Man definiert zunächst ein Log Objekt über den Aufruf der Fabrikmethode Logger.getLogger(EineKlasse.class). Die Methode Logger.getLogger(String) erwartet einen String Parameter, der indirekt über .getName() von Class geliefert wird. Das ist also äquivalent zu Logger.getLogger("class vollerPfadzuEineKlasse"). Dadurch wird ein Singleton Logger für die Klasse EineKlasse erzeugt.
Mit diesem Objekt kann man dann über verschiedene Level Meldungen rausschicken.
Die Level mit ihrer Priorität sind: DEBUG < INFO < WARN < ERROR < FATAL.

Die entsprechenden Methoden meinLogger.debug("Text ....") usw. . Einem Logger wird nun ein Level zur Startzeit zugeordnet (über Konfigurationsdatei), über den die im Code eingestreuten log Aufrufe aktiviert oder deaktiviert werden.
Alle log Meldungen, deren Level mindestens genauso hoch wie der aktuelle Log Level sind sind aktiv.
Wenn der Level des Loggers auf DEBUG eingestellt wird, dann sind alle Log Methodenaufrufe aktiv. Wenn der Level des Loggers auf FATAL eingestellt ist, dann werden nur die Methodenaufrufe .fatal() aktiv. Alle anderen log Aufrufe über .debug(), .info() , .warn() und .error() werden nicht verarbeitet. Dies ist zu vergleichen mit dem Makroprozessor in C, wo über Headervariablen einzelne Codeabschnitte für die Kompilierung ein oder ausgeschaltet werden. Nur geschieht das hier rein formal nicht in der Kompilierphase, sondern zur Laufzeit. Allerdings ist der Performance-Effekt laut Apache gleichzusetzen mit dem Ein- und Ausblenden zur Kompilierzeit.

Falls einem Logger kein Level zum Programmstart zugeordnet wird, dann erbt es den Level seines Vorfahrrens. Für diesen gilt das gleiche. Da der Rootlogger immer einen Level hat (DEBUG) besitzt im Umkehrschluss jeder Logger einen Level über diesen Vererbungsmechanismus.



Die Log Meldungen können nun wiederum an verschieden Orte ausgegeben werden. Dazu werden dem Logger ein oder mehrere Appender zugewiesen. Diese können Konsolen, Dateien, Socket-Verbindungen und beliebige andere Ziele sein. Zuweisung erfolgt über log4j.appender.AppenderName[.*]=Wert Zuweisungen.


Hier ein Beispiel:

log4j.appender.SessionLogAppender=de.xxx.util.log.JIDFileAppender
log4j.appender.SessionLogAppender.file='Logs/'yyyy-MM-dd/'Logs %s_'yyyy-MM-dd_HH-mm-ss'.log'
log4j.appender.SessionLogAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.SessionLogAppender.layout.ConversionPattern=%-5p %d{yyyy-MM-dd HH:mm:ss,SSS} (%F:%L) %m%n 
 
Alle aktiven Log Meldungen vom Logger werden an jeden definierten Appender herausgeschickt und an die Appender seiner Vorfahren.
Dabei kann ein Logger durch setzen des additivity flag auf false das Erben von Appendern seiner Vorfahren verhindern.
Beispiel:
Logger a = Logger.getLogger("a");//Appender für Klassen mit Paketpräfix a
Logger b = Logger.getLogger("a.b");//Will Appender von a erben. additivy flag = true (Voreinstellung) 
Logger c = Logger.getLogger("a.c");//Will nur seine eigenen Appender und nicht die von a. Setzt dazu additivy flag = false 
 
Der Root Logger hat übrigens keinen Default Appender, sondern nur einen Default Debug Level (nämlich DEBUG).

Keine Kommentare:

Kommentar veröffentlichen