|
Einleitung Installation Logger Appender/Layout Konfiguration Links Dateien
log4j - Ein Logger für Java
- Schneller als system.out.println
- Ausgabe auf Konsole, Datei, OutputStream, java.io.Writer, remote
log4j Server, remote Unix Syslog deamon, NT Event logger, ...
- Konfiguration des Loggers über eine Konfigurationsdatei
- Filtermechanismus
zum Anfang
- Die entsprechende Programmrevision herunterladen
oder von CD kopieren
- Entweder: Ganzes Archiv an beliebiger Stelle entpacken
Oder: Lediglich die in \jakarta-log4j-X.XXXX\dist\lib enthaltende log4j-X.XXXX.jar
an beliebiger Stelle platzieren
- Die Jar-Datei in den CLASSPATH aufnehmen
zum Anfang
Funktionsweise:
-
Kategorien bilden das zentrale Konzept hinter log4j. In org.log4j.Category
wird die entsprechende Klasse definiert, deren benannte Instanzen die
Kategorien bilden. Ähnlich wie in Java gibt es eine
Vererbungshirarchie. Eine Kategorie ist parent einer einer anderen,
falls ihr Name gefolgt von einem Punkt Prefix ist. So ist z.B. com.vater
parent von com.vater.sohn und anchestor von com.vater.sohn.enkel.
Die Klasse gilt jedoch als veraltet, sie wird lediglich bis Mitte 2003
beibehalten. Abgelöst wird sie durch die Logger Klasse. Da dies
eine Subklasse ist, bleiben alle Operationen auf Kategorien auch auf
Logger durchführbar.
An oberster Stelle steht der root Logger, welcher sich durch
folgende Eigenschaften abhebt:
1) Er ist namenlos
2) Er ist immer existent
Die Logger Klasse enthält folgende wichtige Methoden:
- Die statische Methode getRootLogger() gibt den root
Logger zurück
- Die statische Methode getLogger(String name) instanziert
die Klasse Logger oder gibt die bereits vorhandene Klasse
mit dem Parameter name zurück
package org.apache.log4j;
public Logger class
{
// 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);
// generic printing method:
public void log(Level l, Object message);
}
Loggern können Level zugeordnet werden. Mögliche Level sind: DEBUG,
INFO, WARN, ERROR und FATAL.
Im allgemeinen sollten die Level für folgende Nachrichten benutzt werden:
DEBUG |
Alle für das Debugging notwendigen Nachrichten |
INFO |
Nachrichten ähnlich des Verbose-Modes |
WARN |
Nachrichten (Fehler) die geloggt werden, das Programm aber weiterlaufen
lassen |
ERROR |
Nachrichten (Fehler) die geloggt werden, das Programm aber weiterlaufen
lassen und z.B. statt eines falschen Parameters ein Standartwert
verwendet wird |
FATAL |
Kritische Nachricht (Fehler) -> das Programm stürzt ab |
Falls einem Logger kein Level zugewiesen wird,
so erbt er den Level des ersten Vorfahren, dem ein Level zugewiesen
wurde(Anchestor).
Um die Vererbung sicherzustellen, hat der root Logger
stets einen Level.
Logging-Anfragen werden durch Aufrufen einer der Print-Methoden verarbeitet.
Sie heissen: debug, info, warn, error, fatal
und log. Per Definition bestimmt die Print-Methode den Level
der Logging-Anfrage. So ist z.B., falls test eine Logger-Instanz ist,
die Anweisung test.inf("..") eine Logging-Anfrage des Levels INFO.
Eine Logging-Anfrage gilt als aktiviert, falls ihr
Level höher oder gleich dem Level des Loggers ist. Ansonsten wird die
Anfrage als deaktiviert bezeichnet.
Es gilt: DEBUG < INFO < WARN < ERROR < FATAL.
Logger können in beliebiger Reihenfolge erstellt und konfiguriert werden.
So ist es z.B. möglich ein child vor dem parent zu erstellen,
denn parent Logger finden stets ihre Nachkommen.
Die Konfiguration der log4j-Umgebung erfolgt typischerweise bei der
Programminitialisierung. Der bevorzugte Weg ist das Lesen einer Konfigurationsdatei.
(mehr dazu später)
Tip: Log4j macht es einfach Logger nach Softwarekomponenten zu
benennen. Dies kann durch statische Instanzierung
eines Loggers in jeder Klasse erreicht werden, wobei der Logger
den vollen Namen der entsprechenden Klasse trägt. Dies ist eine nützliche
und gradlinige Methode Logger zu definieren und nutzen. Da die
ausgebene Logdatei den Namen des generierenden Loggers trägt, ist es
leicht den Ursprung der Nachricht zu finden.
zum Anfang
-
Die Möglichkeit selektiert Logger-Anfragen auf Basis der Logger
an und aus zu schalten ist nur einer der Vorteile. Log4j erlaubt es
Logging-Anfragen an multiple Ziele zu senden. In log4j wird das Ziel
einer Ausgabe appender genannt. Zur Zeit existieren u.a. appender
für die Konsole,
Dateien,
GUI-Komponenten, Remote
Socket Server, JMS,
NT
Event Logger und Unix
Syslog deamons. Es ist auch möglich asynchron aufzuzeichnen.
Mehr als ein appender kann einem Logger zugeordnet werden.
Die addAppender Methode fügt einen appender zu einem Logger
hinzu. Jede aktivierte Logging-Anfrage an einen Logger wird an
alle seine appender weitergeleitet und an die appender
die höher in der Hierarchie stehen. In anderen Worten, appender
werden additiv in der Logger-Hierarchie vererbt. So wird z.B. ein appender
des root Loggers an alle children vererbt. Es ist möglich
dieses Verhalten mit Setzen des additivity
flag auf false zu unterbinden.
Zur Formatierung der Ausgabe ist es möglich einem appender ein
layout zuzuordnen. Somit lässt sich mit dem PatternLayout
die Ausgabe ähnlich wie bei der printf Funktion in C formatieren.
So führt z.B. dieses PatternLayout "%r [%t] %-5p %c - %m%n" zu
folgender Ausgabe:
233 [main] INFO vater.sohn - Test
Es gibt folgende Layouts: TTCCLayout,
HTMLLayout,
PatternLayout,
SimpleLayout
und XMLLayout
Zusätzlich ist es auch möglich Objekte mit einem ObjectRenderer
zu loggen, nachdem das Interface ObjectRenderer
implementiert wurde.
zum Anfang
-
Momentan kann log4j per Konfigurationsdateien in XML oder per Java-Zuweisungen
(key=value) konfiguriert werden.
Beispiel:
// Importiere alle log4j Klassen
import org.apache.log4j.*;
public class Test
{
// Statische Logger-Variable definieren, so dass sie die Logger-Instanz
Test referenziert
static Logger logger = Logger.getLogger(Test.class);
public static void main(String[] args)
{
// Einfache Konfiguration die auf der Konsole loggt
BasicConfigurator.configure();
logger.info("Starte Programm");
Test2 test2 = new Test2();
test2.los();
logger.info("Beende Programm");
}
}
import org.apache.log4j.*;
public class Test2
{
static Logger logger = Logger.getLogger(Test2.class);
public void los()
{
logger.debug("Mache irgendwas...");
}
}
Der BasisConfigurator
fügt dem root Logger einen ConsoleAppender
mit PatternLayout(%-4r
[%t] %-5p %c %x - %m%n) hinzu.
Hinweis: Der root Logger hat standartmässig den Level
DEBUG.
Dies führt zu folgender Ausgabe:
0 [main] INFO Test - Starte Programm
30 [main] DEBUG Test2 - Mache irgendwas...
30 [main] INFO Test - Beende Programm
Nach dem Ändern von BasisConfigurator.configure()
in PropertyConfigurator.configure(args[0])
und mit Hilfe einer Konfigurationsdatei, erhält man die selbe Ausgabe:
# PropertyConfigurator der die selbe Ausgabe
wie eine BasisConfigurator erzeugt
# root Logger auf Level DEBUG setzen, mit einzigem appender A1
log4j.rootLogger=DEBUG, A1
# A1 ist ein ConsoleAppender
log4j.appender.A1=org.apache.log4j.ConsoleAppender
# A1 benutzt PatternLayout
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
Eine geänderte Konfigurationsdatei unterdrück alle Nachrichten aus Test2
unterhalb von WARN:
# Zeigt nur WARN, ERROR, FATAL Nachrichten
von Test2
log4j.rootLogger=DEBUG, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
# Datum im ISO 8601 Format ausgeben
log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
# Nur WARN, ERROR, FATAL Nachrichten von Test2 anzeigen
log4j.logger.Test2=WARN
Dies führt zu folgender Ausgabe:
2002-04-29 16:22:26,393 [main] INFO Test - Starte
Programm
2002-04-29 16:22:26,403 [main] INFO Test - Beende Programm
Der DOMConfigurator
lässt uns log4j per XML-Datei konfigurieren.
Er wird auch benutzt, falls der PropertyConfigurator
mit einer Datei mit Endung .xml aufgerufen wird.
Eine Beispielklasse um eine XML-Datei zu lesen:
public class XMLConfig
{
static Logger logger = Logger.getLogger(XMLSample.class.getName());
public static void main(String argv[])
{
if(argv.length == 1)
{
init(argv[0]);
}
else
{
System.err.println("Wrong number of arguments.");
System.err.println( "Usage: java " + XMLSample.class.getName() +" configFile");
}
}
static void Usage(String msg)
{
System.err.println(msg);
System.err.println( "Usage: java " + XMLSample.class.getName() +" configFile");
}
static void init(String configFile)
{
DOMConfigurator.configure(configFile);
}
}
Eine XML-Konfiguration könnte so aussehen:
<?xml version="1.0" encoding="UTF-8"
?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L)
- %m%n"/>
</layout>
</appender>
<category name="org.apache.log4j.xml">
<priority value="info" />
</category>
<root>
<priority value ="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
zum Anfang
Links:
log4j Homepage
Kurzanleitung
API
FAQ Troubleshooting
zum Anfang
Dateien:
zum Anfang
von Bastian L. Blywis
|
|
|