日志二人转-Log4j与JCL小探
工作中系统出了问题,当需要检查错误来源时才发现系统日志记录非常不规范,很多问题没有合理的记下来,给后续排错带来麻烦。看了一下相关的日志体系,主要还是Log4j与JCL(ApacheCommonsLogging)的使用信息。
Log4j是Apache软件基金会的一个子项目,也是ApacheLogging项目的一部分(现在Log4j2的Beta版本也已经出来了)。用《ThePracticeofProgramming》作者BrianW.Kernighan和RobPike两位大师的话来说,用步步跟踪的debug方式太容易迷失在复杂数据结构的细节中了,而且效率也低,比较而言,想想往哪输出日志语句总比一步步的单步跟踪关键代码省事儿的多吧。Log4j就是希望建立起简单易用的日志体系。
整个Log4j项目分为三部分:loggers,appendersandlayouts,及日志机,附着器,以及日志格式。日志记录的过程就像一个旅行队要出发远行,loggers就是旅行队的队员,appenders就是记录行程情况的随行记者,而layouts就好比记者使用的书法形体(想想用草书写成的后果吧)。Loggers最大的特点就是其本身的层次体系,或者说是继承关系。每个logger都有一个用点号分隔的名字,名字结构较短的logger被看做是名字结构较长logger的祖先。比如被命名为“com.foo”的logger就是名为“com.foo.Bar”logger的祖先。继承关系有什么用呢?原来每个logger都可能被分配一个记录等级,包括:TRACE,DEBUG,INFO,WARN,ERROR和FATAL,并且等级依次升高,而日志的记录也是通过这几个等级的同名方法来记录的。当一个logger没有被分配等级时,它会从离它最近的祖先那里继承等级过来,继承关系向着最顶层的rootlogger进行。对于一个有了具体等级的logger来说,系统将只会将那些大于等于当前等级的日志操作记录下来,比如有:
//定义logger Logger logger = Logger.getLogger("com.foo"); //设置等级为INFO logger.setLevel(Level.INFO);
那么以下操作:
logger.trace("TRACE level."); logger.debug("DEBUG level."); logger.info("INFO level."); logger.warn("WARN level."); logger.error("ERROR level."); logger.fatal("FATAL level.");
将只有logger.info("INFOlevel.")及以后的语句会被我们的随行记者appenders成功记录下来,这也是Log4j的优势所在,在代码里嵌入不同等级的日志信息,通过改变日志等级来达到查看不同等级信息的作用。在项目开发中可以在配置文件Log4j.properties中设置设置等级为DEBUG,则日志中会记录调试及以上等级的信息,交付生产环境后,就可以改设INFO等级,减少不必要的数据,系统出现问题又可以重调为DEBUG等级。
而我们的随行记者appender一般都被安排在Log4j.properties中进行设置。
再来说说JCL(ApacheCommonsLogging)。这款日志组件同样出自——当当当当——我们的Apache,来自于ApacheCommons组件,Commons是Apache关注多角度可重用组件的一个项目。JCL既是一款轻量级的日志组件,同时也是服务于其他日志套件的独立抽象组件。说白了,就是提供统一的接口,而使用其它组件的实现。怎么样,有气魄吧,有点秦始皇横扫六国一统天下的野心。当然目前还是主要给Log4j、AvalonLogKit、JDK1.4的日志工具等,而其中最主要的还是给闻名于Java江湖的Log4j做代言啦!由此可见名人与广告的引力是双向的,即使再牛的品牌,即使付出再多的代价,也会向更牛的名人抛出橄榄枝的。为了唱好日志体系这场引人瞩目的二人转,同时也是给名人提供一套光鲜艳丽的出场服装,更是为了体现强强联手的霸气,JCL还专门在自己的UserGuide中拿出一块篇幅特别说明了自己对Log4j的支持。本来JCL的配置文件是commons-logging.properties,为了支持Log4j,可以在配置文件中说明Log4j配置文件的信息:
log4j.configuration=log4j.properties
之后还加上一句:如果不指定,默认就是log4j.properties。基本就是在展示蜜月照了。