Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.
 
Inhaltsverzeichnis
Vorwort
1 Neues in Java 8 und Java 7
2 Fortgeschrittene String-Verarbeitung
3 Threads und nebenläufige Programmierung
4 Datenstrukturen und Algorithmen
5 Raum und Zeit
6 Dateien, Verzeichnisse und Dateizugriffe
7 Datenströme
8 Die eXtensible Markup Language (XML)
9 Dateiformate
10 Grafische Oberflächen mit Swing
11 Grafikprogrammierung
12 JavaFX
13 Netzwerkprogrammierung
14 Verteilte Programmierung mit RMI
15 RESTful und SOAP-Web-Services
16 Technologien für die Infrastruktur
17 Typen, Reflection und Annotationen
18 Dynamische Übersetzung und Skriptsprachen
19 Logging und Monitoring
20 Sicherheitskonzepte
21 Datenbankmanagement mit JDBC
22 Java Native Interface (JNI)
23 Dienstprogramme für die Java-Umgebung
Stichwortverzeichnis

Jetzt Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Java SE 8 Standard-Bibliothek von Christian Ullenboom
Das Handbuch für Java-Entwickler
Buch: Java SE 8 Standard-Bibliothek

Java SE 8 Standard-Bibliothek
Pfeil 19 Logging und Monitoring
Pfeil 19.1 Logging mit Java
Pfeil 19.1.1 Logging-APIs
Pfeil 19.1.2 Logging mit java.util.logging
Pfeil 19.1.3 Logging mit log4j *
Pfeil 19.1.4 Die Simple Logging Facade
Pfeil 19.1.5 Aktuelle Entwicklungen der Java-Logging-APIs
Pfeil 19.2 Systemzustände überwachen
Pfeil 19.3 MBean-Typen, MBean-Server und weitere Begriffe
Pfeil 19.3.1 MXBeans des Systems
Pfeil 19.4 Geschwätzige Programme und JConsole
Pfeil 19.4.1 JConsole
Pfeil 19.5 Der MBeanServer
Pfeil 19.6 Eine eigene Standard-MBean
Pfeil 19.6.1 Management-Schnittstelle
Pfeil 19.6.2 Implementierung der Managed-Ressource
Pfeil 19.6.3 Anmeldung beim Server
Pfeil 19.6.4 Eine eigene Bean in JConsole einbringen
Pfeil 19.7 Zum Weiterlesen
 
Zum Seitenanfang

19Logging und Monitoring Zur vorigen ÜberschriftZur nächsten Überschrift

»Alle menschlichen Fehler sind Ungeduld.«
– Franz Kafka (1883–1924)

Nicht nur in der Informatik ist der rasante Wechsel der Technologien zu beobachten. Ein Beispiel ist das Automobil, das in den letzten 100 Jahren tiefgreifende Änderungen durchmachte. Von den vielen Schlagwörtern sind ESP und ABS nur zwei, die zudem eine Elektrifizierung bedeuten. Die Komponenten eines Autos sind vernetzt, und Signalgeber melden in Echtzeit Informationen an elektronische Steuereinheiten (Electronic Control Units, ECU). In modernen Kraftfahrzeugen werten fast 100 ECUs mehr als 1 GB an Daten pro Sekunde aus. Damit verschiebt sich auch eine Fehlerquelle: Während früher erst eine Sicherung durchbrennen musste, bleibt ein Auto heute schon stehen, wenn der Bordcomputer einen Fehler meldet. Auch in der Entwicklung ist das teuer: BMW gibt an, dass 40 % der Herstellungskosten auf Elektronik und Software anfallen.

 
Zum Seitenanfang

19.1Logging mit Java Zur vorigen ÜberschriftZur nächsten Überschrift

Das Loggen (Protokollieren) von Informationen über Programmzustände ist ein wichtiger Teil, um später den Ablauf und die Zustände von Programmen rekonstruieren und verstehen zu können. Mit einer Logging-API lassen sich Meldungen auf die Konsole oder in externe Speicher wie Text- oder XML-Dateien bzw. in eine Datenbank schreiben oder über einen Chat verbreiten.

 
Zum Seitenanfang

