学习完了log4j的三个最重要的组件后,现在该学习它另一个重要的功能:配置。其实这是编写项目中最重要的一环,真实的项目一般不会在项目运行过程中去构造Appender、Layout,二是把他们都写在配置文件里面,让log4j去加载。这也提供了足够的灵活性,便于我们在项目实施过程中跟踪、调试、维护等。
log4j支持properties和xml配置文件。有了前面的基础,学习配置文件就很简单了。OK,直接看例子:
log4j.properties:
#设置全局的threshold属性为WARN,还可以设置成DEBUG/INFO/ERROR/FATAL/ALL/OFF log4j.threshold=WARN #设置根logger,格式为:log4j.rootLogger=level,appender1[,appender2]...[,appenderN] log4j.rootLogger=DEBUG,myConsole,myLogFile #设置appender对象,格式为:log4j.appender.appenderName=ClassNameOfAppender #这是一个控制台Appender,日志将保存到控制台 log4j.appender.myConsole=org.apache.log4j.ConsoleAppender #设置appender的layout,格式类似 log4j.appender.myConsole.layout=org.apache.log4j.PatternLayout #设置appender的layout的输出格式 log4j.appender.myConsole.layout.ConversionPattern=%5p [%t] (%F:%L) -%m%n #设置appender的threshold,这是局部的,在满足全局threshold基础上生效 log4j.appender.myConsole.threshold=DEBUG #设置appender对象这是一个文件Appender,日志将保存到文件 log4j.appender.myLogFile=org.apache.log4j.RollingFileAppender #设置文件路径 log4j.appender.myLogFile.File=mylog.log #文件最大大小 log4j.appender.myLogFile.MaxFileSize=100KB #达到文件大小后,最大备份的文件个数 log4j.appender.myLogFile.MaxBackupIndex=10 log4j.appender.myLogFile.layout=org.apache.log4j.PatternLayout #输出格式,日期为 :毫秒数,年,12小时制的时分秒 log4j.appender.myLogFile.layout.ConversionPattern=%d{mmm d,yyyy hh:mm:ss a} : %p [%t] %m%n log4j.appender.myLogFile.threshold=INFO #一个非rootLogger的logger对象,名字为:com.foo,所有com.foo包及其子包下的日志会使用此logger log4j.logger.com.foo=INFO,myConsole1 #设置com.foo的传递性,这样它的日志就不会打印到rootLogger的Appenders log4j.additivity.com.foo=false log4j.appender.myConsole1=org.apache.log4j.ConsoleAppender log4j.appender.myConsole1.layout=org.apache.log4j.PatternLayout log4j.appender.myConsole1.layout.ConversionPattern=%5p [%t] (%F:%L) -%m%n log4j.appender.myConsole1.threshold=DEBUG #配置spring的日志输出地,所有spring.framework包及其子包下的日志会使用此logger log4j.logger.spring.framework=INFO,springAppender log4j.appender.springAppender=org.apache.log4j.RollingFileAppender log4j.appender.springAppender.File=spring.log log4j.appender.springAppender.MaxFileSize=10M log4j.appender.springAppender.MaxBackupIndex=10 log4j.appender.springAppender.layout=org.apache.log4j.PatternLayout log4j.appender.springAppender.layout.ConversionPattern=%d{mmm d,yyyy hh:mm:ss a} : %p [%t] %m%n log4j.appender.springAppender.threshold=INFO
哎呀,有点长,千万别看得头晕,其实配来配去就是那么几个属性,明白了前面所说的Logger、Appender、Layout和他们的一些基本属性的话,这是很容易明白的。一切就绪后,只需在程序中加载配置文件,就可以打印日志啦了:
PropertyConfigurator.configure("log4j.properties");
看完了properties的配置文件,再来看xml格式的配置文件(大同小异):
log4j.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <!--根元素,有全局的threshold设置--> <log4j:configuration threshold="warn" xmlns:log4j='http://jakarta.apache.org/log4j/'> <!--一个普通的Appender--> <appender name="A1" class="org.apache.log4j.FileAppender"> <param name="File" value="A1.log"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %p [%t] %c - %m%n"/> </layout> </appender> <!--另一个Appender--> <appender name="A2" class="org.apache.log4j.FileAppender"> <param name="File" value="A2.log"/> <!--局部的threshold设置--> <param name="threshold" value="INFO"/> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%r %p [%t] %c - %m%n"/> </layout> </appender> <!--一个logger,它的appender是A2,它不向上传递--> <logger name="com.foo" additivity="false"> <appender-ref ref="A2" /> </logger> <!--一个logger,它的appender是A2,它向上传递--> <logger name="com.wombat"> <level value ="debug"/> <appender-ref ref="A2" /> </logger> <!--根logger,它的appender是A1--> <root> <priority value ="debug" /> <appender-ref ref="A1" /> </root> </log4j:configuration>
XML配置文件的加载方法是:
DOMConfigurator.configure("log4j.xml");
OK,让我们来对这个xml文件解释并测试
全局threshold被设置为warn,很明显warn级别以上的日志才会被输出;
除了rootLogger外,还有两个Logger对象--- com.foo和com.wombat;
rootLogger的appender为A1,A1是一个文件Appender;
com.foo和com.wombat对应的appender都是A2,A2也是一个文件Appender,它设置了局部的threshold;
com.foo还设置了additivity属性;
现在我们创建一个测试类:
package com.wombat;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
public class TestLog4jXMLConfig
{
static Logger logger = Logger.getLogger(TestLog4jXMLConfig.class);
public static void main(String[] args)
{
DOMConfigurator.configure("log4j.xml");
logger.info("info from TestLog4jXMLConfig");
logger.debug("debug from TestLog4jXMLConfig");
logger.warn("warn from TestLog4jXMLConfig");
logger.error("error from TestLog4jXMLConfig");
}
}
很明显,这个测试类中的logger会继承自com.wombat,因为它以它的class为名,所以它的日志名为com.wombat.TestLog4jXMLConfig。
执行后,在文件A1.log有输出日志:
2010-09-26 22:08:45,750 WARN [main] com.wombat.TestLog4jXMLConfig - warn from TestLog4jXMLConfig
2010-09-26 22:08:45,750 ERROR [main] com.wombat.TestLog4jXMLConfig - error from TestLog4jXMLConfig
在文件A2.log中有输出日志:
ERROR [main] com.wombat.TestLog4jXMLConfig - error from TestLog4jXMLConfig
在两个文件里面都有日志输出的原因是com.wombat的logger对象没有设置additivity属性,默认为true,所以传递到父类rootLogger的Appender--- A1里面去了,A1没有设置局部的threshold属性,则使用全局的threashold---warn,所以只打印了warn以上的日志,而A2设置了局部的threshold属性,且比全局的threshold级别高,故打印error日志。
让我们来创建另外一个测试文件:
package com.foo;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
public class TestLog4jXMLConfig
{
static Logger logger = Logger.getLogger(TestLog4jXMLConfig.class);
public static void main(String[] args)
{
DOMConfigurator.configure("log4j.xml");
logger.info("info from TestLog4jXMLConfig");
logger.debug("debug from TestLog4jXMLConfig");
logger.warn("warn from TestLog4jXMLConfig");
logger.error("error from TestLog4jXMLConfig");
}
}
执行后,发现只有A2中打印了ERROR日志,A1中什么也没有,不用解释了吧!