Logging

Introduction

Logging and interpreting log messages can be an invaluable tool during the debugging and testing of your applications and in general provides detailed information on the execution of code. JDT provides a small logging package com.archimed.log that is used internally by the other JDT packages to output log messages during the execution of various methods of JDT classes.

Because JDT is normally integrated into other applications, application developers may have already chosen an existing logging framework like for example Apache Log4J or the java.util.logging package. The com.archimed.log package does not make use directly of any existing logging framework but can be set up so that it delegates the generation of log statements to an underlying existing logging framework. In the absence of an existing logging framework, the package can generate log statements on its own.

Logging with JDT’s internal logging framework

By default, JDT is configured to use one instance of com.archimed.log.DefaultJdtLogger for writing all log messages from all the JDT classes. The DefaultJdtLogger class defines seven log levels comparable with the Log4J log levels. The default level is OFF which means no log messages are written. The DefaultJdtLogger class holds a reference to a single OutputStream to which all log messages are written and which is initialized to System.out.

For example, to set the output level to the ERROR level and to direct the output of log messages to System.err :

DefaultJdtLogger.setLevel(DefaultJdtLogger.ERROR);
DefaultJdtLogger.setOutputStream(System.err);

Integrating with an existing logging framework

The logging mechanism in JDT is based on two interfaces:

com.archimed.log.JdtLoggerFactory
com.archimed.log.JdtLogger

The JdtLoggerFactory interface defines one method that returns references to JdtLogger implementing classes. The JdtLogger interface defines the necessary methods for logging messages at various log levels. A JdtLoggerFactory can be specified with the static setJdtLoggerFactory method of the com.archimed.dicom.Jdt class.

All JDT classes that use logging retrieve a reference to a JdtLogger by first retrieving the current JdtLoggerFactory and then retrieving a JdtLogger by using the getJdtLogger class of the factory.

For example the DicomObject class has declared:

protected JdtLogger log = Jdt.getJdtLoggerFactory().getJdtLogger(DicomObject.class);

By default, the installed factory is the com.archimed.log.DefaultJdtLoggerFactory which keeps a reference to a single com.archimed.log.DefaultJdtLogger instance. This factory can be replaced by another factory that returns different implementations of JdtLogger.

In general to replace the default logging with logging from an existing log framework, one has to:

  • create a new factory that implements JdtLoggerFactory and that returns instances of JdtLogger implementing classes

  • create a new JdtLogger implementation, making use of the logging functionality of the existing log framework

Example: Using Apache Log4j

As an example of replacing the default logging, two classes are provided that enable JDT to use Log4j as the logging framework:

com.archimed.dicom.examples.Log4jLoggerFactory
com.archimed.dicom.examples.Log4jLogger

The two classes wrap functionality of the org.apache.log4j.Logger class. To enable JDT logging using these classes the default factory must be replaced with this new factory:

Jdt.setJdtLoggerFactory(new Log4jLoggerFactory());

From that point on , JDT will log messages according to the current Log4j configuration. For example, to enable DEBUG level logging on all classes of JDT one would typically do:

org.apache.log4j.Logger.getLogger("com.archimed").setLevel(org.apache.log4j.Level.DEBUG);