之前曾写过一篇帖子,是log4j按包路径输出到不同文件。
log4j按级别输出到不同文件,也类似。
先看配置:
- ### set log levels ###
- log4j.rootLogger=info,error,info
- log4j.appender.stdout=org.apache.log4j.ConsoleAppender
- log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
- log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
- log4j.logger.info=info
- log4j.appender.info=com.zznode.log.MyAppender
- log4j.appender.info.layout=org.apache.log4j.PatternLayout
- log4j.appender.info.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
- log4j.appender.info.datePattern='.'yyyy-MM-dd
- log4j.appender.info.Threshold = INFO
- log4j.appender.info.append=false
- log4j.appender.info.File=D:/log4j/info.log
- log4j.logger.error=error
- log4j.appender.error=com.zznode.log.MyAppender
- log4j.appender.error.layout=org.apache.log4j.PatternLayout
- log4j.appender.error.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
- log4j.appender.error.datePattern='.'yyyy-MM-dd
- log4j.appender.error.Threshold = ERROR
- log4j.appender.error.append=false
- log4j.appender.error.File=D:/log4j/error.log
测试类:
- import org.apache.log4j.PropertyConfigurator;
- import org.apache.log4j.xml.DOMConfigurator;
- import com.zznode.test.Test;
- /**
- * @desc:
- * @since Nov 8, 2012
- * @author chaisson
- *
- * <p>
- */
- public class Log4jApp {
- public void printLog() {
- Logger log = Logger.getLogger(Log4jApp.class.getClass());
- log.info("测试info");
- log.debug("测试debug");
- log.error("测试error");
- }
- public static void main(String[] args) {
- //DOMConfigurator.configure("log4j.xml");
- PropertyConfigurator.configure("D:/workspace/Test/log4j-new.properties");
- Log4jApp app = new Log4jApp();
- app.printLog();
- // Test test = new Test();
- //test.printLog();
- }
- }
输出结果有点问题:info.log里面也包含了error的输出。
配置中关键的配置说明是这一句:
log4j.appender.debug.Threshold = INFO
而它的作用是输出INFO级别以上的内容到info.log中,所以info.log文件中包含了ERROR级别的文件。
解决办法是:定义自己的Appender类,继承DailyRollingFileAppender,改写针对Threshold 的设置说明(重写针对级别的比较方法)
源代码
- public boolean isAsSevereAsThreshold(Priority priority) {
- return threshold == null || priority.isGreaterOrEqual(threshold);
- }
重写 isAsSevereAsThreshold(Priority priority)方法
- /**
- * @desc:
- * @since Apr 17, 2013
- * @author chaisson
- *
- * <p>
- */
- public class MyAppender extends DailyRollingFileAppender {
- @Override
- public boolean isAsSevereAsThreshold(Priority priority) {
- //只判断是否相等,而不判断优先级
- return this.getThreshold().equals(priority);
- }
- }
这样,进行唯一判断,只有当Threshold与priority一致时,才进行输出,就实现了真正Log4j按照级别输出日志文件。
修改配置文件:
- ### set log levels ###
- log4j.rootLogger=info,error,info
- log4j.appender.stdout=org.apache.log4j.ConsoleAppender
- log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
- log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
- log4j.logger.info=info
- log4j.appender.info=com.zznode.log.MyAppender
- log4j.appender.info.layout=org.apache.log4j.PatternLayout
- log4j.appender.info.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
- log4j.appender.info.datePattern='.'yyyy-MM-dd
- log4j.appender.info.Threshold = INFO
- log4j.appender.info.append=false
- log4j.appender.info.File=D:/log4j/info.log
- log4j.logger.error=error
- log4j.appender.error=com.zznode.log.MyAppender
- log4j.appender.error.layout=org.apache.log4j.PatternLayout
- log4j.appender.error.layout.ConversionPattern=%d{yyyy-MM-dd-HH-mm} [%t] [%c] [%p] - %m%n
- log4j.appender.error.datePattern='.'yyyy-MM-dd
- log4j.appender.error.Threshold = ERROR
- log4j.appender.error.append=false
- log4j.appender.error.File=D:/log4j/error.log
这样才算完成了。
补充:有同事讨论,如果是XML配置,通过filter会简便:
- <filter class="org.apache.log4j.varia.LevelRangeFilter">
- <param name="LevelMin" value="ERROR"/>
- <param name="LevelMax" value="ERROR"/>
- </filter>