log4j2 输出指定单一日志级别(不是该级别及其以上!!!)

本文介绍如何在log4j2中仅输出特定日志级别,而非该级别及其以上级别。关键在于配置多个过滤器,通过ACCEPT、DENY和NEUTRAL策略实现。示例以输出WARN级别为例,详细解析了过滤器的工作原理,并提供相关XML配置参考。

只输出单一级别,而不是本级及以上的级别日志。

直接上代码

eg: 只输出WARN级别

<!--经测试,console标签里面也可以用,RollingFile没有测试,应该也可以-->
<File name="FileWarn" fileName="${FILE_PATH}/warn.log" append="false">
   <Filters>
      <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
      <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
   </Filters>
</File>

核心是:

<Filters>内部去套多个<ThresholdFilter>过滤器,外部的<Filters>标签不能少,不能直接用多个<ThresholdFilter>。网上很多资料就是没有说清楚这个,让人头疼。

原理:

<ThresholdFilter>onMatch如何处理level及其以上级别的信息onMismatch则相应的,如何处理level以下的信息。因此要先定义日志级别高的Filter。

ACCEPT、DENY好理解,关键的就是NEUTRAL中立,不处理但也不拦截,交给后续过滤器处理。而DENY是直接拦截,后续有处理器也没办法处理。

因此要完成输出单一级别的任务:需要两个过滤器。还是以warn级别为例

  • 第一个过滤器,level为上一级别,此处即level="ERROR",然后onMatch="DENY" onMismatch="NEUTRAL" ,效果等价于:(DENY)拦截ERROR及其以上的信息,放行ERROR以下的信息

  • 第二个过滤器,level即为需要输出的级别,此处为level="WARN" ,然后onMatch="ACCEPT" onMismatch="DENY",效果等价于:接收WARN及其以上级别的信息,拦截WARN以下级别的信息。

    但经第一个过滤器,此时WARN及其以上的级别的信息,只剩下WARN自己

至此,完成目标。
只要搞懂了原理,就算是想输出特定几个,或者某级别以下的,都是信手拈来。


拓:NEUTRAL的特例。
如果使用NEUTRAL的,已经是最后一个拦截器。那无论是onMatch还是onMismatch,都会匹配
这里可能onMatch还容易理解,onMismatch都匹配是什么操作。但这是亲测出来的,是没错的。

笔者的理解:既然上面放行了,证明这些信息是有意义的,而到最后一个都还未处理,证明编程失误了,应该是要接收的。所以就统一接收了。

举个例子帮助理解:

<Filters>
       <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
</Filters>

效果是接收WARN以下级别的信息

(这里直接只有一个拦截器,当然也是最后一个拦截器了)


如果按照上述做法还达不到目标的,可能需要调整一下root 的级别。

必须先符合root规定的level,才能到自定义的appender中进行处理

<loggers>
    <root level="">
        <appender-ref ref=""/>
    </root>
</loggers>

参考xml

附上笔者的xml文件,效果是:

  • 分别输出 info、warn、error级别的到不同文件,
  • 控制台输出debug及其以上级别的所有信息。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->

    <!--变量配置-->
    <Properties>
        <!-- 格式化输出:%date表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
        <!-- %logger{36} 表示 Logger 名字最长36个字符 -->
        <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
        <!-- 定义日志存储的路径 -->
        <property name="FILE_PATH" value="C:\Users\Lenovo\Desktop\log"/>
        <!--<property name="FILE_NAME" value="更换为你的项目名"/> -->
    </Properties>
    <appenders>

        <console name="Console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <ThresholdFilter level="ALL"/>

        </console>


        <!-- 打印出所有的info级别的信息,-->
        <File name="FileInfo" fileName="${FILE_PATH}/info.log" append="false">

            <Filters>
                <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>

            <PatternLayout pattern="${LOG_PATTERN}"/>

        </File>

        <!-- 同,打印出所有的Warn级别-->
        <File name="FileWarn" fileName="${FILE_PATH}/warn.log" append="false">
            <Filters>
                <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/>
                <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>

            <PatternLayout pattern="${LOG_PATTERN}"/>
        </File>

        <File name="FileError" fileName="${FILE_PATH}/error.log" append="false">
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </File>

    </appenders>

    <!--Logger节点用来单独指定日志的形式,比如要为指定包下的class指定不同的日志级别等。-->
    <!--然后定义loggers,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>

        <!--过滤掉spring和hibernate的一些无用的debug信息-->
        <logger name="org.springframework" level="INFO"/>
        <logger name="org.mybatis" level="INFO"/>


        <root level="debug">
            <appender-ref ref="Console"/>

            <appender-ref ref="FileInfo"/>
            <appender-ref ref="FileWarn"/>
            <appender-ref ref="FileError"/>
        </root>
    </loggers>

</configuration>


吐槽一下,找了那么多资料居然都没个对的,还以为有多复杂。

正文完,有误欢迎指出。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值