基于slf4j的日志过滤

来源:互联网 发布:股票历史交易数据查询 编辑:程序博客网 时间:2024/05/22 16:53

最近同事提了一个需求过来,他觉得项目对于第三方日志记录的太多了,只想记录一些业务相关的日志减少对于框架日志的显示。
具体要求就是对于框架日志只显示warn等级以上的,而业务日志显示info等级以上的。

这里主要使用的是slf4j与logback结合的方法。使用过滤器来实现对日志的过滤。

首先是现在项目内封装一个日志管理工具。在需要使用到日志记录程序运行状态时直接调用该方法,而不是重新生成一个Logger对象。

这个地方有需要考虑取舍的,比如如果我直接在类中声明创建一个Logger那么在日志记录的时候我可以直接通过看Logger的name就能知道我这个Logger是记录在哪里的,方便迅速排查问题。但是对于对日志记录格式有操作需求的,就需要自己封装。这里指的并不是对于显示线程,显示日期之类的要求,那些只需要规定好pattern格式就可以了。

首先先介绍一下用到的maven依赖:

<dependencies>    <dependency>        <groupId>junit</groupId>        <artifactId>junit</artifactId>        <version>4.12</version>    </dependency>    <dependency>        <groupId>ch.qos.logback</groupId>        <artifactId>logback-classic</artifactId>        <version>1.2.3</version>    </dependency>    <dependency>        <groupId>org.codehaus.janino</groupId>        <artifactId>janino</artifactId>        <version>3.0.7</version>    </dependency></dependencies>

下面是我的Log管理器的样例:

package log.demo;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public final class LogDemo {    private static final Logger LOGGER = LoggerFactory.getLogger("LogDemo");    public static void debug(String format, Object... args) {        LOGGER.debug(format, args);    }    public static void info(String format, Object... args) {        LOGGER.info(format, args);    }    public static void warn(String format, Object... args) {        LOGGER.warn(format, args);    }    public static void error(String format, Object... args) {        LOGGER.error(format, args);    }}

接下来是配置logback.xml:

<?xml version='1.0' encoding='UTF-8'?><configuration debug="false">    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">            <evaluator>                <expression>return logger.equals("LogDemo");</expression>            </evaluator>            <onMatch>ACCEPT</onMatch>            <onMismatch>NEUTRAL</onMismatch>        </filter>        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">            <level>WARN</level>        </filter>        <encoder>            <pattern>[%-5level] %d{HH:mm:ss.SSS} [%thread] %logger{36} - %msg%n            </pattern>        </encoder>    </appender>    <!-- 日志级别 -->    <root level="ALL">        <appender-ref ref="console" />    </root></configuration>   

通过两个过滤器实现第三方框架日志与项目本身的日志的过滤管理。
第三方日志只输出WARN以上的日志等级,而项目本身的日志全部输出。
首先是第一个过滤器EvaluatorFilter,这个过滤器是通过获取LoggingEvent中的属性来进行过滤的。expression标签表达了判断属性。如果返回结果为true,则进行onMatch标签中的操作,否则则按照onMismatch标签进行处理。

标签一共有三个值:

属性 说明 DENY 过滤该日志,不输出 NEUTRAL 不做任何操作,等待下个过滤器过滤 ACCEPT 接受这个日志,直接输出

这个过滤器将以LogDemo为名的Logger记录的日志全部输出,将其他的日志进入下一个过滤器进行过滤。在这里如果没有封装日志管理器的话,可以通过将expression改为一下形式:

<expression>return logger.contains("log.demo");</expression>

其中log.demo改为项目的根包名。

ThresholdFilter过滤器将日志等级在WARN以下的日志过滤了。

最后通过一个Test来查看运行结果。

package log.demo;import org.junit.Test;import org.slf4j.Logger;import org.slf4j.LoggerFactory;public class LogDemoTest {    private static final Logger LOGGER = LoggerFactory.getLogger(LogDemoTest.class);    @Test    public void testInfo() {        LogDemo.debug("This is {}.", "LogDemo test");        LogDemo.info("This is {}.", "LogDemo test");        LogDemo.warn("This is {}.", "LogDemo test");        LogDemo.error("This is {}.", "LogDemo test");        LOGGER.debug("This is {}.", "LogDemo test");        LOGGER.info("This is {}.", "LogDemo test");        LOGGER.warn("This is {}.", "LogDemo test");        LOGGER.error("This is {}.", "LogDemo test");    }}

输出日志结果:

[DEBUG] 19:02:14.479 [main] LogDemo - This is LogDemo test.[INFO ] 19:02:14.482 [main] LogDemo - This is LogDemo test.[WARN ] 19:02:14.483 [main] LogDemo - This is LogDemo test.[ERROR] 19:02:14.483 [main] LogDemo - This is LogDemo test.[WARN ] 19:02:14.483 [main] log.demo.LogDemoTest - This is LogDemo test.[ERROR] 19:02:14.483 [main] log.demo.LogDemoTest - This is LogDemo test.

这样就完成了第三方日志过滤的功能,做的比较简陋,如果想自定义过滤方法的话,可以通过继承类EvaluatorFilter的方式来实现。

原创粉丝点击