Log4j按日志级别输出日志

Log4j是我们最长使用的Java日志组件之一,通常我们将项目所有日志全部保存到一个log文件中,每天产生一个新的日志文件。但是,有时每天日志太多,造成我们要筛选错误和警告等日志不是很方便。因此我们就需要Log4j按照日志级别将日志输出到不同的目录中。

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的继承结构图:

log4j按日志级别输出日志

通过跟踪源代码我们需要更改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 <code>true</code>.
*/
public boolean isAsSevereAsThreshold(Priority priority) {
    return ((threshold == null) || priority.isGreaterOrEqual(threshold));
}

该方法位于AppenderSkeleton抽象类中,下面是isGreaterOrEqual(大于等于)方法的源码:

/**
 Returns <code>true</code> if this level has a higher or equal
 level than the level passed as argument, <code>false</code>
 otherwise.  
 
 <p>You should think twice before overriding the default
 implementation of <code>isGreaterOrEqual</code> 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水平;谢谢支持!!!

不是每一次努力都有收获,但是,每一次收获都必须努力。
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号