Motivation Log4J (I) • Fehlersuche gehört zum Geschäft jeden Entwicklers • ebenfalls sehr wichtig: – Informationen über den Zustand des Programms oder – wichtige Ereignisse in geregelter Weise an System weiterzugeben • Aufgaben Logger: – Variablenwerte kontrollieren – Ablauf einer Anwendung verfolgen Log4J 1 Motivation Log4j (II) • Fehlersuche mit Debugger erledigt: Problem, wenn nicht verfügbar (JSP) • Lösungsversuche oft mit System.out.print(...) • besser Log4J, da log-Statements: – ohne Performancekostenerhöhung im Quelltext verbleiben und an Kunden mitgeliefert werden können bei Bedarf aktivierbar – zur Laufzeit der Anwendung level- und loggerweise an- und ausschaltbar – Ausgaben zur Laufzeit konfigurierbar – Ausgaben in unterschiedlichster Weise möglich (Ausgabeort/Ausgabeformat) Log4J 2 Das Projekt • Open Source Projekt, um Log-Statements in eine Anwendung zu bringen (de facto Standard) • aus Apaches Jakarta Projekt • einsetzbar ab JDK 1.1 • Ziele: – keine (grossen) Performanceverluste durch Loggen – minimaler Konfigurationsaufwand – klassifizierbare Informationen • Hauptbestandteile: Logger, Appender, Layouts Log4J 3 Klasse Logger (I) • Kernkomponente: Klasse Logger (ehemals Category) • kann Entwickler als private statische Variable in Anwendung bereitstellen und mit entsprechenden Methoden nutzen private static Logger logger = Logger.getLogger(“test.Sample“); logger.debug(“irgendwas“); Log4J 4 Klasse Logger (II) • Klassenname als Loggername ist Konvention – so Logging für einzelne Klasse oder package einund ausschalten • Log-Statements bleiben i.d.R. im Code --> Gesamtperformance soll sich nicht verschlechtern if (logger.isDebugEnabled() == true){ logger.debug(“irgendwas“); } • if-Statement als Performance-Wrapper Log4J 5 Log-Level(I) • ALL: niedrigste Priorität, Loggen anschalten • DEBUG: feingranulare Informationsereignisse, um Anwendung zu debuggen • INFO: informierende Nachrichten, die groben Ablauf einer Anwendung aufzeigen • WARN: potentiell nachteilige Situationen • ERROR:Fehler, Anwendung läuft evtl. weiter • FATAL: ernster Fehler --> meist Abbruch der Anwendung • OFF: höchste Priorität, Loggen abschalten • aufsteigende Priorität der Level (ehemals Priority) : ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF Log4J 6 Log-Level (II) • Tritt Logfall ein (Logaufruf): Aufruf Printmethoden der Loggerinstanz, also debug(), info()... • Printmethode bestimmt Level des Logaufruf – z.B. c.info(...) ist Logaufruf auf Level INFO • Loggen ist möglich, wenn Level des Logaufrufes höher oder gleich dem seines Loggers ist – z.B. c.info(...) Logger hat Level WARN c.info() ignoriert Log4J 7 Log-Level (III) • Logger bilden durch “.“ getrennte hierachische Struktur z.B. java.sql.Connection und besitzen bestimmten Level • Level nicht explizit gesetzt von nächst höherem Logger geerbt – z.B. java: INFO, sql: keine Zuweisung sql = INFO • Ansonsten: Logger der Klasse explizit gewünschten Level zuweisen – z.B. java: INFO, sql: WARN sql = WARN – alle Kinder von sql erhalten nun Level von sql und nicht von java Connection = WARN Log4J 8 Appender (I) • log-Statements zur Auswertung an unterschiedliche Ziele verschickbar • Appender legt fest, wohin (Datei, Konsole, DB, Auswertung remote) • jedem Logger-Objekt sind ein oder mehrere Appender zuordenbar • Appender wird bei Konfiguration Layout-Pattern übergeben – optische Aufbesserung – verbesserte Fehlersuche Log4J 9 Appender (II) • Vererbungskonzept auch hier angewandt • Kinder des Loggers erben automatisch alle Appender des Vaters • väterliche Appender werden aber nicht ersetzt, wie bei vererbtem Log-Level, sondern ergänzt – z.B. Vater schreibt auf Konsole, Kind hat FileAppender Kind schreibt auf Konsole und in File – Vererbungsmechanismus mit Logger-Attribut additivity = false unterbindbar Log4J 10 Konfiguration (I) • Ziel: Logging-Verhalten zur Laufzeit konfigurieren – an zentraler Stelle der Anwendung richtiges Startverhalten (Appender/Layout) einstellen – für Anbindung an Konfigurationsdatei sorgen • BasicConfigurator – ohne File, belegt System mit sinnvollen Startwerten (Loggen auf Konsole) • PropertyConfigurator – bezieht Daten aus Property-Datei • DOMConfigurator – ähnlich P. Dateiformat XML Log4J 11 Konfiguration (II) • Zuweisung von Logging-Eigenschaften (Appender, Layout) vollständig gekapselt • einmaliges Aufrufen von configure() erledigt Aufgaben • dateibasierte Konfiguratoren benötigen noch zusätzlich URL-spezifischen Parameter – z.B. PropertyConfigurator.configure(“c:\\test.lcf“) Log4J 12 Property-Datei #obersten Logger auf DEBUG setzen, Appender: A1 log4j.rootLogger = DEBUG, A1 #A1 ist ConsoleAppender Ausgabe auf Console log4j.appender.A1 = org.apache.log4j.ConsoleAppender #A1 verwendet ein Pattern Layout log4j.appender.A1.layout = org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern = [%d / %p / %c ] - %m%n%n Log4J 13 Log4J vs. JSR47 (Sun‘s Log API) • Ähnlichkeiten in Namensgebung (Klassen: Logger, Level) • unterschiedlicher Funktionsumfang (100 Klassen Log4J, 16 JSR47) • Konzept hierarchischer Logger ähnlich • Log4J viele Appender, JSR 3 Handler • Log4J ab JDK 1.1, LSR erst ab 1.4 • Log4J gereift und robust, performanter • Portierungen für C/C++, Pyhton, .NET Log4J 14 Zusammenfassung • • • • • • gute Funktionalität (Ausgabeziele, Level) Handhabung (Programmierung, Konfiguration), Integrierbarkeit in eigene Anwendungen gute Erweiterungsmöglichkeiten in existierenden Systemen verwendet (JBoss) GUI-basierte Tools vorhanden (Chainsaw, LogFactor5) • momentan besser als JSR47, Wechsel allerdings recht unproblematisch Log4J 15 Quellen • Wille, S., Go To Java Server Pages, Addison-Wesley, München, 2001 • Evertz, M.: Logger Dir Einen, Javamagazin, 11/2002, S.23 • http://jakarta.apache.org/log4j/docs/documentation.html • http://www.linuxmagazin.de/Artikel/ausgabe/2002/04/coffee/coffee.html • http://www.zdnet.de/builder/artikel/program/200208/javalogging-api_01-wc.html • http://www.jguru.com/faq/Log4j/ • http://www.jsp-develop.de/knowledgebase/print/736/ Log4J 16