Log4j配置详解
Log4j是最常用的日志记录工具,下面在介绍其配置方式的同时,还会讲解其中的原理和使用技巧。
1. XML配置
一直觉得xml配置文件更清晰一些,所以从xml开始讲起。首先给出一个最简配置的log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configurationxmlns:log4j="http://jakarta.apache.org/log4j/">
<appendername="consoleAppender"class="org.apache.log4j.ConsoleAppender">
<layoutclass="org.apache.log4j.PatternLayout">
<paramname="ConversionPattern"value="%m%n"/>
</layout>
</appender>
<appendername="fileAppender"class="org.apache.log4j.RollingFileAppender">
<paramname="File"value="test.log"/>
<layoutclass="org.apache.log4j.PatternLayout">
<paramname="ConversionPattern"value="%m%n"/>
</layout>
</appender>
<root>
<appender-refref="consoleAppender"/>
</root>
<loggername="test">
<appender-refref="fileAppender"/>
</logger>
</log4j:configuration>
先来看文件下方配置的两个logger,每个logger对应记录日志的一个输入,它们以name进行区分,使用相同name的logger打下的日志一定在同一个日志文件中。其中一个特殊的logger叫做root,它是不需要指定name且一定存在的logger。为了对照此处配置了另一个logger test。
文件上方的appender则对应日志文件的输出,即写入哪个文件、用什么样的格式等。这里配置的appender一个向控制台输出,一个向指定文件输出(test.log)。
其实Log4j的核心概念就这么两个,可以看到logger和appender是引用关系,一个logger可以向多个appender输出,一个appender可以被多个logger共同使用。
下面来看一下如何在Java使用logger
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
publicclassLog4jTest{
publicstaticvoid main(String[] args){
DOMConfigurator.configure("log4j.xml");
//PropertyConfigurator.configure("log4j.properties");
Logger root =Logger.getRootLogger();
Logger test =Logger.getLogger("test");
System.out.println(root.getName());
System.out.println(test.getName());
root.info("Root Log");
test.info("Test Log");
}
}
我们会看到root logger的name就是root,"Root Log"会被输出到控制台,"Test Log"既会被写入test.log,也会输出到控制台。这里要说明的一点是,所有非root的logger都有一个additivity属性,默认为true,它们记录的日志都会在root logger输出一份。
2. properties配置
log4j.appender.consoleAppender=org.apache.log4j.ConsoleAppender
log4j.appender.consoleAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.consoleAppender.layout.ConversionPattern=%m%n
log4j.appender.fileAppender=org.apache.log4j.RollingFileAppender
log4j.appender.fileAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.fileAppender.layout.ConversionPattern=%m%n
log4j.rootLogger=DEBUG, consoleAppender
log4j.logger.test=DEBUG, fileAppender
通过和上面xml配置的对比,不难理解其中的含义。不同的是配置logger时必须指定Level,这里设置的是DEBUG。
此外加载配置文件的类也有所不同,使用的是 PropertyConfigurator.configure("log4j.properties");
3. 代码配置
实际上Log4j可以不使用配置文件,直接在代码中进行配置。与上述配置文件等价的代码配置如下
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;
publicclassLog4jTest{
publicstaticvoid main(String[] args){
ConsoleAppender consoleAppender =newConsoleAppender();
consoleAppender.setName("consoleAppender");
consoleAppender.setLayout(newPatternLayout("%m%n"));
consoleAppender.activateOptions();
RollingFileAppender fileAppender =newRollingFileAppender();
fileAppender.setName("fileAppender");
fileAppender.setFile("test.log");
fileAppender.setLayout(newPatternLayout("%m%n"));
fileAppender.activateOptions();
Logger root =Logger.getRootLogger();
root.addAppender(consoleAppender);
Logger test =Logger.getLogger("test");
test.addAppender(fileAppender);
System.out.println(root.getName());
System.out.println(test.getName());
root.info("Root Log");
test.info("Test Log");
}
}
这里注意一定要执行Appender的activateOptions()方法,否则对Appender的配置不会生效。
4. WebApp中log4j的配置
在Java Web工程的web.xml添加加载Log4j配置文件的Listener
<?xml version="1.0" encoding="UTF-8"?>
<web-appversion="2.5"xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>MyApp</display-name>
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/log4j.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
</web-app>
这是一种比较简便的方法,不过需要依赖Spring。如果有其他的方式欢迎留言告诉我一下。
最后说一下代码中logger的使用方式,实际上Logger.getLogger("name")中的name,不一定要是配置文件中声明的logger,你可以随时get出一个任意name的logger,只不过这个logger没有配置appender,并且additivity=true,它记录的日志会输出到root logger的appender中。因此你经常可以看到代码中这样来写
privateLogger logger =Logger.getLogger(Log4jTest.class);
或
privateLogger logger =Logger.getLogger(this.getClass());
这些logger真正的name是具有完整包名的参数类的名称,如cn.gaofeihang.demo.Log4jTest。这样做的好处是,通过配置日志格式,可以在打日志时记录产生日志的类名称,便于排查问题。
这是一篇不太一样的配置说明,意在讲解配置背后的一些原理和技巧。关于log4j各个配置项的使用方法,网上已有很多介绍,就不再赘述。
Log4j 的详细介绍:请点这里
Log4j 的下载地址:请点这里