19.1.1Logging-APIs Zur vorigen ÜberschriftZur nächsten Überschrift

Bei den Logging-Bibliotheken und APIs ist die Java-Welt leider gespalten. Da die Java-Standardbibliothek in den ersten Versionen keine Logging-API anbot, füllte die Open-Source-Bibliothek log4j schnell diese Lücke. Sie wird heute in nahezu jedem größeren Java-Projekt eingesetzt. Als Sun dann in Java 1.4 eine eigene Logging-API (JSR-47) einführte, war die Java-Gemeinde erstaunt, dass java.util.logging (JUL) weder API-kompatibel zum beliebten log4j noch so leistungsfähig wie log4j ist.[ 140 ](Suns Logging-API ist dagegen nur ein laues Lüftchen, das nur Grundlegendes wie hierarchische Logger bietet. An die Leistungsfähigkeit von log4j mit einer großen Anzahl von Schreibern in Dateien (FileAppender, RollingFileAppender, DailyRollingFileAppender), Syslog und NT-Logger (SyslogAppender, NTEventLogAppender), Datenbanken, Versand über das Netzwerk (JMSAppender, SMTPAppender, SocketAppender, TelnetAppender) kommt das Sun-Logging nicht heran.)

Im Laufe der Jahre veränderte sich das Bild. Während in der Anfangszeit Entwickler ausschließlich auf log4j bauten, werden es langsam mehr Projekte mit der JUL. Ein erster Grund ist der, externe Abhängigkeiten zu vermeiden (wobei das nicht wirklich funktioniert, da nahezu jede eingebundene Java-Bibliothek selbst auf log4j baut), und der zweite, dass für viele Projekte JUL einfach reicht. In der Praxis bedeutet dies für größere Projekte, dass mehrere Logging-Konfigurationen das eigene Programm verschmutzen, da jede Logging-Implementierung unterschiedlich konfiguriert wird.

 
Zum Seitenanfang

19.1.2Logging mit java.util.logging Zur vorigen ÜberschriftZur nächsten Überschrift

Mit der Java-Logging-API lässt sich eine Meldung schreiben, die sich dann zur Wartung oder zur Sicherheitskontrolle einsetzen lässt. Die API ist einfach:

Listing 19.1com/tutego/insel/logging/cul/CULDemo.java, JULDemo

public class CULDemo {

private static final Logger log = Logger.getLogger( CULDemo.class.getName() );

public static void main( String[] args ) {
log.info( "Dann mal los." );

try {
((Object) null).toString();
}
catch ( Exception e ) {
log.log( Level.SEVERE, "oh oh", e );
}

log.info( "Ging alles glatt." );
}
}

Lassen wir das Beispiel laufen, folgt auf der Konsole die Warnung:

Jun 08, 2012 2:14:18 PM com.tutego.insel.logging.jul.CULDemo main
Schwerwiegend: oh oh
java.lang.NullPointerException
at com.tutego.insel.logging.jul.CULDemo.main(CULDemo.java:14)
Jun 08, 2012 2:14:18 PM com.tutego.insel.logging.jul.CULDemo main
Information: Ging alles glatt.

Das Logger-Objekt

Zentral ist das Logger-Objekt, das über Logger.getAnonymousLogger() oder über Logger.getLogger(String name) geholt werden kann, wobei name in der Regel mit dem voll qualifizierten Klassennamen belegt ist. In der Regel ist der Logger als private statische finale Variable in der Klasse deklariert.

Loggen mit Log-Level

Nicht jede Meldung ist gleich wichtig. Einige sind für das Debuggen oder wegen der Zeitmessungen hilfreich, doch Fehlermeldungen in den catch-Zweigen sind enorm wichtig. Damit verschiedene Detailgrade unterstützt werden, lässt sich ein Log-Level festlegen. Er bestimmt, wie »ernst« der Fehler bzw. eine Meldung ist. Das ist später wichtig, wenn die Fehler nach ihrer Dringlichkeit aussortiert werden. Die Log-Level sind in der Klasse Level als Konstanten deklariert:[ 141 ](Da das Logging-Framework in Version 1.4 zu Java stieß, nutzt es noch keine typisierten Aufzählungen, denn die gibt es erst seit Java 5.)

  • FINEST (kleinste Stufe)

  • FINER

  • FINE

  • CONFIG

  • INFO

  • WARNING

  • SEVERE (höchste Stufe)

