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)
?
?
我就不翻译了,请看官方代码注释,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。
??
既然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加载问题?
?
一个很实际的问题是为啥要搞掉JCL? 引入slf4j的成本还是很高的,这篇文章有回答:
http://articles.qos.ch/classloader.html
http://articles.qos.ch/thinkAgain.html
?
总结,混乱的各种日志组合情况?
各种冲突情况总结:
?
参考桥接方案可以参考这篇文章:http://ihyperwin.iteye.com/blog/1455596