Log4j的简单思想
Log4j真的很简单,简单到令人发指的地步。不是要记录日志吗?那就给你一个Log,然后用Log来写东西就行了,先来一个完整类示例:
package test.robin;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class Test {
static Log log = LogFactory.getLog(Test.class);
public void log(){
log.debug("Debug info.");
log.info("Info info");
log.warn("Warn info");
log.error("Error info");
log.fatal("Fatal info");
}
public static void main(String[] args) {
Test test = new Test();
test.log();
}
}
我们从这个例子说起,先不要着急,很快就豁然开朗了。
Log4j默认把日志信息分为五个等级:
all<debug < info < warn < error < fatal<off
虽然可以自己添加等级,但是我觉得没有必要,五个够用了吧!你要写入信息的时候就把信息归为五个等级中的一个,然后调用相应的函数即可。分五个等级到底有什么用呢?日志信息到底写到哪里去了?“LogFactory.getLog(Test.class)”又是什么意思捏?接着往下看吧!(现在用这个Logger.getLogger(Test.class)或者Logger.getLogger(InitDicDao.class.getName()) )
继承思想:
Log4j的关键之处在于它的继承思想。也就是一个Log可以继承另外一个Log的属性(输出到哪里,日志等级,日志格式等等)。怎么继承?
Log4j是根据Log的名字来判断继承关系的,比如:
名字为“com.robin.lib”的Log就是“com.robin.lib.log”的parent,明白了吧!Log4j还有一个rootLogger,相当于Java的Object。Log4J中总是存在一个rootLogger,即使没有显示配置也是存在的,并且默认输出级别为DEBUG。其它的logger都继承自这个rootLogger(如果其他logger未单独定义其输出级别)了解Log4j的继承思想对学习Log4j很重要。
回过头来看“Logger.getLogger(Test.class)”这里的“Test.class”事实上传进去的是Test这个类的完整路径(包名+类名),“test.robin.Test”。这样如果存在“test”或者“text.robin”这样的Log那么Test这个Log就继承它,否则就继承rootLogger。
那具体的Log属性是在哪里定义的呢?
我们可以认为Logger.getLogger(Test.class)就是静态方法获取一个loger实例,这个实例的相关信息就是我们在配置文件里配置好的logger。(xml文件的logger标签)
每次我们在系统中取得logger时,并不是新建实例,这些实例是系统启动的时候就按照配置文件初始化好的(也可能时第一次引用的时候建立的,然后缓存其实例供以后使用,这部分还没有时间研究)。
关于logger的两点说明:
· 用同名参数调用Logger.getLogger(String name)将返回同一个logger的引用。故可以在一个地方配置logger,在另外一个地方获得配置好的logger,而无须相互间传递logger的引用。
· logger的创建可以按照任意的顺序,即,父logger可以后于子logger被创建。log4j将自动维护logger的继承树。