Zum Loggen selbst bietet die Logger-Klasse die allgemeine Methode log(Level level, String msg) bzw. für jeden Level eine eigene Methode:

Level

Aufruf über log(…)

Spezielle Log-Methode

SEVERE

log(Level.SEVERE, msg)

severe(String msg)

WARNING

log(Level.WARNING, msg)

warning(String msg)

INFO

log(Level.INFO, msg)

info(String msg)

CONFIG

log(Level.CONGIF, msg)

config(String msg)

FINE

log(Level.FINE, msg)

fine(String msg)

FINER

log(Level.FINER, msg)

finer(String msg)

FINEST

log(Level.FINEST, msg)

finest(String msg)

Tabelle 19.1Log-Level und Methoden

Alle diese Methoden setzen eine Mitteilung vom Typ String ab. Sollen eine Ausnahme und der dazugehörende Strack-Trace geloggt werden, müssen Entwickler zu folgender Logger-Methode greifen, die auch schon das Beispiel nutzt:

  • void log(Level level, String msg, Throwable thrown)

Die Varianten von severe(…), warning(…) usw. sind nicht überladen mit einem Parametertyp Throwable.

Log-Meldungen formatieren

Um Log-Nachrichten einfach zu formatieren – und um Kosten für eine String-Konkatenation einzusparen, falls die Nachricht nicht geloggt wird –, gibt es von der Methode log(…) zwei weitere Version:

  • void log(Level level, String msg, Object param1)

  • void log(Level level, String msg, Object[] params)

Um von der Log-Nachricht auf den Parameter zuzugreifen, gibt es einen Platzhalter der Art {0}, {1}, der auf die Log-Parameter der angegebenen Position zugreift. Wollen wir zum Beispiel den Dateinamen als INFO loggen, sieht das so aus:

log.log( Level.INFO, "Open {0}", file );

Sollen Dateiname und Länge in die Nachricht einfließen, muss für die Argumente ein Minifeld aufgebaut werden, da die Logging-API ein Object[] erwartet und nicht mit Varargs arbeitet:

log.log( Level.INFO, "Open {0}, size {1}",
new Object[]{ file, Files.size( Path.get(file) ) } );

Würde geloggt werden?

Das Logging-Framework versucht, so schnell wie möglich zu entscheiden, ob eine Nachricht bei einem eingestellten Log-Level geloggt werden soll oder nicht. Ist die Stufe in der Produktion zum Beispiel auf WARNING, sind INFO-Meldungen zu ignorieren. Problematisch aus Performance-Sicht sind zum Beispiel aufwändig aufgebaute Log-Nachrichten, die dann sowieso nicht geloggt werden. Ein

log.info( "Open " + file + ", size " + Files.size( Path.get(file) ) );

führt zur Laufzeit immer zu einer String-Konkatenation und einem Attributzugriff auf das Dateisystem, egal, ob die erzeugte Nachricht später geloggt wird oder nicht. Platzhalter schaffen Abhilfe, aber der teure Zugriff auf die Dateilänge bleibt, denn Java wertet erst alle Argumente aus, bevor die Methode aufgerufen wird.

JUL bietet zur Umgehung des Problems zwei Lösungen. Als Erstes bietet die Logger-Klasse eine Testmethode boolean isLoggable(Level level), über die ein schneller Test durchgeführt werden kann:

if ( log.isLoggable(Level.INFO) )
log.info( "Open " … );

Natürlich kann info(…) nicht wissen, dass es auf jeden Fall loggen soll, daher findet der Test noch einmal statt. Eine allgemeine Überprüfung für alle Logging-Ausgaben bietet sich daher nicht an, sondern nur dann, wenn eine aufwändige Operation im Logging-Fall ausgeführt werden soll.

Die zweite Möglichkeit ist neu in Java 8. Sie nutzt Objekte vom Typ Supplier, die eine Implementierung enthalten, also etwa die Konkatenation oder teure Zugriffe auf das Dateisystem. Im Prinzip hätte Oracle das auch schon vor Java 8 integrieren können, doch erst Lambda-Ausdrücke führen zu einer kompakten Schreibweise. Das sieht zum Beispiel so aus:

