1.总体概览
可以看出,实际上commons-logging和slf4j都是日志的接口,供用户使用,而没有提供实现。
log4j,logback等才是日志的真正实现
所以,基本上就是接口+具体实现的方式来使用
2.各个框架之间的集成
(1)slf4j与log4j1集成
1)maven
org.slf4j
slf4j-log4j12
1.7.12
2)jar包
说明:其中的slf4j-api是slf4j自身api;log4j是log4j自身的实现;slf4j-log4j12是slf4j和log4j的集成包
(2)slf4j与logback集成
1)maven
org.slf4j
slf4j-api
1.7.7
ch.qos.logback
logback-classic
1.1.3
ch.qos.logback
logback-core
1.1.3
2)jar
3.日志系统之间的切换
(1)log4j切换到logback
假如我们再代码中使用了log4j的api来进行日志输出,现在想在不更改代码的情况下,使之通过logback来进行实际的日志输出已经使用的jar包:log4j
使用案例:
import org.apache.log4j.Logger;
import org.junit.Test;
public class Log4jTest {
private static final Logger logger = Logger.getLogger(Log4jTest.class);
@Test
public void test()
{
logger.info("this is log4j");
}
}
替换步骤:
1)去掉log4j的jar包
2)添加以下jar包
1>log4j-over-slf4j(实现log4j切换到slf4j)
2>slf4j-api
3>logback-core(logback实现)
4>logback-classic
或者直接写maven依赖
1.7.7
....
org.slf4j
slf4j-api
${org.slf4j-version}
org.slf4j
log4j-over-slf4j
${org.slf4j-version}
ch.qos.logback
logback-core
1.1.3
ch.qos.logback
logback-classic
1.1.3
3)添加logback.xml配置文件
这样就实现了在不更改任何代码的情况下,将log4j切换到logback
(2)common-logging切换到logback
假如我们再代码中使用了common-logging的api来进行日志输出,现在想在不更改代码的情况下,使之通过logback来进行实际的日志输出已经使用的jar包:common-logging-1.1.3
使用案例:
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class JCLTest {
private static Log log = LogFactory.getLog(JCLTest.class);
@Test
public void test()
{
log.debug("Debug info.");
log.info("Info info");
log.warn("Warn info");
log.error("Error info");
log.fatal("Fatal info");
}
}
替换步骤:
1)去掉common-logging的jar包(其实不去也行)
2)添加以下jar包
1>jcl-over-slf4j(实现lcommon-logging切换到slf4j)
2>slf4j-api
3>logback-core(logback实现)
4>logback-classic
或者直接写maven依赖
org.slf4j
slf4j-api
${org.slf4j-version}
org.slf4j
jcl-over-slf4j
1.6.1
ch.qos.logback
logback-core
1.1.3
ch.qos.logback
logback-classic
1.1.3
3)添加logback.xml配置文件
这样就实现了在不更改任何代码的情况下,将common-logging切换到logback
4.不同日志系统之间的统一
由于项目中可能引入很多其他框架,而这些框架很有可能使用不同的日志框架,如log4j,logback,common-logging,java.util.logging等,而且就算相同日志jar的版本也有可能不同,造成项目日志体系非常混乱。
这个时候就希望统一使用某一种日志系统来实现,这个时候就可以使用如下配置:
org.slf4j
slf4j-api
${org.slf4j-version}
org.slf4j
jcl-over-slf4j
${org.slf4j-version}
org.slf4j
log4j-over-slf4j
${org.slf4j-version}
org.slf4j
jul-to-slf4j
${org.slf4j-version}
org.jboss.logging
jboss-logging
3.1.4.GA
在其中配置了几个适配器:log4j-over-slf4j, jcl-over-slf4j, jul-to-slf4j。
然后jboss-logging部分也进行了统一的版本控制(因为依赖传递会使用离项目最近的依赖)
剩下的就是配置logback即可
注意:jul需要额外执行一行初始化代码
SLF4JBridgeHandler.install();// jul to slf4j
5.日志系统之间的冲突
先总结一下相关jar包:
(1) log4j-over-slf4j, jcl-over-slf4j, jul-to-slf4j等这些类似from-over-slf4j命名的jar,都是从一种日志系统切换到slf4j
(2)slf4j-jcl,slf4j-log4j12等这些类似slf4j-to命名的jar,都是从slf4j切换到一种日志系统
所以很显然就有如下2中情况:
1) jcl-over-slf4j 与 slf4j-jcl 冲突
jcl-over-slf4j: commons-logging切换到slf4j
slf4j-jcl : slf4j切换到commons-logging
如果这两者共存的话,必然造成相互委托,造成内存溢出
2) log4j-over-slf4j 与 slf4j-log4j12 冲突
log4j-over-slf4j : log4j1切换到slf4j
slf4j-log4j12 : slf4j切换到log4j1
如果这两者共存的话,必然造成相互委托,造成内存溢出。