Organize the relationship between SLF4J, Logback, and Log4J along with their behavior

Let's sort out the differences and relationships between SLF4J, Logback, and Log4J along with their behavior.

What is SLF4J

Facade that realizes flexible switching of Java logging implementation is called SLF4J. ※SLF4J Facade means "the front of the building" and refers to one of GoF's design patterns, the "Facade pattern". The following is a class diagram of the Facade pattern (from TECHSCORE). facade2.gif

Java logging implementations include Log4J, Log4J 2, Logback, etc., but SLF4J is the contact point for these implementations. In the above figure, Facade is SLF4J, classA is Log4J, and classB is Logback.

I think the following official figure is easy to imagine. concrete-bindings.png In other words, from the application's point of view, SLF4J acts as an interface for the logging implementation, and Logback and Log4J are the logging implementation itself.

Power of SLF4J

Although it is said that it is the power of SLF4J, it becomes a Facade pattern (the power of the interface when it comes down to it), but let's check the advantages of using SLF4J with the following code.

App.java


public class App {
	public static void main(String[] args) {
		Logger logger = LoggerFactory.getLogger(App.class);
		logger.info("INFO LOG!!  Logger Class=" + logger.getClass());
	}
}

Use Logback for logging implementation

First, let's use Logback for the logging implementation. Add the following dependency to pom.xml to use Logback.

pom.xml


//In the case of Logback, this addition alone is due to Maven's transitive dependency, SLF4J(slf4j-api)And logback-core is also added to the dependency.
<dependency>
	<groupId>ch.qos.logback</groupId>
	<artifactId>logback-classic</artifactId>
	<version>1.2.3</version>
</dependency>

Build it and run App.java. Then, the following is output to the console.

Console.


23:53:02.124 [main] INFO co.jp.ars.App - INFO LOG!!  Logger Class=class ch.qos.logback.classic.Logger

You can see that Logback is used in the logging implementation, as shown in "Logger Class = class ch.qos.logback.classic.Logger".

Use Log4J for logging implementation

Next, let's use Log4J for the logging implementation. Add the following dependency to pom.xml to use Log4J.

pom.xml


//In the case of Log4J, this addition alone is due to Maven's transitive dependency, log4j-x.x.x.The jar is also added to the dependency.
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-api</artifactId>
	<version>1.7.25</version>
</dependency>
<dependency>
	<groupId>org.slf4j</groupId>
	<artifactId>slf4j-log4j12</artifactId>
	<version>1.7.25</version>
</dependency>

When using Log4J, log4j.xml (or log4j.properties) is required, so create log4j.xml on the classpath as follows.

log4j.xml


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
	<appender name="demo" class="org.apache.log4j.ConsoleAppender">
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%t %-5p %c{2} - %m%n" />
		</layout>
	</appender>
	<logger name="co.jp.ars">
		<level value="info" />
		<appender-ref ref="demo" />
	</logger>
</log4j:configuration>

Build it and run App.java. Then, the following is output to the console.

Console.


main INFO  ars.App - INFO LOG!!  Logger Class=class org.slf4j.impl.Log4jLoggerAdapter

There is "Logger Class = class org.slf4j.impl.Log4jLoggerAdapter", but the implementation of Log4jLoggerAdapter is as follows, and it can be confirmed that the actual state of Logger is "org.apache.log4j.Logger". (That is, you can see that Log4J is used for the logging implementation).

Log4jLoggerAdapter.java


public final class Log4jLoggerAdapter extends MarkerIgnoringBase implements LocationAwareLogger, Serializable {

    private static final long serialVersionUID = 6182834493563598289L;

    final transient org.apache.log4j.Logger logger;

    //~ Omitted ~

    public void info(String msg) {
        logger.log(FQCN, Level.INFO, msg, null);
    }

    //~ Omitted ~
}

In the case of SLF4J + Log4J, there is an intermediate adapter called SLF4J binding between them. The intermediate adapter is the above "Log4jLoggerAdapter". It is reprinted below. concrete-bindings.png

What are you happy about?

I just switched the logging implementation in the settings, and did not modify the application (App.java) that outputs logs at all. At the beginning, I mentioned that "Facade that realizes flexible switching of Java logging implementation is called SLF4J", but by using Facade called SLF4J, it is possible to flexibly switch logging implementation.

Logback, Log4j trends

By the way, the trend of logging implementation is not so different (as of December 6, 2018). キャプチャ.PNG

that's all.

reference

Recommended Posts

Organize the relationship between SLF4J, Logback, and Log4J along with their behavior
About the relationship between HTTP methods, actions and CRUD
Arbitrate the fight between PowerMock and jacoco with Gradle
Verification of the relationship between Docker images and containers
[Java] Check the difference between orElse and orElseGet with IntStream
The difference between programming with Ruby classes and programming without it
Relationship between Controller and View
Relationship between package and class
About the relationship between the Java String equality operator (==) and initialization. Beginners