log.info( () -> { "Open " + file + ", size " + Files.size( Path.get(file) ) } );

Der Programmcode wird so lange nicht ausgewertet, bis das Logging-Framework entscheidet, dass der Block ausgeführt werden muss. Erst dann gibt es Kosten für String-Operationen und Dateizugriff.

Neue log(…)-Methoden seit Java 8 in java.util.logging.Logger mit Supplier sind: log(Level, Throwable, Supplier), severe(Supplier), warning(Supplier), info(Supplier), config(Supplier), fine(Supplier), finer(Supplier) und finest(Supplier).

Handler und Logging in eine Datei

Wenn der Logger Nachrichten herausschreibt, dann baut er zunächst ein LogRecord-Objekt – es enthält Informationen wie die Log-Nachricht, Zeit, Thread-ID, Log-Level. Anschließend gibt das Logging-Framework dieses Objekt an einen assoziierten Handler weiter. Soll der Logger in eine Datei schreiben, so kann er mit einem FileHandler verbunden werden; sollen die Meldungen nach System.err gehen, so lässt sich der ConsoleHandler nutzen.

Hinzugefügt wird ein Handler mit addHandler(Handler), etwa so:

Handler handler = new FileHandler( "log.txt" );
log.addHandler( hanlder );

Um das Datenvolumen zu kontrollieren und einzuschränken, lassen sich die Logger bzw. Handler mit einem Filter versehen, der nur das in den Datenstrom schreibt, was den Filter passiert. Und das Datenformat selbst kann zusätzlich mit Formatobjekten angepasst und lokalisiert werden, bevor der Logger sie in den Datenstrom schreibt. Die Logging-API unterstützt hierzu Resource-Bundles.

Log-Level

Der Logger und der Handler sind beide mit einem Log-Level verbunden. Externe Konfigurationseinstellungen oder die Methode setLevel(Level) setzen diesen Level. Jede Meldung, die einen höheren Level als diesen gesetzt hat, kommt zur Ausgabe. Die Prüfung ist zweistufig: Wenn die Meldung den Logger passiert, kann der Handler (oder die Handler, es kann mehrere geben) die Nachricht noch verwerfen. Soll wirklich alles geloggt werden, müssen der Logger und auch der Handler mit setLevel(Level.ALL) initialisiert werden. setLevel(Level.OFF) schaltet das Logging aus.

[zB]Beispiel

Setze einen ConsoleHandler, und gib alle Log-Meldungen aus:

Logger log = Logger.getLogger( CULDemo.class.getName() );
Handler handler = new ConsoleHandler();
handler.setLevel( Level.FINEST );
log.addHandler( handler );
log.setLevel( Level.FINEST );
log.fine( "Alles ist fein!" );

[»]Hinweis

Wenn in unserem Beispiel etwas fine(…) geloggt wird und setLevel(Level.ALL) gesetzt ist, erscheint die Ausgabe dennoch nicht, da Oracle mit der Datei logging.properties im lib-Verzeichnis vom JRE den Standard-Log-Level vom Konsolen-Handler mit INFO vorbelegt hat. Und es sind ja immer zwei Level-Tests, die eine Log-Meldung bestehen muss. Selbst wenn unser Logger die Meldung annimmt, so verwirft sie der voreingestellte Konsolen-Logger.

Methoden logp(…)

Die normalen log(…)- und Hilfsmethoden loggen eine Nachricht nach einem gewissen Log-Level. Es gibt weiterhin mehrere überladene logp(…)-Methoden, die zusätzlich über einen String einen Klassennamen und Methodennamen annehmen, der dann mit geloggt wird. Die einfachste Variante ist logp(Level level, String sourceClass, String sourceMethod, String msg).

Während die normalen Logger-Methoden wie fine(…) oder severe(…) nicht auf logp(…) zurückgreifen, sondern auf log(Level level, …), gibt es zwei Methoden in Logger, die über logp(…) arbeiten, das sind entering(…) und exiting(…), die verwendet werden, um das Betreten bzw. Verlassen von Methoden zu dokumentieren.

