Logging

When implementing a system, you will be given a choice of predefined logging frameworks using SLF4J, depending on your destination platform, and the log level you wish to implement for. All necessary JAR files will be copied into your project and made available.

Frameworks for Java SE/OSGi, JUnit Test Suite

Logback

Configuration via config file (logback.xml in source-catalog/classpath) or configuration object. See Configuration with Logback for details.

java.util.Logging

Configuration via config file (logging.properties located either in <jre>/lib/ or via command line: java -Djava.util.logging.config.file=“mylocation/logging.properties”) or configuration object. See

Configuration with JUL for details.

Log4J

Configuration via config file (/log4j.properties/) or configuration object. See

Configuration with Log4J for details.

System.out()

Configuration via configuration object as described at Configuration with SimpleLogger.

Logging for Blocks

Especially during debugging and testing your system, it is important that blocks log any relevant events. For that, you should use the provided logging methods, rather than System.out or System.err.

Logging is based upon SLF4J. The common superclass for block declares a SLF4J logger object, which you can use.

public int getDuration() {
    logger.debug("Timer with id {} started with {} milliseconds.", id, duration);
    ...
}

This is the recommended way of logging. The curly braces are replaced by the list of the last arguments. If you are interested why that is a good idea, read the discussion here. Alternatively, the block superclass declares some simple methods for logging on different levels:

  • logError(String m)
  • logWarn(String m)
  • logInfo(String m)
  • logDebug(String m)
  • logTrace(String m)
public int getDuration() {
    logDebug("Timer started with " + duration + " milliseconds.");
    ...
}

Log Level ERROR

This level should only be used for recording a failure that prevents the system from starting or running, i.e. the system is completely unusable. Error messages record that something went wrong, i.e. some sort of failure occurred and the system was either not able to recover or it was able to recover but at the expense of losing information or failing to honor a request.

It is crucial that:

  • these get logged,
  • sufficient information is provided to identify the cause of the problem,
  • logging is done in a standard way (to allow automatic monitoring).

For example, if the error is caused by a configuration failure, the configuration file name should be provided, as well as the property causing the problem.

Log Level WARN

A WARN message records that something in the system was not as expected. It is not an error, i.e. it is not preventing correct operation of the system or any part of it, but it is still an indicator that something is wrong with the system that the operator should be aware of, and may wish to investigate. This level may be used for errors in user-supplied information.

For example, a configuration file was downloaded (and it was readable), but it did not contain any entries, which may be unusual for this application.

Log Level INFO

INFO messages are intended to show what’s going on in the system, at a broad level. INFO messages do not indicate that something is wrong (use WARN or ERROR for that), and the system should be able to run at full speed in production with INFO level logging.

The following types of message are appropriate at INFO level:

  • Item / Component successfully initialized,
  • Transaction started, including some data about what kind of operation and parameters,
  • Transaction completed, including some data about what kind of operation and parameters.

Log Level DEBUG

DEBUG messages are intended to help isolating a problem in a running system, by showing the code that is executed, and the context information used during that execution. In many cases, it is that context information that is most important, so try to make this information as useful as possible.

The following types of message are appropriate at DEBUG level:

  • Entering a block/method/class with parameter,
  • Leaving a block/method/class with its return value,
  • Description of an action being taken (with context information),
  • Description of calculated values or made decisions (with context information).

Note that DEBUG messages are intended to be used for debugging in production systems, so they must be written for public consumption. Avoid any messages in a non-standard format.

If a DEBUG message is expensive to generate, you should guard it with a logger.isDebugEnabled() if check. Just make sure that nothing that happens inside that if statement is required for normal system operation.

Log Level TRACE

Trace messages are developer only and should be removed from code before going into production

Exceptions

Ideally, an exception should only be logged by the code that handles the exception. Code that merely translates the exception should do no logging.