Spring5.2.x-02 - log system

phenomenon

  1. In the Spring system, if the log is created by Spring JCL, the configuration of log4j will overwrite logback; Even if there are binders for logback and slf4j, log4j will be used preferentially; Others, such as the logs in mybatis, are printed with their own independent log components
  2. Spring boot uses logback by default. The logging technology is unified, and all use consistent log components

problem

  1. Why does Spring's logging system not interoperate with mybatis
  2. Why can spring boot unify logging technology

java log classification

Implementation class framework

  1. JUL: java's own log framework
  2. Log4j/Log4j2/LogBack: third party logging framework

Facade frame

  1. JCL: log oriented interface programming. The disadvantage is that it does not update and cannot solve the problem of historical hard coding. The selection range of log components is hard coding in the code
  2. Slf4j: the inconsistency of historical hard coded logs is solved through Adapter and Bridge; Through the binder, the scope of the log component can be configured by itself

Spring-JCL

spring4.x uses apache's jcl, 5 After X, the spring jcl of its own module is used, because the original jcl is not maintained, and spring jcl is maintained by itself

Spring JCL is enabled whenever you see log4j2, as shown in the following code snippet

	private static final String LOG4J_SPI = "org.apache.logging.log4j.spi.ExtendedLogger";

	private static final String LOG4J_SLF4J_PROVIDER = "org.apache.logging.slf4j.SLF4JProvider";

	private static final String SLF4J_SPI = "org.slf4j.spi.LocationAwareLogger";

	private static final String SLF4J_API = "org.slf4j.Logger";
		// As long as there is log4j
		if (isPresent(LOG4J_SPI)) {
			// With bridge & & with slf4j, slf4j can be enabled
			if (isPresent(LOG4J_SLF4J_PROVIDER) && isPresent(SLF4J_SPI)) {
				// log4j-to-slf4j bridge -> we'll rather go with the SLF4J SPI;
				// however, we still prefer Log4j over the plain SLF4J API since
				// the latter does not have location awareness support.
				logApi = LogApi.SLF4J_LAL;
			}
			else {
				// Use Log4j 2.x directly, including location awareness support
				logApi = LogApi.LOG4J;
			}
		}
		else if (isPresent(SLF4J_SPI)) {
			// Full SLF4J SPI including location awareness support
			logApi = LogApi.SLF4J_LAL;
		}
		else if (isPresent(SLF4J_API)) {
			// Minimal SLF4J API without location awareness support
			logApi = LogApi.SLF4J;
		}
		else {
			// java.util.logging as default
			logApi = LogApi.JUL;
		}

The basic principle is to see if you can use reflection to find the corresponding class. If you can't find it, it means that there is no running environment and there is no such class. Just set catch to false

As a result, the internal logs of spring and other external logs are not necessarily unified. There may be log4j2 in spring and jul in tomcat, which cannot be configured uniformly

Therefore, a log4j-to-slf4j bridge should be added (spring boot web is configured with a bridge by default, and logs can be unified as logback)

Switch from log frame to SLF4J Bridge

The package structure of the bridge is the same as that of the log framework to be bridged, and the classes are the same, so there will be no errors in compilation

It should use an agent. I don't know how to implement the details

  1. jul-to-slf4j: bridge from JDK logging to slf4j
  2. Log4j over slf4j: bridge from log4j1 to slf4j
  3. JCL over slf4j: a bridge from commons logging to slf4j

Switch from SLF4J to specific log framework binder

  1. slf4j-jdk14: bridge from slf4j to JDK logging
  2. slf4j-log4j12: bridge from slf4j to log4j1
  3. Log4j slf4j impl: bridge from slf4j to log4j2
  4. Logback classic: slf4j the bridge to logback
  5. Slf4j JCL: bridge from slf4j to commons logging

Added by chrisredding on Sat, 08 Jan 2022 14:16:47 +0200