Internationalisierung mit setResourceBundle(…) und logrb(…)

Nutzer von log(…) und logp(…) können die Meldungen internationalisieren. Dafür bietet die API zwei Möglichkeiten. Als Erstes kann seit Java 8 global für den Logger mit setResourceBundle(ResourceBundle bundle) ein ResourceBundle zugewiesen werden. Immer dann, wenn eine Log-Nachricht geschrieben wird, wird der Logger zunächst die Nachricht als Schlüssel in der Ressourcen-Abbildung nutzen; gibt es zu dem Schlüssel keine Übersetzung, gilt die Nachricht als Log-Ausgabe.

Neben dieser globalen Zuweisung über setResourceBundle(…) gibt es zwei Extra-Methoden logrb(…), die ResourceBundle-Objekte direkt annehmen:

  • void logrb(Level level, String sourceClass, String sourceMethod, ResourceBundle bundle, String msg, Object... params)

  • void logrb(Level level, String sourceClass, String sourceMethod, ResourceBundle bundle, String msg, Throwable thrown)

[zB]Beispiel

Die Log-Meldung nimmt logrb(…) also aus einem ResourceBundle, und das kann so aussehen:

logger.logrb( Level.SEVERE, "Application", "main",
bundle, "resource.MissingInput" );

Erfragt wird also vom ResourceBundle bundle die Kennung mit der ID resource.MissingInput.

Konfiguration über externe Dateien

Eine weitere Anpassung von Logging besteht darin, es von außen über Property-Dateien zu verfeinern. Sie lassen sich dann beim Start der Anwendung über den Schalter Djava.util.logging.config.file= logging.properties übergeben. Die Datei logging.properties kann etwa so aussehen:

handlers=java.util.logging.FileHandler, java.util.logging.ConsoleHandler

tutego.level = ALL

java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

java.util.logging.FileHandler.level=SEVERE
java.util.logging.FileHandler.pattern=tutego.log
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter

[+]Tipp

Um die Datei zur Laufzeit zu laden und sie nicht explizit beim Programmstart anzugeben, kann Folgendes verwendet werden:

System.setProperty( "java.util.logging.config.file", "logging.properties" );
try { LogManager.getLogManager().readConfiguration(); }
catch ( Exception e ) { e.printStackTrace(); }
 
Zum Seitenanfang

19.1.3Logging mit log4j * Zur vorigen ÜberschriftZur nächsten Überschrift

