Migrating from SLF4J

SLF4J is a logging API whose reference implementation is Logback, just like Log4j API is a logging API whose reference implementation is Log4j Core. In this page we will guide you through migrating from SLF4J to Log4j API as your logging API.

Instead of migrating your logging API, SLF4J, are you looking for migrating your logging implementation, Logback? Please refer to Migrating from Logback.

Struggling with the logging API, implementation, and bridge concepts? Click for an introduction.
Logging API

A logging API is an interface your code or your dependencies directly logs against. It is required at compile-time. It is implementation agnostic to ensure that your application can write logs, but is not tied to a specific logging implementation. Log4j API, SLF4J, JUL (Java Logging), JCL (Apache Commons Logging), JPL (Java Platform Logging) and JBoss Logging are major logging APIs.

Logging implementation

A logging implementation is only required at runtime and can be changed without the need to recompile your software. Log4j Core, JUL (Java Logging), Logback are the most well-known logging implementations.

Logging bridge

Logging implementations accept input from a single logging API of their preference; Log4j Core from Log4j API, Logback from SLF4J, etc. A logging bridge is a simple logging implementation of a logging API that forwards all messages to a foreign logging API. Logging bridges allow a logging implementation to accept input from other logging APIs that are not their primary logging API. For instance, log4j-slf4j2-impl bridges SLF4J calls to Log4 API and effectively enables Log4j Core to accept input from SLF4J.

To make things a little bit more tangible, consider the following visualization of a typical Log4j Core installation with bridges for an application:

Visualization of a typical Log4j Core installation with SLF4J, JUL, and JPL bridges
@startuml

frame "Compile time" {
  [Application] --> [Log4j API] : logs to

  [Log4j API] #Cyan

  [SLF4J] #Cyan

  [Library 1] --> [SLF4J] : logs to
  [Application] --> [Library 1] : uses
  [Application] --> [Library 2] : uses
  [Application] --> [Library 3] : uses
}

frame Runtime {

  [Log4j Core] <.. [Log4j API] : is implemented by
  [Log4j Core] <.. (log4j2.xml) : is provided to
  [Log4j Core] #LightGreen

  [JPL-to-Log4j] ..> [Log4j Core] : forwards to
  [JPL-to-Log4j] #Yellow

  [SLF4J-to-Log4j] ..> [Log4j Core] : forwards to
  [SLF4J-to-Log4j] #Yellow

  [JUL-to-Log4j] ..> [Log4j Core] : forwards to
  [JUL-to-Log4j] #Yellow

  frame JRE {
    [JPL] #Cyan
    [JUL] #Cyan
  }

}

[Library 2] --> [JUL] : logs to
[Library 3] --> [JPL] : logs to

[JPL] ..> [JPL-to-Log4j] : is implemented by
[JUL] ..> [JUL-to-Log4j] : is implemented by
[SLF4J] ..> [SLF4J-to-Log4j] : is implemented by

legend top right
  | <#LightGreen> | Logging implementation |
  | <#Yellow> | Logging bridge |
  | <#Cyan> | Logging API |
  | <size:18><U+2192></size> | Compile-time usage |
  | <size:18><U+21E2></size> | Runtime usage |
endlegend

@enduml

Migrating

If your application or library logs using SLF4J, you can migrate it to Log4j API as follows:

  1. Remove org.slf4j:slf4j-api dependency

  2. Follow the instructions shared in the "Getting started" page for installing log4j-api and using it

  3. Search for org.slf4j usages in your project and replace them with Log4j API equivalents

    For an exhaustive list of code changes that need to be carried out, refer to the SLF4J to Log4j API migration OpenRewrite recipe. This you can use to

    1. either manually follow the described migrations,

    2. or run OpenRewrite to automatically migrate the code.

    org.slf4j.LoggerFactory

    Replace its usages with org.apache.logging.log4j.LogManager. Note that LogManager.getLogger(Foo.class) can be simplified as LogManager.getLogger(), if Foo is the enclosing class of the field.

    org.slf4j.Logger

    Replace its usages with org.apache.logging.log4j.Logger. Since SLF4J’s Logger is almost a parent of Log4j’s Logger, most methods should work without any changes.

    org.slf4j.MDC

    Replace its usages with org.apache.logging.log4j.ThreadContext.

  4. If you use @Slf4j from Lombok, you need to replace them with @Log4j2 instead.

At this stage, you should have your application or library logging using Log4j API.

If it is a library that you migrated,

then you don’t need to take any extra steps. Unlike applications, libraries should be logging implementation agnostic. That is, libraries should log through a logging API, but leave the decision of the logging implementation to the application.

If it is an application that you migrated, and you are not using Log4j Core as your logging implementation,

then you can consider doing so. Certain Log4j API features (e.g., garbage-free logging) require an end-to-end setup which is mostly possible using Log4j API in combination with Log4j Core.

See Installation for installing Log4j Core.
If you are using Logback, refer to Migrating from Logback.