Best Practice for Logging

Use a logging framework

Using a logging framework is always recommended and shall be preferred over System.err.println or System.out.println! Logging output and layouting shall be configurable to the end user's needs.

If you are not sure why you should use logging, take a look at the article Logging 101.

Use slf4j as logging API

When using a logging framework there shall exist only be one single configuration point for logging, without loosing the flexibility of exchange the actual logging API to be used when running a 52°North application (either a webservice or when using an API within a custom application, like the OxFramework). SLF4J is more flexible and performant than commons-logging. Use it!

And switching is easy - there is a migration tool and also support for external legacy APIs that your application depends on.

Why slf4j provides better performance?

slf4j API provides a logging interface which enables late binding of message formatting. This actually means that log messages are formatted after the API has determined if the current log level is configured to be active. For example, if configuration is configured to INFO log level, the following String message would not be formatted (String formatting, or even concatenation with the + -operator really slows down the application):

LOGGER.debug("This message will not be {}", "formatted");

Tip: If you are using Java 1.5, use slf4j-api version 1.7.x. The Logger interface offers message formatting via Java's varargs mechanism instead of Object[].

Bindings

You can use several log APIs along with SLF4J. Just look for an appropriate SLF4J bridge. However, logback is the native SLF4J implementation and comes with great set of log appenders, is easy and flexible to configure. And it is more performant than log4j, so you should switch if you care about your software.

Binding logging APIs like log4j is just a matter of classpath setting. Ensure you have on your classpath:
  • slf4j-api-x.y.z.jar (note that you can use any version of slf4j, as long as the version of slf4j-api.jar and its binding match)
  • the jar of the chosen logging framework (like log4j-1.2.16.jar)
  • the jar providing the binding between slf4j and chosen logging framework (e.g. slf4j-logj12.jar)

Tip: SLF4J's native log implemenation logback provides a log4j.properties converter.

Note: Separating log settings in logback-test.xml and logback.xml files might cause some IDEs (at least eclipse) to use the first logback-test.xml found on classpath rather than using logback.xml at application start. This may confuse log configuration as tests often differ in configuration (do not log in files, and may have different log levels). To overcome this issue set the -Dlogback.configurationFile=/path/to/file parameter at startup to ensure the application picks up the right log settings file. See the logback jira for a more detailed discussion on this. (telling eclipse to just ignore all logback-text.xml files is just a matter of configuration: https://github.com/52North/SensorWebClient/issues/22#issuecomment-20515421)

logback examples

Adding slf4j and logback to Maven pom.xml file

<properties>
 <slf4j.version>1.6.4</slf4j.version>
 <logback.version>1.0.1</logback.version>
</properties>

<dependencies>

 <dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>${slf4j.version}</version>
 </dependency>

 <dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>${logback.version}</version>
 </dependency>

 <dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-core</artifactId>
  <version>${logback.version}</version>
 </dependency>

</dependencies>

If you want to use the Maven properties as shown below, add the following properties (containing example values):

<config.logger.fileappender.filepath>D:/logs</config.logger.fileappender.filepath>
<config.logger.level>DEBUG</config.logger.level>

Configuration of File and StdOut appender

This example comes with properties which can be filtered during a Maven build. However, besides Maven properties, you can define your own properties within the file itself (see the ${logFile} parameter).

The FILE appender is configured so that it keeps log files for 30 days in a separate directories. This leaves a clean logs directory.

Save the following content in a file ../src/main/resources/logback.xml.

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">

 <!-- refer to http://logback.qos.ch/manual/appenders.html -->

 <property name="logFile"
 value="${config.logger.fileappender.filepath}/${pom.artifactId}-${project.version}" />

 <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
 <file>${logFile}.log</file>

 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
 <fileNamePattern>${logFile}/%d{yyyy-MM-dd}.log</fileNamePattern>
 <!-- keep 30 days' worth of history -->
 <maxHistory>30</maxHistory>
 </rollingPolicy>

 <encoder>
 <pattern>
 %date %level [%thread] [%file:%line] %msg%n
 </pattern>
 </encoder>
 </appender>

 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
 <encoder>
 <pattern>
 %d{HH:mm:ss.SSS} [%thread] %-5level %logger{0} - %msg%n
 </pattern>
 </encoder>
 </appender>

 <logger name="org.n52" level="${config.logger.level}" />

 <root level="WARN">
 <appender-ref ref="FILE" />
 <appender-ref ref="STDOUT" />
 </root>
</configuration>

Metadata

Topic revision: r7 - 05 Jul 2013 11:57:07, HenningBredel - This page was cached on 25 Aug 2016 - 09:38.

This site is powered by FoswikiCopyright &© by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Wiki? Send feedback