Weitere aktuelle Java-Titel finden Sie bei dpunkt.
 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index


14.5.2

Architektur



Die zentrale Komponente des Logging-Frameworks ist die Klasse LogManager. Sie erzeugt und verwaltet Exemplare der Klasse Logger, über die man letztendlich konkrete Einträge in ein Protokoll erzeugen kann. Auch beim Aufruf von Logger.getLogger() wird intern auf den LogManager zurückgegriffen.

Abbildung 14.4: Die Arbeitsweise des Logging-Frameworks
Abbildung 14.4

Die Grundeinstellungen des Logging-Frameworks sind in der Datei

  <java_home>/jre/lib/logging.properties
abgelegt. Sie definieren die globalen Einstellungen, die initial beim Starten einer Java Virtual Machine gesetzt werden. Durch Angabe der Property java.util.logging.config.file beim Start des Java-Interpreters kann man eine eigene Konfigurationsdatei für das Logging-Framework angeben:
  java -Djava.util.logging.config.file=myprops.properties TestApp
In der Konfigurationsdatei wird z. B. definiert, welche Einträge protokolliert und wie sie weiter verarbeitet werden.

Die Klasse Logger stellt für die Anwendung die Schnittstelle zur Generierung von Protokolleinträgen bereit. Zu jedem Logger-Exemplar gibt es so genannte Handler, die neue Protokolleinträge verarbeiten. Sie können diese nach Ebene oder benutzerdefinierten Kriterien filtern und sie anschließend an entsprechende Formatierer weiterleiten. Formatierer sind Exemplare der Klasse Formatter und haben die Aufgabe, Log-Records in ein konkretes Format zu übertragen (z. B. XML), um sie z. B. in einer Datei abzulegen.

Die Grundeinstellung des Logging-Frameworks erlaubt die Definition globaler Handler, die per Voreinstellung bei allen erzeugten Logger-Exemplaren registriert werden. Weitere Handler können nach Bedarf mit der Methode addHandler() in der Anwendung registriert werden.

Logger

Prinzipiell gibt es zwei Arten von Logger-Exemplaren: Benannte Logger haben den Vorteil, dass sie den Zugriff aus verschiedenen Programmmodulen vereinfachen, da der Zugriff lediglich über deren Namen erfolgt, der dem entsprechenden getLogger()-Aufruf übergeben wird. Bei der initialen Anforderung eines Logger-Exemplars mit einem bestimmten Namen wird es intern im LogManager im Namensraum gespeichert. Bei späteren getLogger()-Aufrufen mit demselben Namen wird dann lediglich das bereits initialisierte Exemplar zurückgeliefert.

Anonyme Logger hingegen werden zwar auch über die Klasse LogManager erzeugt, jedoch nicht in einem eigenen Namensraum verwaltet. Das heißt, jeder Aufruf von getAnonymousLogger erzeugt ein neues Logger-Exemplar.

Handler

Ein Handler nimmt die von der Anwendung erzeugten Protokolleinträge entgegen, kann Filterfunktionen durchführen und leitet sie anschließend in einem bestimmten Ausgabeformat an ein Ausgabemedium weiter. Zur Formatierung greift die Handler-Klasse wiederum auf Formatierer zurück, die selbst Exemplare der Klasse Formatter sind. Im Paket java.util.logging sind folgende Handler-Klassen definiert: Nach dem Abrufen eines Logger-Exemplars sind zunächst nur die globalen Handler verfügbar, die in der Konfigurationsdatei definiert sind. Durch die Methode addHandler() kann man zusätzlich eigene Handler bei einem Logger-Exemplar registrieren. Danach werden die Protokolleinträge sowohl von den globalen Handlern als auch vom eigenen Handler verarbeitet. Wenn man nicht möchte, dass die Protokolleinträge auch von den globalen Handlern verarbeitet werden, kann man mit der Methode setUseParentHandlers(false), unterbinden, dass die globalen Handler ebenfalls benutzt werden:
  Logger logger = Logger.getLogger("de.dpunkt.runtime");
  logger.setUseParentHandlers(false);
  logger.addHandler(new ConsoleHandler());
Über die Methode setLevel() kann man festlegen, bis zu welchem Log-Level Protokolleinträge von einem Handler verarbeitet werden. Alle Einträge, die unter dem angegebenen Level liegen, werden vom Handler ignoriert:
  Logger logger;
  ...
  logger.setLevel(Level.FINE);
Im obigen Beispiel wird FINE als Log-Level spezifiziert und somit die Protokolleinträge mit den Log-Levels FINER und FINEST ignoriert.

Über die Methode setFilter() kann man einen benutzerdefinierten Filter setzen. Ein solcher Filter implementiert das Interface Filter, das lediglich die Methode isLoggable() definiert. Ist ein Filter gesetzt, wird für jeden Protokolleintrag die Methode isLoggable() aufgerufen. Als Ergebnis liefert die Methode einen booleschen Wert, der anzeigt, ob der Protokolleintrag vom Handler verarbeitet werden soll. Folgendes Beispiel zeigt z. B. die Implementierung eines Filters, der nur Protokolleinträge akzeptiert, die in einem bestimmten Zeitbereich innerhalb eines Tages liegen (z. B. zwischen 8 und 16 Uhr):
  import java.util.*;
  import java.util.logging.*;

  class TimeFilter implements Filter {
    int start, end;
  
    public TimeFilter(int start, int end) {
      this.start = start;
      this.end = end;
    }

    public boolean isLoggable(LogRecord r) {
      Calendar cal = Calendar.getInstance();
      cal.setTime(new Date(r.getMillis()));
      int h = cal.get(Calendar.HOUR_OF_DAY);
      return (start <= h) && (h <= end);
    }

  }
Folgende Zeilen zeigen, wie der Filter gesetzt wird:
  Logger logger;
  ...
  Handler h = new ConsoleHandler();
  h.setFilter(new TimeFilter(8, 16));
  logger.addHandler(h);

Formatierer

Formatierer sind Exemplare der Klasse Formatter und formatieren einen Protkolleintrag in einem bestimmten Format. Das Paket java.util.logging bringt folgende Formatierer mit: Formatierer können einem Handler über die Methode setFormatter() zugeordnet werden:
  Logger l;
  ...
  Handler h = new ConsoleHandler();
  h.setFormatter(new XMLFormatter());
  l.setHandler(h);

Einstellungen

Folgender Ausschnitt zeigt die Einstellungen in der globalen Konfigurationsdatei des Logging-Frameworks:
# Globale Handler
handlers= java.util.logging.ConsoleHandler
.level= FINEST

# Einstellungen für FileHandler
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter

# Einstellungen für XMLHandler
java.util.logging.ConsoleHandler.level = FINEST
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
Die Einstellungen sind alle im Java-Properties-Format abgelegt. Über die Property handlers werden zunächst die globalen Handler über den vollqualifizierten Klassennamen angegeben. .level gibt anschließend den globalen Log-Level an, bis zu dem Log-Einträge verarbeitet werden.

Darunter folgen die Einstellungen für die einzelnen Handler inklusive der Formatierer, die für diese Handler benutzt werden. Für jeden Handler kann der globale Log-Level auf einen anderen Wert gesetzt werden.


 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index

Copyright © 2002 dpunkt.Verlag, Heidelberg. Alle Rechte vorbehalten.