Search code examples
springlog4jlog4j2slf4j

What is Spring Boot Starter Log4J2


Well, I think the title describes the question. I know that I should use spring-boot-starter-log4j2 if I wanted to use log4j2 as my logging framework in spring. But my question is, how does it different from the plain org.apache.logging.log4j:log4j-api?

Looking at the compile time dependency of spring-boot-starter-log4j2, it has log4j-slf4j2-impl. Does that meant it use the SLF4J interface on top of log4j2 implementation? Will I still be able to use log4j2 specific features that's not available in SLF4J?

If the answer to previous question is no, is there any way I can configure my dependencies so I can use all of the log4j2 features? Because after I read the answer for this question: Is it worth to use slf4j with log4j2, I come into a conclusion that it is best to code directly to log4j2 API.

Thanks.


Solution

  • TL;DR: spring-boot-starter-log4j2 let's you select Log4j 2.x Core as logging backend, log4j-api let's you select Log4j 2.x API as logging API. The choice of API and backend are independent (cf. API separation).

    All Spring Boot starters are BOMs (bills of materials) that allow you to simplify your dependency list by grouping libraries together.

    One of the core features of Spring Boot is unified logging (cf. documentation): the major logging APIs (Java Util Logging, SLF4J, Log4j 2.x API) are configured to use the same backend. Therefore in your Spring Boot logs you'll find the logs generated by all libraries regardless of the API they use.

    The logging starters contain a logging backend and the bridges from foreign APIs to the native API of the backend:

    • spring-boot-starter-logging contains logback-classic (whose native API is SLF4J), jul-to-slf4j (a JUL to SLF4J bridge) and log4j-to-slf4j (a Log4j 2.x API to SLF4J bridge).
    • spring-boot-starter-log4j2 contains log4j-core (whose native API is Log4j 2.x API), log4j-jul (a JUL to Log4j 2.x API bridge) and log4j-slf4j2-impl (an SLF4J to Log4j 2.x API bridge).

    These are runtime dependencies that let you choose your logging backend. As you can remark, they don't (explicitly) contain any logging API.

    The choice of logging API is totally independent, you can choose (and should declare as compile dependency):

    • slf4j-api, one of the original APIs and the first one to offer "{}" interpolation. This is the best choice if you want to use Logback as backend, you won't be able to use all the features of Log4j 2.x Core (e.g. garbage-free logging or custom messages).
    • log4j-api, a younger API that contains most of the methods from SLF4J and many more. This is the best choice if you want to use Log4j 2.x Core as backend. If you use Logback you can still use most of its features. Some of the newest Logback features (e.g. a set of key-value pairs distinct from those in the MDC) can not be directly accessed from the Log4j 2.x API.