首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

log4j,slf4j,logback有关问题总结

2013-12-11 
log4j,slf4j,logback问题总结2013-12-10 17:48:56 [INFO] com.taobao.hsf.tlog.proxy.gather.impl.ProxyAg

log4j,slf4j,logback问题总结
2013-12-10 17:48:56 [INFO] com.taobao.hsf.tlog.proxy.gather.impl.ProxyAgentGather - ProxyAgentGather process jobs : 0, time cost : 0 mslog4j:WARN No appenders could be found for logger (org.apache.commons.httpclient.HttpClient).log4j:WARN Please initialize the log4j system properly.

?

?我的logback配置

<?xml version="1.0" encoding="UTF-8"?><!-- Logback Configuration.  --><configuration debug="false">    <appender name="STDOUT" />        <appender-ref ref="STDOUT" />    </root></configuration>

?

?

我完美的想法是logback作为最牛逼的日志组件,应该把之前的log4j等实现接管过来吧,怎么没有呢?我debug了一下,首先从出现警告的HttpClient开始,使用的是apache-commons-logging。其实只要搞懂这样代码做了什么事情,对日志系统就理解了。

?

   private static final Log LOG = LogFactory.getLog(HttpClient.class);

?

首先这行代码在commons-logging内部实际执行的是:

?

getFactory().getInstance(clazz)

?

?

问题1,commong-logging如何查找LogFactory?

我就不翻译了,请看官方代码注释,5种情况写得很清楚明白:

public Log4JLogger(String name) { this.name = name; this.logger = getLogger();}public Logger getLogger() { if (logger == null) { logger = Logger.getLogger(name); } return (this.logger);}?可以看到实际使用的org.apache.log4j.Logger.getLogger(name)来创建logger。由于我们的环境有log4j包,所以在我们的环境中第一个Log4j的Logger会创建成功。log4j logger创建之后会自动检测,如果没有发现log4j.properties等配置信息就会提示警告。

?

?

所以得出一个结论,出现问题是因为apache-common-logging不会自动发现logback。

??

问题3,logback和log4j如何桥接

既然apache-common-logging不能发现logback,那log4j和logback如何桥接呢?slf4j官方当然考虑到这个问题,参考官方文档:http://logback.qos.ch/bridge.html

使用log4j-over-slf4j,相当于ACL-->log4j-->slf4j-->logback打通。中间的log4j到slf4j,通过log4j-over-slf4j进行桥接。那么log4j-over-slf4j实际上如何桥接的呢?答案是直接在slf4j中定义同名的log4j的Logger包。这个问题参考:log4j-over-slf4的log4j Loger加载问题?

?

问题4,slf4j存在的价值??

一个很实际的问题是为啥要搞掉JCL? 引入slf4j的成本还是很高的,这篇文章有回答:

http://articles.qos.ch/classloader.html

http://articles.qos.ch/thinkAgain.html

?

总结,混乱的各种日志组合情况
    slf4j-log4j-<version>.jar: ?上层是SLF4J,底层通过log4j实现。slf4j-jcl-<version>.jar: 上层是SLF4J,底层还是通过Commons Logging的动态查找机制。jcl-over-slf4j-<version>.jar:上层是Commons Logging,底层交给SLF4J提供的静态绑定机制查找真正的日志实现框架。(注意:slf4j-jcl和jcl-over-slf4j不能同时出现在classpath)log4j-over-slf4j-<version>.jar: 上层是Log4J,底层交给SLF4J静态绑定要真正实现日志打印的框架。

?

各种冲突情况总结:

    slf4j-log4j,slf4j-simple不能同时出现,两个jar包都有sl4j的StaticLoggerBindder会冲突。log4j-over-slf4j和log4j不能同时出现,两个jar包都有org.apache.log4j.Logger会冲突。同理,jcl-over-slf4j和common-loggng不能同时出现。slf4j-jcl和jcl-over-slf4j不能同时出现,逻辑上进入无限递归。

?

参考

桥接方案可以参考这篇文章:http://ihyperwin.iteye.com/blog/1455596

热点排行