This article is a series

Who exactly is a journal? Why use a logging framework?

You’ve all used system.out to debug output. It’s convenient to do this in a development environment, but it’s a problem to do it online:

  1. The system keeps running, producing more and more output, and the disk space gets progressively full
  2. Different businesses want to output logs in different locations
  3. In some cases, the log output needs to be dynamically adjusted to improve performance
  4. Automatically outputs log information, such as date, thread, method name, and so on

Obviously, system. out cannot solve our problems, but the problems we encounter must have been encountered before, and logging is no exception. Ceki is one of the great ones, and the entire Java logging System is almost involved in or deeply influenced by Ceki. Of course, the complexity of Java logging is partly due to this great guy.

Java logging feud

  • In early 1996, the European Security Electronic Markets Project team decided to write its own Tracing API. The API has evolved into a very popular Java logging package, Log4j (created by Ceki).
  • Log4j became part of the Apache Foundation project, and Ceki joined the Apache organization. Log4j has since become a near-standard for logging in the Java community. The Apache Foundation is also said to have suggested that Sun introduce Log4j into the Java standard library, but Sun declined.
  • In 2002, With the release of Java1.4, Sun introduced its own Logging library, JUL(Java Util Logging), which basically mimics Log4j’s implementation. Log4j was already a mature technology before JUL came out, giving it an advantage in terms of choice.
  • Later, Apache introduced Jakarta Commons Logging. JCL simply defines a Logging interface (which also provides a Simple implementation of Simple Log) that dynamically loads Logging components at run time. That is, in your application code, Simply invoke the Commons Logging interface, and the underlying implementation can be either Log4j or Java Util Logging.
  • Later (in 2006), Ceki was not comfortable with the way Apache worked and left the company. Then I created Slf4j(a Logging portal interface similar to Commons Logging) and Logback(an implementation of Slf4j), and went back to Sweden to create QOS company Logback. The QOS website describes Logback as follows: The Generic, Reliable Fast&Flexible Logging Framework is a Generic, Reliable, fast and flexible Logging Framework.
  • The Java Logging world is divided into two camps: Commons Logging and Slf4j.
  • Commons Logging has a large user base under the Apache tree. But there is evidence that patterns are changing. At the end of 2013, someone analyzed 30,000 projects on GitHub and counted the 100 most popular Libraries, which shows that Slf4j has a better development trend.
  • Apache rewrote Log4j 1.x in 2012-07 to create a new project, Log4j 2, which has all the features of Logback.
  • Today, the Logging framework has evolved into Slf4j as an API, which is implemented into logback and log4j.

Let’s pay our respects to the great god, haha:

So how do you gracefully use logging in a chaotic Java logging architecture?

In fact, under Ceki design system, logging is like Java JDBC, Servlet, etc., after defining the standard, the implementation can switch with each other, the problem is that the people who set the standard work out a lot of standards, JCL, SLF4j, etc., the official (Sun Company) is late and not to force, The development has now finally been unified by SLF4j in a clever way (bridging, binding, see below) with the following standard usage:



This diagram, taken from the SLF4J manual, simplifies the redundant parts and clearly shows how to use them:

Application references SLf4J-API (coded using SLF4j’s interface org.slf4j.logger rather than logback or log4j’s implementation)

  • Slf4j automatically looks for the logback implementation (slf4J is implemented by default)
  • Log4j: It is basically the same, but with an additional adapter layer, it refers to slf4J-log4j12.jar, officially known as concrete-bindings, which binds SLf4J-API to log4j final output logging

Specific dependencies are as follows

logback

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.2.3</version>
</dependency>Copy the code

log4j2

<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-slf4j-impl</artifactId>
  <version>2.12.1</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.12.1</version>
</dependency>Copy the code

Thanks to Maven’s dependency passing mechanism, we don’t need to show declarations that rely on slf4J-api.jar.

