Log4j是我们在Java中常用的一个log输出工具。Log4j命名的初衷也就是Log for Java的意思, JDK虽然从1.4以后也自带了一个Log的API,不过到目前为止我是没有见过什么人用过JDK自带的那个Log API,倒是用Log4j进行开发成为了事实上的标准。
Log4j从整体上来划分,其实是由三部分组成的,分别是级别(Level),输出器(Appender)与格式(Layout)。其中Level就是大家常用到的log4j的那几种,从Source上来看,一共分成8个级别,级别从低到高分别是ALL,TRACE,DEBUG,INFO,WARN,ERROR,FATAL,OFF。其中ALL输出的log最为详尽,表示把所有的log都输出,而OFF最少,少到没有了。除了ALL和OFF的剩下的6种级别是我们常用的级别,在开发的时候,我们常用DEBUG级别来进行调试,在中期测试的时候,采用INFO来查看一些重要的信息就OK了,在系统测试的时候把级别打开倒WARN来查看一些警告的信息或者错误信息。而在真实环境应用的时候。把log级别开到ERROR就足够了,因为在真实环境应用时,我们最关心的是错误的信息。log级别如果开的比较低的话,由于log输出过多,很可能会影响到应用程序的性能。
Log4j的初始化分为2种方式。第一种为Properties文件初始化,而第二种为xml文件初始化。在第一次系统使用到Log4j的类的时候,比如用到了Logger这个类的getLogger方法,这个方法的log4j的源代码如下










通过这段代码我们可以看出,首先系统会在classpath的根路径下寻找log4j.xml,如果找不到就去寻找log4j.properties文件进行初始化。
在初始化代码中。首先会寻找我们的Category配置,如果找到了Category以后,则把Category中所配置的Appender进行初始化,并且把这个Category与Appender进行捆绑。
还有一个疑问就是系统究竟怎么知道我当前这个log级别配置是什么呢。那其实也很简单。在Logger.getLogger方法中,在我们的org.apache.log4j.Hierarchy类中有如下代码
























可以看出,如果当前Class名没有在配置文件中的Category中配置的话,就会取子Category,如果子的取不到,那么就再取子Category的子的,一层层取下去,如果都取不到,就返回一个null,在我们控制台上,就会出来找不到Logger配置的系统异常输出流信息了。
在取子Category的时候,则是把classname按照从前到最后一个小数点进行substring后再看有没有匹配的,没有的话则循环下去,再截开头到倒数第二个小数点,直到找到或者把小数点都截光了还找不到为止。
对Log4j的这么一个简单的介绍,应该相信大家会对log4j的Level有了一个认识,对初始化文件的次序也有了认识,也知道了log4j是如何查找Category来输出的。以后如果有时间,我还将会写出其余的研究log4j的心得,包括如何自定义Appender以及自定义Layout出来。