Calvin edited this page Nov 13, 2013 · 9 revisions

##Overview Slf4j已经成为Logger的事实标准API, 它只是一个外壳,而与Commons-Logging比,最突出的一点是大部分情况下它不需要写类似下面的代码。

   if(logger.isInfoEnabled()){
       logger.info("hello " + name);
   }

而后面的实现方面,java.util.logging, log4j ,logback,log4j2 一个比一个强。其中logback是log4j作者觉得log4j已经太烂不想再改了,重新写的一个实现。Log4j本来一统江湖好好的,后来被人说方法上太多同步修饰符,在高并发下性能太烂。Netflix的blitz4j就重新实现了一次log4j项目,去掉了大量的同步修饰符,不过其负责人自己说,新项目还是建议直接用logback,所以SpringSide就用了logback。

不过,后来apache社区又说,slf4j和logback都是log4j作者开的qos.ch公司的产品,日志是件很重要的事情,不应该操控在一家公司手里。所以又以纯社区驱动搞了log4j2,参考了logback,也做了一些自己的改动。不过现在还是漫长的beta版。

##Slf4j## slf4j只是一个日志外壳,需要你加入slf4j-jdk14.jar, slf4j-log4j12.jar或logback.jar,将日志调用转发到实际的日志框架。在classpath中有哪个jar包,slf4j就会选择哪个实现。如果错误的同时存在多个jar包,用哪个那就看运气了。

有些第三方的工具包,已经直接使用了log4j, common-logging 或 java.util.logging。如果我们最后决定使用log4j做最终输出,则需要放一个jcl104-over-slf4j.jar和 jul-to-slf4j.jar来假装成common-logging和java.util.logging的api,将日志请求转发给slf4j,slf4j再转发给log4j,此时还需要保证,classpath里没有正牌的common-logging.jar。 而原本直接使用log4j的就不需要做任何改动。

slf4j的api不需要写isWarnEnable(),是因为原来common-logging的API,早早就进行了一次字符串拼接,如果不需要打印就白白浪费了时间。而slf4j的代码如下,只在真正需要打印的时候才进行拼接。

logger.info("Hello {}", name);

注意如果参数本身的获取就需要消耗大量的时间,就依然需要用isXXEnable()把代码段圈起来。

   if(logger.isInfoEnabled()){
       logger.info("hello " + userDao.get(id).getName);
   }

##Logback## Logback其实和log4j还是一脉相承,最大区别是不支持log4j.properties这种properties文件了,必须写成XML形式。

###业务日志### 除了Error/Warning/Debug的系统日志,业务日志也可以用Logback编写,showcase中的logback.xml演示了这一点:

  • 因为业务日志的量可能比较大,也为了日志的后处理程序方便,设置了按小时分开文件,而且每个文件达到10M后自动滚动。而且对滚动出来的日志进行压缩以节约空间。
  • 重新设定了pattern,线程,Class之类的就不用打印了,甚至日期也不用打印了。
  • 重新设定了logger不继承root的appender,业务日志不写到console 和 rollingfile那里去。

###LogbackListAppender### 对日志输出的测试一向是头痛的事情,扩展出一个的Appender,临时附加到需要侦听的logger,使用一个List将所有log记录下来,并提供相应的获取消息的API。 springside test中封装了一个LogbackListAppender, 同样原理也可以为log4j或java.util.logging编写相应的appender。
典型的场景如下:

//add the mock appender  to logger
LogbackListAppenderappender = new LogbackListAppender();
appender.addToLogger(UserManager.class);
.....invoke some business code 
assertEquals("hello", appender.getFirstMessage());

###Logback进阶### TODO

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.