Log4j是我们最长使用的Java日志组件之一,通常我们将项目所有日志全部保存到一个log文件中,每天产生一个新的日志文件。但是,有时每天日志太多,造成我们要筛选错误和警告等日志不是很方便。因此我们就需要Log4j按照日志级别将日志输出到不同的目录中。
我们先看看log4j的配置文件,如下:log4j.rootLogger=info, console, huangx, bug315
# console appender
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d %p [%c] - %m%n
# info log
log4j.appender.huangx=org.apache.log4j.RollingFileAppender
log4j.appender.huangx.File=F:/Eclipse_Logging/Logging_Log4j_Learn/document/huangx_info.log
log4j.appender.huangx.layout=org.apache.log4j.PatternLayout
# 将info日志输出到huangx_info.log文件中去(关键点)
log4j.appender.huangx.Threshold=info
log4j.appender.huangx.layout.ConversionPattern=%d %p [%c] - %m%n
# error log
log4j.appender.bug315=org.apache.log4j.RollingFileAppender
log4j.appender.bug315.File=F:/Eclipse_Logging/Logging_Log4j_Learn/document/bug315_error.log
log4j.appender.bug315.layout=org.apache.log4j.PatternLayout
# 将error日志输出到bug315_error.log文件中去(关键点)
log4j.appender.bug315.Threshold=error
log4j.appender.bug315.layout.ConversionPattern=%d %p [%c] - %m%n
java代码如下:package com.bug315;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
/**
* 测试Log4j按照日志级别输出日志
* @author huangxin
* @date 2016年3月11日10:17:13
*/
public class LogLevelOut {
public static void main(String[] args) {
// 加载Log4j配置文件
PropertyConfigurator.configure("example-levelout/log4j-level.properties");
// 获取日志对象
Logger log = Logger.getLogger( LogLevelOut.class );
log.debug("debug infomation");
log.info("info infomation");
log.warn("warn infomation");
log.error("error infomation");
}
}
输出结果:
huangx_info.log文件内容如下:
2016-03-11 10:51:39,388 INFO [com.bug315.LogLevelOut] - info infomation
2016-03-11 10:51:39,389 WARN [com.bug315.LogLevelOut] - warn infomation
2016-03-11 10:51:39,389 ERROR [com.bug315.LogLevelOut] - error infomation
bug315_error.log文件内容如下:
2016-03-11 10:51:39,389 ERROR [com.bug315.LogLevelOut] - error infomation
仔细观察上面的输出日志,读者可能会发现huangx_info.log日志文件中不是只输出info信息吗?为什么所有的日志信息都显示出来了。这是和log4j输出日志相关的,log4j输出日志是按照输出当前级别和更高级别的数据。
解决办法:
我们需要自定义Appender,继承DailyRollingFileAppender,改写针对Threshold的判断(重写针对级别的比较方法)
下面是DailyRollingFileAppender的继承结构图:
通过跟踪源代码我们需要更改isAsSevereAsThreshold(Priority priority)方法,该方法源码如下:/**
Check whether the message level is below the appender's
threshold. If there is no threshold set, then the return value is
always true
.
*/
public boolean isAsSevereAsThreshold(Priority priority) {
return ((threshold == null) || priority.isGreaterOrEqual(threshold));
}
该方法位于AppenderSkeleton抽象类中,下面是isGreaterOrEqual(大于等于)方法的源码:/**
Returns true
if this level has a higher or equal
level than the level passed as argument, false
otherwise.
You should think twice before overriding the default
implementation of isGreaterOrEqual
method.
*/
public boolean isGreaterOrEqual(Priority r) {
return level >= r.level;
}
该方法位于Priority类。从上面两个方法可以看出,log4j判断日志是否输出是判断当前的日志的级别是否大于等于配置文件中指定的日志级别,如果成立则输出;
现在我们需要从写isAsSevereAsThreshold(Priority priority)方法,然后将判断方式从大于等于改为等于,这样我们就可以严格根据日志级别来输出。如下:package com.bug315.log4j;
import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.Priority;
/**
* 自定义自己的Appender
* @author huangxin
* @date 2016年3月11日11:12:51
*/
public class MyDailyRollingFileAppender extends DailyRollingFileAppender {
@Override
public boolean isAsSevereAsThreshold(Priority priority) {
// 只判断日志级别是否相等,而不判断日志级别优先级
return this.getThreshold().equals(priority);
}
}
这样,进行唯一判断,只有当Threshold与priority一致时,才进行输出,就实现了真正Log4j按照级别输出日志文件。
接下来我们需要修改配置文件中的appender,修改后的配置文件如下:log4j.rootLogger=info, console, huangx, bug315
# console appender
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d %p [%c] - %m%n
# info log
# 应用自定义的Appender
log4j.appender.huangx=com.bug315.log4j.MyDailyRollingFileAppender
log4j.appender.huangx.File=F:/Eclipse_Logging/Logging_Log4j_Learn/document/huangx_info.log
log4j.appender.huangx.layout=org.apache.log4j.PatternLayout
log4j.appender.huangx.Threshold=info
log4j.appender.huangx.layout.ConversionPattern=%d %p [%c] - %m%n
# error log
# 应用自定义的Appender
log4j.appender.bug315=com.bug315.log4j.MyDailyRollingFileAppender
log4j.appender.bug315.File=F:/Eclipse_Logging/Logging_Log4j_Learn/document/bug315_error.log
log4j.appender.bug315.layout=org.apache.log4j.PatternLayout
log4j.appender.bug315.Threshold=error
log4j.appender.bug315.layout.ConversionPattern=%d %p [%c] - %m%n
到这里就讲解完了,不知道说清楚没有;不过读者可以自行研究Log4j的源码,这样对使用Log4j有很好的帮助,同时还能提高你Java水平;谢谢支持!!!