Die Logging-Bibliothek log4j (http://logging.apache.org/log4j/) ist Open Source und unterliegt der unternehmerfreundlichen Apache Software License. Log4j ist so populär geworden, dass die API auch in andere Programmiersprachen übersetzt wurde, etwa in C++ (log4cxx), Microsoft .NET (log4net) oder PHP (log4php). Aktuell läuft ein Update von der ursprünglichen Version auf die neue Version Log4j 2.

Die Installation im Fall von Java besteht darin, ein Java-Archiv, wie log4j-1.2.16.jar, in den Klassenpfad aufzunehmen.

Das erste Beispiel

Eine Beispielklasse deklariert ein org.apache.log4j.Logger-Objekt als statische Variable, damit unser main(String[]) später über log.info(Object message) und log.error(Object message [, Throwable t]) Meldungen über den Logger absetzen kann. Das Hauptprogramm nutzt zur ersten Konfiguration den BasicConfigurator – im nächsten Schritt ersetzen wir diesen durch eine Konfigurationsdatei.

Listing 19.2com/tutego/insel/logging/log4j/Log4jDemo.java, Log4jDemo

public class Log4jDemo {

private final static Logger log = Logger.getLogger( Log4jDemo.class );

public static void main( String[] args )
{
BasicConfigurator.configure();

log.info( "Dann mal los." );

try {
((Object) null).toString();
}
catch ( Exception e ) {
log.error( "oh oh", e );
}

log.info( "Ging alles glatt." );
}
}

Die Ausgabe ist:

0 [main] INFO com.tutego.insel.logging.log4j.Log4jDemo - Dann mal los.
3 [main] ERROR com.tutego.insel.logging.log4j.Log4jDemo - oh oh
java.lang.NullPointerException
at com.tutego.insel.logging.log4j.Log4jDemo.main(Log4jDemo.java:15)
6 [main] INFO com.tutego.insel.logging.log4j.Log4jDemo - Ging alles glatt.

Zu sehen sind: die Anzahl vergangener Millisekunden seit dem Start des Programms, der Name des loggenden Threads, der Log-Level, der Name des Loggers und die geloggte Nachricht.

Best Practice

Werden Ausnahmen aufgefangen, sollten diese immer mit geloggt werden. Alle Logging-Methoden debug(…), error(…), fatal(…), info(…) und warn(…) sind überladen und existieren einmal mit nur einem Parameter für die Nachricht selbst und dann mit zwei Parametern für die Nachricht und ein Throwable.

Logger, Level, Appenders, Layout

Beim Logging mit log4j sind vier zentrale Begriffe anzutreffen:

  • Logger: Derjenige, der die zu loggenden Einträge annimmt. Steuert, ob überhaupt geloggt werden soll. Steht im Zentrum des Interesses.

  • Level: Was soll geloggt werden? Nur Fehler oder auch Warnungen und Informationen? Der Level priorisiert die Ausgaben, damit die Entwickler den Wald vor lauter Bäumen sehen können.

  • Appenders: Hängen die Log-Ausgabe irgendwo an, etwa an Dateien, die Konsole, NT-Event-Log, Unix Syslog, …

  • Layout: Wie sollen die Ausgaben formatiert werden? Etwa in HTML oder XML?

Der Logger ist mit einem Appender, einem Log-Level und mit einem Layout assoziiert.

Logger-Konfiguration

Log4j lässt sich mit Java-Anweisungen im Quellcode oder mit Konfigurationsdateien im XML- oder Properties-Format konfigurieren. Nehmen wir die programmierte Konfiguration über BasicConfigurator.configure() aus dem Programm, so liefert log4j lediglich folgende Ausgabe:

log4j:WARN No appenders could be found for logger (com.tutego.insel.logging.Log4jDemo).
log4j:WARN Please initialize the log4j system properly.

Der Hinweis ist klar: Es muss eine Konfiguration geben. Setzen wir daher in den Klassenpfad eine Datei mit genau dem Namen log4j.properties und dem folgenden Inhalt:

Listing 19.3log4j.properties

log4j.rootLogger=DEBUG, A
log4j.appender.A=org.apache.log4j.ConsoleAppender
log4j.appender.A.layout=org.apache.log4j.PatternLayout
log4j.appender.A.layout.ConversionPattern=%-4r [%t] %-5p %c %x – %m%n

Starten wir wiederum das Programm, ist die Ausgabe wie vorher:

0 [main] INFO com.tutego.insel.logging.log4j.Log4jDemo - Dann mal los.
3 [main] ERROR com.tutego.insel.logging.log4j.Log4jDemo - oh oh
java.lang.NullPointerException
at com.tutego.insel.logging.log4j.Log4jDemo.main(Log4jDemo.java:15)
5 [main] INFO com.tutego.insel.logging.log4j.Log4jDemo - Ging alles glatt.

Das Muster =%-4r [%t] %-5p %c %x – %m%n bestimmt demnach die Formatierung der Ausgabe in den ConsoleAppender. Der Log-Level ist alles, was »größer« als DEBUG ist. Wenn wir das auf

log4j.rootLogger=ERROR, A

einschränken, bekommen wir lediglich in der Konsolenausgabe Folgendes geschrieben:

0 [main] ERROR com.tutego.insel.logging.Log4jDemo – oh oh
java.lang.NullPointerException
at com.tutego.insel.logging.Log4jDemo.main(Log4jDemo.java:17)

Logger-Hierarchien

Ohne eine Logging-API würden Entwickler vermutlich mit System.out oder System.err Ausgaben schreiben. Dabei gelangen jedoch alle an System.out gesendeten Zeichenketten in den Standardausgabekanal und alle an System.err gesendeten Fehler oder Warnungen in den Fehlerstrom. Ein Wunsch ist, dass die Ausgaben nur für gewisse Pakete oder Klassen gelten sollten. Bei Ausgaben über System.out/err lässt sich das »Logging« aber nicht einfach ausschalten und dann wieder einschalten.

Eine gute Logging-API bietet daher Hierarchien, sodass gewisse Einstellungen einer Ebene auf untergeordnete Ebenen übertragen werden. Diese Baumstruktur kennen wir schon von Paketen:

com

Vater von com.tutego

com.tutego

Nachfolger von com

Die Wurzel-Hierarchie steht am Anfang aller Hierarchien. Sie bildet den Root-Logger. Er hat keinen Namen.

Wenn wir in unserem Fall für das Paket com.tutego und alle Unterpakete den Log-Level auf WARN stellen, schreiben wir in der Konfigurationsdatei:

log4j.logger.com.tutego=WARN
 
Zum Seitenanfang

19.1.4Die Simple Logging Facade Zur vorigen ÜberschriftZur nächsten Überschrift

Immer wieder gibt es Versuche, die Logging-Bibliothek aus der Java-Standardbibliothek und log4j unter einen Hut zu bringen. Das kann so aussehen, dass die Client-API eine andere ist als die darunterliegende Bibliothek, die das Logging wirklich durchführt. Der populärste Versuch ist eine leichtgewichtige Bibliothek namens Simple Logging Facade[ 142 ](Das Prinzip, eine einfache API vor eine komplexe Implementierung zu setzen, ist als das Entwurfsmuster Fassade bekannt.)for Java (http://www.slf4j.org/), abgekürzt SLF4J. Die API sieht etwa so aus:

import org.slf4j.*;

public class HelloMyLogger {
private final static Logger log = LoggerFactory.getLogger( HelloMyLogger.class );
public static void main( String[] args ) {
log.info( "Hallo {}", "Welt" );
}
}

SLF4J hat sich mittlerweile als Logging-Fassade etabliert und schiebt eine alternative API, die Commons Logging (http://commons.apache.org/proper/commons-logging/), abgekürzt JCL, in den Hintergrund. JCL führte in der Praxis zu gewaltigen Problemen mit Klassenladern[ 143 ](http://www.qos.ch/logging/thinkAgain.jsp) und wurde von einigen Kritikern als größter Irrsinn beschimpft. So ist es vielleicht kein Wunder, dass die letzte JCL-Version 1.1.1 von Ende 2007 ist. SLF4J hat keine Probleme mit Klassenladern.

 
Zum Seitenanfang

19.1.5Aktuelle Entwicklungen der Java-Logging-APIs Zur vorigen ÜberschriftZur nächsten Überschrift

Die Welt der Logging-APIs ist unübersichtlich und macht es mit der Einführung von Log4j 2 nicht einfacher. Viele Teams sind von log4j weggegangen und zu Alternativen wie Logback (http://logback.qos.ch/) gewechselt, das die Nachfolge von log4j antreten wollte. Logback implementiert auch die API von SLF4J direkt. Der Autor von log4j und Logback ist in beiden Fällen Ceki Gülcü, sodass Logback von der langen Logging-Erfahrung des Autors profitiert. Da es nun allerdings mit Log4j 2 einen guten Nachfolger vom populären log4j gibt, ist offen, für was sich die Breite Masse der Entwickler entscheiden wird. Fakt ist, dass Log4j 2 deutlicher schneller arbeitet. Log4j 2 und Logback wiederum haben unterschiedliche Möglichkeiten, die http://stackoverflow.com/questions/18816234/log4j-2-0-vs-logback kurz aufzählt.

 


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
 Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Java SE 8 Standard-Bibliothek Java SE 8 Standard-Bibliothek
Jetzt Buch bestellen

 Buchempfehlungen
Zum Rheinwerk-Shop: Java ist auch eine Insel
Java ist auch eine Insel


Zum Rheinwerk-Shop: Professionell entwickeln mit Java EE 8
Professionell entwickeln mit Java EE 8


Zum Rheinwerk-Shop: Besser coden
Besser coden


Zum Rheinwerk-Shop: Entwurfsmuster
Entwurfsmuster


Zum Rheinwerk-Shop: IT-Projektmanagement
IT-Projektmanagement


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo

 
 


Copyright © Rheinwerk Verlag GmbH 2018
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 
Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern