Die jadice Codebasis macht an vielen Stellen Gebrauch von Logging um auf Probleme hinzuweisen und Nachvollziehbarkeit zu ermöglichen. Zur Nutzung von Logging existieren mehrere allgemein erhältliche Frameworks, die verschiedene Ansätze verfolgen und über unterschiedlichen Leistungsumfang verfügen.

Da die jadice document platform zur Einbindung in eine Gesamtapplikation konzipiert ist, legt sie sich nicht auf die Verwendung eines bestimmten Logging-Frameworks fest. Es existiert stattdessen die jadice Logging Framework Façade, die das Logging-System der integrierenden Applikation mitverwenden kann.

Die Auslieferung der jadice document platform stellt neben dem Standard JDK Logger zwei weitere Implementationen von Logging-Delegates zur Verfügung. Soll Log4J verwendet werden, fügen Sie die entsprechende Log4J-Implementation dem Klassenpfad der Anwendung hinzu. Zur Verwendung eines anderen Logging-Frameworks nehmen Sie statt dessen die entsprechende SLF4J-Implementation im Klassenpfad auf.

Eine detaillierte Beschreibung, wo die gewünschte Implementation des Logging-Delegates in der Auslieferung zu finden ist, ob und welche weiteren Schritte notwendig sind, entnehmen Sie bitte den folgenden Abschnitten.  

Die in der Auslieferung enthaltenen Logging-Delegates benötigen keine weitere spezifische Konfiguration. Eine Anpassung des Verhaltens des Ziel-Logging-Systems, zum Beispiel des Log-Levels oder ähnlichem, wird grundsätzlich über die Konfigurationsmöglichkeiten des jeweiligen Ziel-Logging-Systems gesteuert.

Ein Großteil aller Klassen der jadice document platform generiert Logging-Ausgaben. Wird eine dieser Klassen aktiviert – also durch den ClassLoader geladen – fordert sie beim jadice Logging-Framework einen Logger an. Mit der ersten Anfrage an das Framework wird dieses initialisiert und durchsucht den Klassenpfad nach dem gewünschten Ziel-Logging-System. Sollte diese Suche fehlschlagen, wird die folgende Nachricht auf der Kommandozeile ausgegeben:

Unable to initialize logging.

Eine weitere Nachricht auf der Kommandozeile stellt daraufhin nähere Angaben über den Grund des Fehlschlags zur Verfügung. Es existieren zwei Arten von Gründen:

  1. No logging delegation implementation on classpath

    Tritt diese Fehlermeldung auf, so wurde keine der beiden in den vorigen Abschnitten beschriebenen Logging-Delegates für Log4J oder SLF4J im Klassenpfad gefunden. Es muss daher die .jar-Datei für das gewünschte Ziel-Logging-System korrekt dem Java-Klassenpfad hinzugefügt werden wie in den vorhergehenden Abschnitten beschrieben.

  2. Initialization failure due to exception

    Diese Fehlermeldung deutet auf ein Problem des zugrundeliegenden Ziel-Logging-Systems hin und kann daher vielfältige Ursachen haben. Im Allgemeinen sollte die Dokumentation des entsprechenden Systems konsultiert werden.

    Die folgenden Beispiele geben Anhaltspunkte für einzelne Fehlersituationen.




Die einzelnen Logging-Systeme, mit denen jadice über die vorgestellte Façade verbunden werden kann, bieten jeweils spezielle Konfigurationsmöglichkeiten welche Meldungen im Log auftauchen oder ignoriert werden sollen.

Um geeignete Konfigurationen für das Logging aus der jadice document platform vornehmen zu können, sollen an dieser Stelle einige Hinweise gegeben werden. Da es sich bei Log4J um ein häufig eingesetztes Framework handelt, wird es für die im Folgenden aufgeführten Beispiele verwendet. Die erklärten Prinzipien lassen sich jedoch auf andere Frameworks übertragen.

Häufig – vor allem während der Implementationsphase – ist es gewünscht, für eine Gesamtapplikation nur die wichtigsten Log-Meldungen auszugeben, für einzelne Komponenten jedoch detaillierte Informationen zu erhalten. Die gebräuchlichen Logging-Frameworks unterstützen dieses Konzept indem eine Hierarchie von Loggern gebildet wird. Die Detailtiefe der erzeugten Log-Meldungen kann für Teile dieser Hierarchie festgelegt werden.

Die in jadice verwendeten Logger bilden ihre Hierarchie nach einer festen Konvention, die sich an den Klassennamen in denen der Logger verwendet wird orientiert. Bis auf wenige Ausnahmen trägt jeder Logger den voll qualifizierten Namen der Klasse, in der er benutzt wird. Dies ermöglicht eine sehr leichte Einschränkung der Logger-Konfiguration auf einzelne Klassen oder, über die Verwendung des Package-Namens, auf Teilkomponenten der jadice document platform.

Beispiel 4.4. Konfiguration des LogLevels für sämtliche jadice-Klassen unter Log4J

Beispielhaft soll an dieser Stelle gezeigt werden, wie der Detailgrad sämtlicher Logmeldungen der jadice document platform festgelegt werden kann ohne den Detailgrad für die integrierende Applikation zu beeinflussen. Das Beispiel verwendet Log4J mit einer XML-basierten Konfiguration. Da die Package-Namen sämtlicher jadice-Klassen mit dem konstanten Wert com.levigo. beginnen, wird dieser zur Konfiguration herangezogen.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//Apache//DTD Log4j 1.2//EN" 
    "http://logging.apache.org/log4j/docs/api/org/apache/log4j/xml/log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
 
  <!-- ... general configuration ... -->

  <!-- for all jadice classes, log only error messages -->
  <logger name="com.levigo" additivity="true">
        <level value="error"/>
  </logger>
  
  <!-- for all other Loggers, log info messages -->
  <root>
    <level value="info" />
    <!-- ... specify logging destination via log4j appender ... -->
  </root>
	
