Java Log Component Series (iii) the relationship and debugging of LOG4J+LOGBACK+SLF4J
Blog Categories:Open Source Framework Background
As the open source framework is becoming richer, many open source frameworks use different log components. exist in a project, different versions, different frameworks coexist. Causing the log output to be extremely confusing. Although not fatal damage to the system, but it is obvious that the architecture is not good enough, the pursuit of the ultimate slightly inadequate.
Some of the standard common interface, the standard implementation, the existence of various bridges, the following let me establish the relationship between these frameworks.
From the above picture, we can see 4 parts.
Interface: All log implementations fit together, invoked with a unified interface.
Implementation: The current mainstream log implementation
Old log to SLF4J adapter: If you use SLF4J, but only want to use one implementation, want to log4j log system from Logback output, this is very useful.
SLF4J to implemented adapters: If you want to make a specific implementation of SLF4J, you need these packages.
The relationship between SLF4J and the old log framework
slf4j equals commons-logging, a common entry for various log implementations, depending on which jar is in the classpath to determine the specific log implementation library.
Logback-classic (default Logback implementation)
Slf4j-jcl.jar (Apache Commons logging)
Slf4j-logj12.jar (log4j 1.2.4)
Slf4j-jdk14 (java.util.logging)
transfer log calls to SLFJ for all Third-party class libraries or legacy code that use the legacy log APIs
Jcl-over-slf4j.jar/jcl104-over-slf4j:apache Commons logging 1.1.1/1.0.4, direct replacement can be.
LOG4J-OVER-SLF4J.JAR:LOG4J, direct replacement can be.
JUL-TO-SLF4J:JDK logging, you need to call Slf4jbridgehandler.install () at the beginning of the program to register the Listener reference Juloverslf4jprocessor, You can define the bean in applicationcontext.xml to implement initialization. Note that the original log4j.properites will be invalidated, logback on the site, and support conversion from log4j.properties to Logback.xml.
Advantage: The reason to transfer to Logback
SLF4J supports parameterized Logger.error ("account id:{} does not exist", userId), and Farewell to the IF (logger.isdebugenable ()) era.
In addition, the overall performance of Logback is better than log4j, Hibernate and other projects have adopted SLF4J: "Some key operations, such as the decision whether to record a log statement operation, its performance has been significantly improved." This operation requires 3 nanoseconds in the Logback, and 30 nanoseconds in the log4j. The Logback Creation Recorder (logger) is also faster: 13 milliseconds, and 23 milliseconds in log4j. More importantly, it takes only 94 nanoseconds to get the existing logger, while the log4j takes 2234 nanoseconds and the time is reduced to 1/23. "
Use of slf4j and Logback
1. If the log has more than 3 parameters, it needs to be written
Object[] params = {newval, below, above}; Logger.debug ("Value {} was inserted between {} and {}.", params);
Code comparisons for commons-logging and slf4j: Commons-logging Sample code:
Java code import org.apache.commons.logging.log; import org.apache.commons.logging.logfactory; public class testlog { log log = logfactory.getlog (testlog.class); public void print () { if (log.isdebugenabled ()) { log.debug (SQL); log.debug ("my name is " + name + ), i am " + age + " years old. "); } } }
Import Org.apache.commons.logging.Log;
Import org.apache.commons.logging.LogFactory;
public class Testlog {
log log = Logfactory.getlog (Testlog.class);
public void print () {
if (log.isdebugenabled ()) {
log.debug (SQL);
Log.debug (' My name is ' + name + ', I am ' + age + ' years old. ');}}
Sample code for SLF4J:
Java code import org.slf4j.logger; import org.slf4j.loggerfactory; public class testlogbyslf4j { Logger logger = loggerfactory.getlogger (testlogbyslf4j.class); public void print () { logger.debug (SQL); logger.debug ("My name is {}, i am {} years old. ", name, age); } }
Import Org.slf4j.Logger;
Import org.slf4j.LoggerFactory;
public class Testlogbyslf4j {
Logger Logger = Loggerfactory.getlogger (testlogbyslf4j.class);
public void print () {
logger.debug (SQL);
Logger.debug (' My name is {} ' I am {} years old. ', name, age);
}
2. Because the interior has been optimized, the authors believe that SLF4J's logger need not be defined as static.
3. Can set the cache after the bulk write log files (but if the server reboots, may lose records not written to disk)
4.MDC, with filter, the current user name and other business information into the MDC, in the log format definition can use the variable.
5.JMS Appender for alarms, DB appender for business logs, etc.
Production environment and elegant solutions
My factory project because of the use of a large number of open source architecture, so the project's log system is very confusing. There is a frequent case of log pack conflicts. For example: commons-logging-1.0.4,commons-logging-1.1.3,log4j,logback,jboss-logging,java.util.logging ... Different versions, different implementations. Before the author must configure at least three log4j,logback,commons-logging configuration files, in order to complete the log output. After studying the log system, I plant the pom.xml of Maven as follows
XML code <!--log-->
<dependency>
<groupId>Org.slf4j
</groupId>
<artifactId>Slf4j-api
</artifactId>
<version>${org.slf4j-version}
</version>
</dependency>
<dependency>
<groupId>Org.slf4j
</groupId>
<artifactId>Jcl-over-slf4j
</artifactId>
<version>${org.slf4j-version}
</version>
</dependency>
<dependency>
<groupId>Org.slf4j
</groupId>
<artifactId>Log4j-over-slf4j
</artifactId>
<version>${org.slf4j-version}
</version>
</dependency>
<dependency>
<groupId>Org.slf4j
</groupId>
<artifactId>Jul-to-slf4j
</artifactId>
<version>${org.slf4j-version}
</version>
</dependency>
<dependency>
<groupId>Org.jboss.logging
</groupId>
<artifactId>Jboss-logging
</artifactId>
<version>3.1.4.GA
</version>
</dependency><!--
<dependency>
<groupId>Commons-logging
</groupId>
<artifactId>Commons-logging
</artifactId>
<version>1.1.3
</version>
</dependency>
<dependency>
<groupId>Log4j
</groupId>
<artifactId>Log4j
</artifactId>
<version>1.2.17
</version>
</dependency>--
>
<!--log--> <dependency> <groupId>org.slf4j</groupId> <artifactid>slf4j-api</ artifactid> <version>${org.slf4j-version}</version> </dependency> <dependency> <gr Oupid>org.slf4j</groupid> <artifactId>jcl-over-slf4j</artifactId> <version>${ org.slf4j-version}</version> </dependency> <dependency> <groupid>org.slf4j</groupid > <artifactId>log4j-over-slf4j</artifactId> <version>${org.slf4j-version}</version> &L t;/dependency> <dependency> <groupId>org.slf4j</groupId> <artifactid>jul-to-slf4j</ artifactid> <version>${org.slf4j-version}</version> </dependency> <dependency> <gr Oupid>org.jboss.logging</groupid> <artifactId>jboss-logging</artifactId> <version> 3.1.4.ga</version> </dependency> <! --<dependency> <groupId>commons-logging</groupId> <artifactid>commons-logging</artifa ctid> <version>1.1.3</version> </dependency> <dependency> <groupid>log4j</gr
oupid> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> -->
Added a couple of important implementation adapters, LOG4J-OVER-SLF4J,LOG4J-OVER-SLF4J,JUL-TO-SLF4J. Then the jboss-logging section also has a unified version control. Delete and exclude all versions of the log4j,commons-logging at the same time. Adapter and specific log implementations, cannot coexist, otherwise the adapter does not take effect. In this case, we only have the Logback configuration file, because the log4j output has been delegated to slf4j (through log4j-over-slf4j), and SLF4J's default implementation is Logback.
Where June needs to execute a line of initialization code extra
Java code Slf4jbridgehandler.install ();//June to SLF4J
Slf4jbridgehandler.install ()//June to SLF4J
Common error debugging
"Error 1" is just a typical error, mainly the wrong red part of the second line
Log4j:warn No Appenders could is found for logger (COM.MCHANGE.V2.LOG.MLOG).
Log4j:warn Please initialize the log4j system properly.
Log4j:warn http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
This error occurs because no log4j configuration file is causing the. Add the Log4j.xml under the classpath and make some configuration. After configuration, start output
2014-02-25 09:30:31:743[info][com.mchange.v2.log.mlog.<clinit> (mlog.java:80)]-MLog clients using log4j Logging.
2014-02-25 09:30:31:780[info][com.mchange.v2.c3p0.c3p0registry.banner (c3p0registry.java:204)]-Initializing c3p0-0.9.1.2 [built 21-may-2007 15:04:56; debug? true; Trace:10]
That means back to normal.
。 For example, my configuration file is as follows
Log4j.xml
XML code
<?xmlVersion= "1.0" encoding= "UTF-8"
?><! DOCTYPE log4j:configuration SYSTEM "Log4j.dtd"
>
<log4j:configurationxmlns:log4j= ' http://jakarta.apache.org/log4j/'
>
<appenderName= "Console" class= "Org.apache.log4j.ConsoleAppender"
>
<layoutClass= "Org.apache.log4j.PatternLayout"
>
<paramName= "Conversionpattern" value= "%d{yyyy-mm-dd hh:mm:ss:sss}[%-5p][%l]-%m%n"
/>
</layout>
</appender>
<loggerName= "Org.springframework" additivity= "false"
>
<levelValue= "Info"
/>
<appender-refref= "Console"
/>