As you can see, log4j relies on log4J-slf4j-impl. Jar, which is the adapter layer shown in the figure above. The reason for this is that slf4J is not an official specification, so no one follows it (i.e. there is no native org.slf4j.Logger interface implemented in their own logging framework, such as log4j). The binding layer (log4J-slf4J-impl. Jar) uses log4j as a static lookup implementation (see a follow-up article on how this works). This enables logging using Log4j without relying on log4j (best practice for interface oriented programming, Ceki has used this philosophy to make SLF4J the standard for Java logging and a model for turning bad cards around.

The above section explains the concret-bindings idea, which is the essence of this article, readers must understand here, there is also a similar bridge idea, please continue to read.

summary

So far we have completed log integration, but is it really that simple?

First of all, is there any problem with such a chaotic logging system (SLf4J, JUL, JCL, Logback, log4j)? The answer is yes, various third-party libraries use different logging frameworks. If we rely on Spring, the default logging implementation of Spring (not Boot) is JCL, or if we already have a project that uses Log4j and want to use LogBack, do we need to change code class by class (there are migration tools available)? Can we use just one framework to handle JUL (java.util.logging), JCL (Jakarta Commons Logging), Log4j1, Log4j2?

The answer is yes. Ceki’s Slf4j provides a solution, known as Bridging legacy, which simply hijacks the above so that third-party log output is redirected to Slf4j, Finally, the upper API (coding) and the lower level of the unified log implementation (unified output log location, format). Let’s take a look at the diagram:



To be compatible with other logs, we need to reference the bridge package on the right: Xxx.over /to-slf4j.jar, XXX corresponds to the logging framework. In the case of logback, in addition to the logback dependency above, the following dependencies need to be introduced to ensure that all logs are bridged to SLf4J.

How to bridge?

Logback as follows

<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.2.3</version>
</dependency>
<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>jcl-over-slf4j</artifactId>
</dependency>
<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>jul-to-slf4j</artifactId>
</dependency>
<! Log4j-to-slf4j --> log4j-to-slf4j--> log4j-to-slf4j-->
<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>log4j-over-slf4j</artifactId>
</dependency>Copy the code

Log4j2 as follows

<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-slf4j-impl</artifactId>
  <version>2.12.1</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.12.1</version>
</dependency>
<! The following is a bridge package that uses log4j as the underlying implementation. You cannot bridge log4j or you will get infinite recursion.
<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>jcl-over-slf4j</artifactId>
</dependency><dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>jul-to-slf4j</artifactId>
</dependency>Copy the code

The SpringBoot project references some of the dependencies, so they are used slightly differently:

Logback as follows

<! -- LogBack as a built-in implementation is relatively simple to use -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency><! -- Importing missing bridge packets --><dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
</dependency>Copy the code

Log4j2 as follows

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter</artifactId>
   <! Use log4j2 to exclude logback dependencies -->
   <exclusions>
      <exclusion>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-logging</artifactId>
      </exclusion>
   </exclusions>
</dependency>
<! -- Spring has written a log4j2-starter but lacks a bridge package -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<! -- Importing missing bridge packets -->
<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>jcl-over-slf4j</artifactId>
</dependency>Copy the code

conclusion

The above two methods are the best to use in the project, other authors do not recommend using.

Finally, let’s see how SLf4J is used:

static final org.slf4j.Logger logger = LoggerFactory.getLogger(TestLog.class);
logger.trace("A TRACE Message");
logger.debug("A DEBUG Message");
logger.info("An INFO Message");
logger.warn("A WARN Message");
logger.error("An ERROR Message");Copy the code

This way we can switch logging implementations without changing the code, and it is easy to do, just switch dependencies as described above. Other usage details won’t be covered here, but stay tuned to future articles (best practices, profiles, principles, extensions, etc.).

If you think your writing is good, ask for attention, ask for praise, ask for forwarding, if you have any questions or mistakes in the article, welcome to leave a comment and discuss.

Please indicate the source of reprint.

Scan the public account to get the first updates



Reference:

Java- The lake of logs


www.slf4j.org/manual.html


www.slf4j.org/legacy.html


www.baeldung.com/spring-boot…