</log4j:configuration>

Anmerkung: Durch den Parameter additivity="true" wird festgelegt, dass der deklarierte Logger die Grundeinstellungen des in der Hierarchie über ihm liegenden Loggers erben soll – in diesem Fall ist dies der Root-Logger. Bei den geerbten Einstellungen handelt es sich im Besonderen um den Logging-Appender, der beispielsweise angeben könnte, dass sämtliche Nachrichten auf die Konsole geschrieben werden sollen. Der Log-Level könnte ebenfalls mitvererbt werden, wird hier jedoch überschrieben und auf error geändert.


Nachdem in den vorhergehenden Abschnitten darauf eingegangen wurde, wie das Logging der jadice document platform in die einbettende Applikation integriert werden kann, sollen nun noch einige Details dazu erläutert werden, in welchen Fällen Log-Messages produziert werden und wie in anderen Programmteilen darauf reagiert werden kann.

Wie es auch in den Ziel-Logging-Systemen allgemein üblich ist, verwendet das jadice Logging Framework verschiedene Kategorien um die Wichtigkeit und Tragweite einer Log-Message einzuordnen. Die Kategorien werden Log Levels genannt und durch die Façade auf geeignete Levels des Ziel-Logging-Systems abgebildet. Es existieren mehrere Log Levels, die den von Log4J angebotenen entsprechen.

Die folgende Aufstellung zeigt, in welchen Fällen die einzelnen Levels innerhalb der jadice document platform verwendet werden.

Der Log-Level DEBUG dient dazu, einzelne Detailabläufe nachzuvollziehen. Nachrichten, die unter diesem Level produziert werden, sind hauptsächlich zur Analyse von Fehlersituationen notwendig. Wird die jadice document platform auf diesen Level konfiguriert, so wird das durch die Anzeige eines entsprechenden Wasserzeichens auf der Viewer-Komponente verdeutlicht. Der Nutzer wird durch diese Meldung darauf hingewiesen, dass die Applikation umfangreiche Log-Meldungen ausgibt und daher nicht die reguläre Performance zu erwarten ist.

Für Produktivsysteme wird empfohlen, den Log-Level auf WARN zu setzen. So werden in Fehlerfällen die wichtigsten Informationen ausgegeben ohne dass im günstigen Fall die Performance beeinträchtigt wird.

Ereignisse, die ein gewissen Schweregrad darstellen oder die in integrierenden Anwendungen möglicherweise spezifische Reaktionen auslösen sollen, werden in jadice als Qualified Log-Events kategorisiert. Die jadice document platform propagiert diese Ereignisse an QualifiedLogListener Instanzen.

QualifiedLogEvents können in den Schweregraden WARN, ERROR und FATAL auftreten. Um QualifiedLogEvents zu erhalten, müssen Realisierungen von QualifiedLogListener an dem zentralen jadice Logging Mechanismus registriert werden. Dieser wird durch die Klasse LoggingConfiguration repräsentiert. Eine Instanz der LoggingConfiguration kann mithilfe der statischen Methode LoggingConfiguration.getGlobal() bezogen werden.

Die Registrierung eines Listeners kann für zwei unterschiedliche Gültigkeitsbereiche erfolgen: Es können entweder alle qualifizierten Log-Messages der genannten Levels angefordert werden oder nur solche, die auf dem zum Registrierungs-Zeitpunkt verwendeten Thread produziert werden.

Wird ein QualifiedLogListener benachrichtigt, so erfolgt dies in Form eines QualifiedLogEvents. Neben der tatsächlichen Nachricht, die auch variable Textfragmente enthalten kann, besitzt jedes QualifiedLogEvent eine eindeutige ID, die angibt um welchen Typ von Event es sich handelt. Tritt beispielsweise ein Fehler im Lesevorgang eines Formats auf, so könnte die ID allgemein darüber informieren, dass ein Lesefehler in einem Format auftrat, während die Log-Message zusätzlich den Namen des Formats angeben könnte. Diese Trennung erlaubt es, auf gleichartige Events in einer definierten Weise zu reagieren.

Die ID eines QualifiedLogEvents setzt sich zusammen aus zwei Teilen: Component ID und Event ID. Erstere bezeichnet den Teilbereich der jadice document platform, dem die Meldung entstammt. Letztere bezeichnet den Typ des Events. Die gesamte ID wird als String repräsentiert in welchem die beiden Teile durch einen Bindestrich (-) voneinander getrennt sind; weitere Bindestriche sind nicht enthalten. Die Trennung der ID in zwei Bestandteile hat den Vorteil, dass auf eine ganze Gruppe von Nachrichten in gleicher Weise reagiert werden kann. Die jadice document platform gruppiert beispielsweise solche Events, die im Zusammenhang mit dem Rendering auftreten, unter einer gemeinsamen Component ID. Über entsprechende Filterung und Anzeigelogik könnte somit bewirkt werden, dass sämtliche Warnungen oder Fehler, die im Zusammenhang mit dem Rendering auftreten, dem Nutzer in einer Message Box angezeigt werden.

Als Hilfestellung geben sämtliche Log-Messages, die an Instanzen von QualifiedLogListener verteilt werden, ihre vollständige ID auch auf der Konsole aus. Diese kann notiert und in einem QualifiedLogListener verwendet werden.

[jadice document platform Version 5.4.2.13: Dokumentation für Entwickler. Veröffentlicht: 2020-04-08]
loading table of contents...