Each framework in various frameworks produced by Java (such as spring, etc.) will use different log systems. There will be certain problems with mixing multiple different logs in one jvm. Here we will sort out the common log frameworks in the Java system, introduce the relationship with each log framework centered on SFL4j, and introduce how to manage various log frameworks in the production environment.
1. Introduction to the interface
In the Java system, there are mainly two log system interfaces: slf4j and common-logging. There are many frameworks to implement, such as logback, log4j, etc.
Of course, although both are interfaces, the two can also achieve mutual log proxy output through bridge packets.
The log implementation of common-logging mounted is often log4j. During initialization, if there is no special specification for who to mount, it will be automatically instantiated in the order above. log4jLogger encapsulates log4j's logger and calls log4j when printing logs.
2. Bridge and being bridged in SLF4j
As an interface definition, slf4j can have many implementation frameworks at the bottom, and can also support other log implementations or frameworks to sfl4j. Its implementation is based on different bridge packages.
2.1 slf4j bridge
As an interface definition, there are many implementations below. The implementation principle is to perform initialization when obtaining ILoggerFactory. The initialization process binds the implementation object: load all classes that implement StaticLoggerBinder, and then obtain its singleton. When executing getLogger, the method of this singleton class is called to obtain the corresponding Logger object with specific implementation of logging functions. If there are multiple implementations, then bind one of them. This situation requires the removal of unwanted log implementation classes.
2.2 slf4j is bridged
The above figure shows how other log systems are connected to the slf4j log system. The basic principle is to proxy their respective log systems and output them to the sfl4j interface. For specific implementations, you can see the implementation of the bridge package. Basically, the original log implementation has been reimplemented, and the underlying method of actually calling log output is to slf4j.
Only jul is an exception, because Java comes with jdk implementation, and it is impossible to re-revise those classes. This place implements a slf4j handler based on the jul handler extension mechanism and then writes the log to slf4j. To take effect, you must also modify jre/lib/logging.properties to configure the new handler into the .handlers property. Generally, production won't be done like this.
2.3 Application
When applying actual projects, be careful that the bridged and the bridged package cannot appear at the same time, otherwise a dead loop will occur. For example, sfl4j bridges both log4j and log4j, then the log4j output call will point to slf4j, and slf4j points to log4j in this loop. Be sure to eliminate useless packages.
Production suggestions: The implementation of slf4j-api mounted only retains logback, and the upper log printing bridge can exist all pointing to slf4j.
Refer to the following dependencies, and all other log packages are excluded:
<dependencies> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.24</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.1</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.14</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>1.7.24</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>1.7.7</version> </dependency></dependencies>
3. Test code implementation and pom
Test code
public class TestLoggers { /** * slf4j-api -->slf4j-log4j12 -> log4j */ public void testSfl4jUpLog4j(){ org.slf4j.Logger logger = LoggerFactory.getLogger(TestLoggers.class.getName()); logger.info("Slf4j print use log4j"); } /** * slf4j-api --> slf4j-jcl --> common-logging-api (automatically to log4j)--> log4j */ public void testSlf4j2CommonLogging(){ org.slf4j.Logger logger = LoggerFactory.getLogger(TestLoggers.class.getName()); logger.warn("Slf4j print to common logging"); } /** * log4j-over-slf4j-api--> logback-classic */ public void testLog4j2Slf4j(){ org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(TestLoggers.class.getName()); logger.info("Log4j print to slf4j"); } /** * jcl-over-slf4j --> sfl4-api-->logback */ public void testCommonLogging2Sl4j(){ Log log = LogFactory.getLog(TestLoggers.class.getName()); log.info("common log to slf4j"); } /** * jul(console default)-->jul-to-slf4j-->slf4j-->logback * To add org.slf4j.bridge.SLF4JBridgeHandler in jre/lib/logging.properties */ public void testJul2Slf4j(){ java.util.logging.Logger logger = java.util.logging.Logger.getLogger(TestLoggers.class.getName()); logger.info("jul print to slf4j"); } public static void main(String[] args) { TestLoggers tester = new TestLoggers(); tester.testSlf4j2CommonLogging(); }}Test maven dependencies
<dependencies> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.24</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging-api</artifactId> <version>1.1</version> </dependency> <!--<dependency>--> <!--<groupId>org.slf4j</groupId>--> <!--<artifactId>jcl-over-slf4j</artifactId>--> <!--<version>1.7.14</version>--> <!--</dependency>--> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>1.7.24</version> </dependency> <!--<dependency>--> <!--<groupId>org.slf4j</groupId>--> <!--<artifactId>jul-to-slf4j</artifactId>--> <!--<version>1.7.7</version>--> <!--</dependency>--> <!--<dependency>--> <!--<groupId>ch.qos.logback</groupId>--> <!--<artifactId>logback-classic</artifactId>--> <!--<version>1.2.1</version>--> <!--</dependency>--> <!--<dependency>--> <!--<groupId>org.slf4j</groupId>--> <!--<artifactId>slf4j-log4j12</artifactId>--> <!--<version>1.7.5</version>--> <!--</dependency>--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jcl</artifactId> <version>1.7.24</version> </dependency> </dependencies>
The above article briefly discusses the use of Slf4j compatibility with other log systems is all the content I share with you. I hope you can give you a reference and I hope you can support Wulin.com more.