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 的下载地址:请点这里

相关推荐