SLF4J vs Log4j vs Logback vs Log4j2: Key Differences and Integration

This article provides a comprehensive guide to Java logging frameworks, detailing the roles of SLF4J, Log4j, Logback, and Log4j2, comparing their architectures, showing how to configure each with XML files and Maven dependencies, and offering practical code examples and troubleshooting tips.

Vipshop Quality Engineering
Vipshop Quality Engineering
Vipshop Quality Engineering
SLF4J vs Log4j vs Logback vs Log4j2: Key Differences and Integration

Introduction

In Java projects, a logging system is essential for monitoring and debugging. The most common solutions are SLF4J, Log4j, Logback, and Log4j2. This article explains their purposes, differences, and how to integrate them.

SLF4J

SLF4J (Simple Logging Facade for Java) provides a unified API for logging but does not implement logging itself. It requires a concrete implementation such as Log4j, Logback, or Log4j2.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Slf4jDemo {
    private static final Logger LOG = LoggerFactory.getLogger(Slf4jDemo.class);
    public void printLog() {
        LOG.debug("debug message");
        LOG.info("info message");
        LOG.warn("warn message");
        LOG.error("error message");
    }
    public static void main(String[] args) {
        new Slf4jDemo().printLog();
    }
}

Without a binding (e.g., slf4j-log4j12.jar), SLF4J will fail with Failed to load class "org.slf4j.impl.StaticLoggerBinder".

Log4j

Log4j is a mature logging framework that writes logs to console, files, GUI components, etc. It was discontinued in 2015. Configuration is typically done via log4j.xml or log4j.properties.

import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;

public class Log4jDemo {
    private static final Logger LOG = LogManager.getLogger(Log4jDemo.class);
    public void printLog() {
        LOG.debug("debug message");
        LOG.info("info message");
        LOG.warn("warn message");
        LOG.error("error message");
    }
    public static void main(String[] args) {
        new Log4jDemo().printLog();
    }
}

Logback

Logback is the native implementation of the SLF4J API, created by the same author of Log4j. It offers better performance and lower memory usage.

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.util.ContextInitializer;

public class LogbackDemo {
    private static final Logger LOG =
        (Logger) LoggerFactory.getLogger(LogbackDemo.class);
    public void printLog() {
        LOG.debug("debug message");
        LOG.info("info message");
        LOG.warn("warn message");
        LOG.error("error message");
    }
    public static void main(String[] args) {
        new LogbackDemo().printLog();
    }
}

Log4j2

Log4j2 is the successor of Log4j, built on the LMAX Disruptor for high‑throughput asynchronous logging. It supports many configuration formats (XML, JSON, YAML, properties).

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

public class Log4j2Demo {
    private static final Logger LOG = LogManager.getLogger(Log4j2Demo.class);
    public void printLog() {
        LOG.debug("debug message");
        LOG.info("info message");
        LOG.warn("warn message");
        LOG.error("error message");
    }
    public static void main(String[] args) {
        new Log4j2Demo().printLog();
    }
}

Configuration Files

All three frameworks use XML configuration files with similar syntax. Example snippets:

<!-- Logback configuration (logback.xml) -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%-4relative[%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="debug">
        <appender-ref ref="consoleAppender"/>
    </root>
</configuration>
<!-- Log4j2 configuration (log4j2.xml) -->
<Configuration status="WARN">
    <Appenders>
        <Console name="consoleAppender" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS}[%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="com.example" level="info" additivity="false">
            <AppenderRef ref="consoleAppender"/>
        </Logger>
        <Root level="debug">
            <AppenderRef ref="consoleAppender"/>
        </Root>
    </Loggers>
</Configuration>

Maven Dependencies

Typical Maven pom.xml snippets for each combination:

<!-- SLF4J + Log4j (binding) -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
</dependency>
<!-- SLF4J + Logback -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
</dependency>
<!-- SLF4J + Log4j2 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
</dependency>

Integration Diagrams

SLF4J to Log4j binding diagram
SLF4J to Log4j binding diagram
SLF4J to Logback relationship diagram
SLF4J to Logback relationship diagram
SLF4J to Log4j2 binding diagram
SLF4J to Log4j2 binding diagram

Log Conflict and Troubleshooting

If multiple bindings (e.g., both slf4j-log4j12.jar and log4j-slf4j-impl.jar) are present, SLF4J prints a warning about multiple bindings and uses the first one found on the classpath. Adjust the classpath order or exclude unwanted bindings to resolve the conflict.

Comparison Table

Aspect

SLF4J

Log4j

Logback

Log4j2

Layer

Facade API

Implementation

Implementation (native SLF4J)

Implementation

Standalone use

Cannot

Yes

Not recommended

Yes

Maven artifact

org.slf4j:slf4j-api

log4j:log4j

ch.qos.logback:logback-classic

org.apache.logging.log4j:log4j-api

Config file

log4j.xml / log4j.properties

logback.xml

log4j2.xml (or json/yaml)

Binding

org.slf4j:slf4j-log4j12

Native (no extra binding)

org.apache.logging.log4j:log4j-slf4j-impl

Performance (200 M single‑thread logs)

101 s

13 s

97 s

Performance Test

A single‑thread benchmark of 2 million log statements shows Logback is the fastest, while Log4j and Log4j2 have comparable slower performance.

Conclusion

SLF4J provides a flexible façade that decouples application code from the underlying logging implementation. By selecting the appropriate binding and configuration file, developers can switch between Log4j, Logback, and Log4j2 without code changes, achieving both convenience and performance.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javalogginglogbacklog4jslf4jLog4j2
Vipshop Quality Engineering
Written by

Vipshop Quality Engineering

Technology exchange and sharing for quality engineering

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.