Goodbye Log4j

After seeing so many students in last four years, I have decided to write this article about the new loggers which are widely being used by the industry. Almost all the university students I have seen are familiar with Log4j 1.x (at least heard about it) but most of them even did not hear about SLF4J and Logback. The purpose of this article is introducing SLF4J and Logback and convincing you towards them. Before getting into the topic, be informed that Log4j 1.x is not being maintained after August 5, 2015 and Ceki Gülcü the developer of Log4j came up with the new tools SLF4J and Logback. Technically, Logback is an enhanced successor of Log4j and performs better than Log4j.

He did a good job, but we have to move forward.
SLF4J – Simple Logging Facade for Java, as the name suggests it provides a common interface for various Java loggers. The actual logger which you are using to log the events can be Logback, Apache Commons Logging, JDK 1.4 Logging or Log4j (I am sure, I miss some more loggers). Since it quickly becomes a standard, industry moves towards SLF4J. Especially most of the libraries and frameworks are migrating to SLF4J because they do not need to pack the logger within their own library but let the developers choose their desired logger implementation. For example, if you have slf4j-api.jar (API), slf4j-log4j12.jar (Connector) and log4j-1.x.jar (Implementation), your logs will be logged using Log4j. If you replace the slf4j-log4j12.jar and log4j-1.x.jar by slf4j-jdk14.jar, your logs will be logged using java.util.logging.


Remember that SLF4J is not an alternative for Log4j; it is only a facade. If you are developing a library or middleware, use SLF4J and the developers who use your library will provide any implementations according to their requirements. Using SLF4J as a facade to access other logger implementations provide two major advantages.

1: Loose coupling between your project and the logger
If you directly use a logger in your code, your code directly has access to the logger-specific classes. For example, if you use Log4j, an instance of logger should be retrieved in all the classes using the following statement.
import org.apache.log4j.Logger;
...
static final Logger LOGGER = Logger.getLogger(MyClass.class);
Suppose if your uncle suggests replacing Log4j by JDK logger for some strange reasons, you have to open all those 9,836 Java classes and replace the above statement by something for JDK logger.
If you used Log4j with SLF4J, the only thing you need is replacing Log4j and log4j-connector JAR files (or maven dependencies) by JDK logger connector library. You do not want to touch any source files in order to replace your logger.

2: Performance
SLF4J supports an advanced feature called parameterized logging which can significantly improve logging performance for disabled logging statement. For example, if you have a Log4j statement as shown below, your application will perform String concatenation regardless of whether the message will be logged or not.
int val = /* Definced the the runtime */;
logger.debug("Current value is " + val);
SLF4J provides parameterized logging methods which will construct the final String only if the log has to be logged.
int val = 10;
logger.debug("Current value is {}", val);

There is a disadvantage too: using a logging facade in a standalone application may slightly reduce the performance compared to native implementation. This is where Logback comes into the stage. Logback is a native implementation of SLF4J, so it performs better than other logger implementations. Studies have shown that using SLF4J + Logback performs better than SLF4J + Log4j (Reference). In my case, I always go with Logback for all of my standalone applications. In the company I am working for, we distribute the libraries only with SLF4J so that the clients have the choice on selecting the actual logger implementation and we do not need to distribute a logger along with our library.

Adding Logback to your project
Step 1:
Add the following dependencies. If you need the JAR files, download them from this link.
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j-version}</version>
</dependency>

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

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

Step 2:
Retrieve the logger instance using LoggerFactory.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
...
static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class);

Step 3:
If you do not have a custom configuration, Logback will continue with its default configuration. If you prefer to have a custom configuration, add logback.xml to the classpath with a similar configuration.
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">

    <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator" />

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

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>output.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>

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

</configuration>
For more details: Logback Configuration

Migrating from Log4j to Logback
Step 1:
Remove the Log4j dependencies and add the Logback dependencies.

Step 2:
Retrieve the logger instance using LoggerFactory.

Step 3:
If you have any fatal logs, change them to error because SLF4J does not support fatal. If you still want to use something similar to fatal, use markers.

Step 4:
Replace the log4j.xml by logback.xml. Use this online tool, convert your existing Log4j configuration to Logback.
Previous
Next Post »

Contact Form

Name

Email *

Message *