Application logging through SLF4J : Quick Reference

The detailed information on SLF4J is available on http://www.slf4j.org. The primary reason of writing the blog is that there is lot of information but usually people do not have the time to do into the details, hense a quick reference is required to get it going. So I would be trying to put forward all the important aspects.

The Simple Logging Facade for Java or (SLF4J) serves as a simple facade or abstraction for various logging frameworks, e.g. java.util.logging, log4j and logback, allowing the end user to plug in the desired logging framework at deployment time.

Reason
The obvious next question was that this is what JCL (Jakarta Commons Logging: http://commons.apache.org/) is all about. Why was the need for another facade? SLF4J does answer to few of drawbacks but there is no specific answer to why JCL was not modified. The drawbacks which are taken care as part of SLF4J are:
  • Parameterized log messages solve an important problem associated with logging performance.
  • Marker objects, which are supported by the org.slf4j.Logger interface.

Benefits
SLF4J supports an advanced feature called parameterized logging which can significantly boost logging performance for disabled logging statement. For some Logger logger, writing,
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
incurs the cost of constructing the message parameter, that is converting both integer i and entry[i] to a String, and concatenating intermediate strings. This, regardless of whether the message will be logged or not. One possible way to avoid the cost of parameter construction is by surrounding the log statement with a test. Here is an example.
if(logger.isDebugEnabled()) { logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); }
Assuming entry is an object, you can write:
Object entry = new SomeObject(); logger.debug("The entry is {}.", entry);
After evaluating whether to log or not, and only if the decision is affirmative, will the logger implementation format the message and replace the '{}' pair with the string value of entry. SLF4J uses its own message formatting implementation which differs from that of the Java platform. This is justified by the fact that SLF4J's implementation performs about 10 times faster but at the cost of being non-standard and less flexible.

Usage
As I prefer Maven, the first step is to include the SLF4J dependency

<dependency>
   <groupid>org.slf4j</groupid>
   <artifactid>slf4j-api</artifactid>
   <version>1.6.4</version>
  </dependency>

This would include the dependency but when you will build you would see messages
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
The reason for the messages is that the SLF4J uses the bridge between the core SLF4J and the other logging APIs. In absence of which it switches to no-operation (NOP) mode. If we dont want to integrate with any existing Logging API then the default implementation would need to be specified as below

<dependency>
   <groupid>org.slf4j</groupid>
   <artifactid>slf4j-simple</artifactid>
   <version>1.6.4</version>
  </dependency>

In case if you would like to use the existing logging API like log4j, the you would need to specify the binding through the Bridging API jar,

<dependency>
   <groupid>org.slf4j</groupid>
   <artifactid>slf4j-log4j12</artifactid>
   <version>1.6.4</version>
  </dependency>

Do not forget to also include log4j dependency also for it to work as expected.

Well I am done here with the facts for get it going with SL4J but making it a begining and not the end I would say that anybody looking for highly performant logging system should have a deeper dive into LogBack (http://logback.qos.ch).

The Marker interface is worth exploration along with LogBack. The LogBack logging API is by the same author of log4j and the extention to it. It is supposed to be 10 times faster than log4j apis.

Comments

Popular posts from this blog

Hibernate: a different object with the same identifier value was already associated with the session

BeanDefinitionStoreException: Failed to parse configuration class: Could not find class [javax.jms.ConnectionFactory]