Faster logging with SLF4J

Logging in Java has a long and obscure history. There are numerous APIs for logging, and there is for sure no answer which one is the best. Today, I started a project from scratch, which gave me the opportunity to try out SLF4J (Simple Logging Facede 4 Java). In most of my projects I have been using  Log4J so far. The switch was rather simple, anyways I would like to write down the most important steps here.

Why SLF4J

  • Log4J was initially created by Ceki Gülcü. After Log4J Ceki created SLF4J, so I guess he put everything he learned from Log4J into SLF4J.
  • SLF4J provides a nice way of creating short and easy to read logging statements in the code, that have only minor resource consumption if logging is turned off.
  • Some commonly used open-source projects use SLF4J compared with some of its provider bridges, in seldom cases this might struggle using the bridged logging APIs.
  • Last but not least: Why not? As previously mentioned, there is no best solution for logging, so why not trying alternatives.

How does it work

As the name suggests SLF4J is a logging facade that needs an actual logging implementation to be able to log anything at all. All the widespread logging solutions can be used by SLF4J. So you might use Log4J or JCL or even the Simple Implementation to do logging with SLF4J. In any case you will use the same API calls in your code (thus facade in the name).

Get the JARs

If you configure your JARs by copying them into some lib folder (I hope nobody is actually doing that any longer!), just go to their web page and download the latest versions of slf4j-api and the slf4j-{your favorite provide}. Don’t forget to put the JAR of your provider into the lib folder as well.

If you use maven or ivy, here is the sample configuration for SLF4J backed by Log4J. Please note, that the provider JAR will be automatically retrieved, so do not put it into your maven dependencies.

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

Let’s log

Logging with SLF4J is pretty straight forward. Just have a look at the example below. The second logging statement shows how the API should be used to avoid to String conversion for large objects if logging is turned off (or the level is lower). Check the SLF4J FAQ for further details on performance of (non) logging. If you are wondering if you should declare your logger as a static or instance variable, make sure to look at that consideration.

final static Logger logger = LoggerFactory.getLogger(Slf4jTest.class);

public void someMethod(HeavyObject object) {
    logger.debug("This is a simple debug message");
    logger.debug("HeavyObject is {}", object);
}