neo's nice place neo's nice place sitemap
neo's nice place
main
about me
berlin
guestbook
links
links
miscellaneous
sitemap

Fabian
Einleitung Installation Logger Appender/Layout Konfiguration Links Dateien

log4j - Ein Logger für Java

Zusammenfassung

Einleitung: Warum log4j?

  • 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

Installation:

  1. Die entsprechende Programmrevision herunterladen oder von CD kopieren
  2. 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
  3. Die Jar-Datei in den CLASSPATH aufnehmen
  4. zum Anfang

Funktionsweise:

  • Category/Logger hierarchy

    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

  • Appender und Layout

    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

  • Konfiguration

    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:

Hello.java Zum testen der richtigen Installation von log4j, Ausgabe:
0 [main] DEBUG Hello - Hello world.
20 [main] INFO Hello - What a beatiful day.
Testa.java
Test2.java
Beispiel mit BasicConfigurator und 2 Klassen
Testb.java
Test2.java
1.config
2.config
Beispiel mit PropertyConfigurator und 2 verschiedenen Konfigurationsdateien
XMLConfig.java
sample1.xml
sample2.xml
Beispielklasse zum Lesen einer XML-Konfigurationsdatei

zum Anfang

 

von Bastian L. Blywis

sitemap