Let's sort out the differences and relationships between SLF4J, Logback, and Log4J along with their behavior.
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).
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. 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.
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());
}
}
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".
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.
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.
By the way, the trend of logging implementation is not so different (as of December 6, 2018).
that's all.
Recommended Posts