Log4j是Apache提供的一个开源日志操作包,其功能十分强大,操作极其简单,所以很多开源项目和企业级开发过程中都会选择它作为日志记录工具。
Log4j主要由三个重要组件组成:
1)Logger,核心组件代表了log4j的日志记录器,能够对日志信息进行分类筛选,决定什么日志信息被输出、什么日志信息应该忽略;
2)Appender,指定日志信息输出地方,可以是控制台、文件、数据库等;
3)Layout,指定日志信息输出格式。
log4j一共有五种日志级别:fatal、error、warn、info、debug。
Log4j提供了一个root logger作为所有logger的“祖先”(如同Java中的Object类),它永远存在,且不能通过名字引用,而是Logger.getRootLogger()方法取得。如果子类logger没有定义日志级别,则将继承父类的日志级别,如果定义了,就不会继承父类日志级别。
默认情况下,子类logger会继承父类所有的appender,把它们加入到自己的appender。如果把子类logger组件的additivity标识设置成false,那它就不会继承父类appender。默认additivity值为false。
2、基本使用方法
layout表示日志输出的格式,log4j支持的layout有TTCCLayout, HTMLLayout, PatternLayout, SimpleLayout和XMLLayout,常用的是PatternLayout,性能最好的是SimpleLayout(因为它足够 simple)。PatternLayout支持的模式选项说明如下:
%m:输出日志消息内容.
%p: 输出日志事件的priority(DEBUG、INFO等).
%r: 输出自程序启动后到当前的时间差,似乎用处不大。
%c: 输出logger名字空间的全称,如果加上{<层数>}表示列出从最内层算起的指定层数的名字空间
%t: 输出当前的线程名,一些多线程环境中或许用的上。
下面的参数有性能问题,对性能要求高的场景需要做好度量。
%d: 输出时间,可以指定时间格式,比如 [%d{yyyy-MM-dd HH:mm:ss}]等。
%C: 输出调用日志类方法者的fully-qualified类名,默认是输出全路径(也就是包名+类名),也可以限定{n}表示输出全称的最后n个部分,比如”com.foo.SomeClass”, 模式%C{1}将输出”SomeClass”。
%M:输出调用日志类方法者的方法名。
%F: 输出调用日志类方法者的文件名。
%L: 输出调用日志类方法者的行号。
%l: 输出调用日志类方法者的源代码位置,它是%C.%M(%F:%L)的简称。
上面的输出选项中,和调用者位置相关的选项会有性能问题。这是因为,log4j调用 Throwable.getStackTrace()来得到整个调用过程的栈信息,自底向上比较调用的函数名,直到找到日志函数(debug等)的上一级函数名,然后通过反射得到一系列位置信息。这个过程显然要比其他几项的取得复杂的多,但它对分析日志查找问题却是很有用的。
log4j中的filter可以指定appender要输出的日志等级范围下面是使用filter的一个样例:
<appender name="TRACE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%t] %-5p %c - %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="levelMin" value="DEBUG" />
<param name="levelMax" value="INFO" />
</filter>
<filter class="org.apache.log4j.varia.DenyAllFilter" />
</appender>
LevelRangeFilter可以指定某个范围(从levelMin到levelMax)的等级,在上面的配置中,如果没有 DenyAllFilter,表示从DEBUG到INFO级别的日志不做处理,而加了DenyAllFilter后含义反转,表示该appender只打印从DEBUG到INFO的日志。log4j中另一个实用的filter是LevelMatchFilter,它准确的匹配某个日志等级。
下面是一个比较完整的xml格式log4j配置文件,请参考:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%1r] %1p - %10.10c - %m \n"/>
</layout>
</appender>
<appender name="LOG-AVAILABLECONFIG" class="org.apache.log4j.DailyRollingFileAppender">
<param name="DatePattern" value="'.'yyyy-MM-dd"/>
<param name="file" value="${app.log}/config.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss}] - %m \n"/>
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="LevelMin" value="INFO"/>
</filter>
</appender>
<category name="com.app.rpc.config" additivity="false">
<priority value="INFO"/>
<appender-ref ref="LOG-AVAILABLECONFIG"/>
</category>
<root>
<priority value="INFO"/>
<appender-ref ref="CONSOLE"/>
</root>
</log4j:configuration>
上面category可以指定日志打印类范围,com.app.rpc.config这个package下所有日志,都是用LOG-AVAILABLECONFIG这个appender打印日志
<appender-ref ref="CONSOLE" /> 指定了日志是否打印到控制台
additivity表示在层级关系中是否向上查找。
b)程序中使用日志
使用Log4j,第一步就是获取日志记录器,这个记录器将负责控制日志信息。其语法为: private final static Log log = LogFactory.getLog(xxx.class);
对于web程序,spring它提供了一个初始化log4j的监听类,当然你也可以自已写个servlet初始化log4j。在spring框架中,可以在web.xml配置一个监听类来初始化log4j。
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>