log4j的阈值滤波器中的ACCEPT vs NEUTRAL

Bet*_*ide 3 log4j2

如果我在log4j xml文件中使用简单的Threshold过滤器,则仅意味着从过滤器级别开始记录所有内容。所以

<ThresholdFilter level="INFO" onMatch="NEUTRAL"/>
Run Code Online (Sandbox Code Playgroud)

记录INFO,WARNING,ERROR和FATAL。因此,它表明默认值NEUTRAL的含义是:不要过滤掉任何内容并让日志通过。

如果我将其更改为

<ThresholdFilter level="INFO" onMatch="ACCEPT"/>
Run Code Online (Sandbox Code Playgroud)

应该怎么办?

arm*_*edl 7

简短地回答您的问题:实际上,当您将代码从“中性”更改为“接受”时,没有任何变化。但这仅在您只有一个过滤器时才成立(正如 DB 也提到的)。

“NEUTRAL”和“ACCEPT”只有在您使用多个过滤器时才会有所不同。

如果您喜欢
集思广益您可以将所有日志分为两个关于一个过滤器的集合:
* 要么日志消息 (/event) 与此过滤器匹配 * 要么日志消息 (/event) 与此过滤器
不匹配筛选

如果您总是使用“NEUTRAL”-“DENY”组合(onMatch="NEUTRAL"+onMismatch="DENY" 或 onMatch="DENY"+onMismatch="NEUTRAL"),那么您会得到所有“NEUTRAL”-子集的交集到过滤器。使用“NEUTRAL”-“ACCEPT”组合,您可以获得并集。

但您需要注意以下规则:一旦过滤器触发“接受”或“拒绝”,则不会评估其他过滤器。所以过滤器的顺序很重要。对于复合过滤器(-<filters>标签)尤其如此。

并且您可以在不同位置设置过滤器。我认为,但我仍然不能完全确定订单是按以下顺序评估的:

  1. 上下文范围的过滤器直接在配置中配置。被这些过滤器拒绝的事件不会传递给记录器进行进一步处理。一旦事件被上下文范围的过滤器接受,它就不会被任何其他上下文范围的过滤器评估,也不会使用记录器的级别来过滤事件。但是,该事件将由 Logger 和 Appender 过滤器评估。
  2. 记录器过滤器在指定的记录器上配置。这些是在 Context-wide Filters 和 Logger 的日志级别之后评估的。被这些过滤器拒绝的事件将被丢弃,并且无论可加性设置如何,该事件都不会传递给父 Logger。
  3. Appender 过滤器用于确定特定的 Appender 是否应该处理事件的格式和发布。
  4. Appender 引用过滤器用于确定 Logger 是否应该将事件路由到 appender。

来源:https : //logging.apache.org/log4j/2.0/manual/filters.html


D.B*_*.B. 6

首先,我只想提及一个问题,然后再回答您的问题。你写了:

记录INFO,WARNING,ERROR和FATAL。因此,它表明默认值NEUTRAL的含义是:不要过滤掉任何内容并让日志通过。

这不是完全准确的,因为TRACE和DEBUG级别的事件未发布,因为它们被过滤器的onMismatch参数的默认值过滤掉了。根据ThresholdFilter文档

onMismatch [是]过滤器不匹配时采取的操作。可以是接受,拒绝或中性。默认值为DENY。

回到您的问题,使用单个过滤器NEUTRALACCEPT使用单个过滤器之间的区别不大,它们的行为相同。但是,当您使用CompositeFilter时,会有很大的不同。

假设我有一个简单的类,它会生成一些日志:

package example;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;

public class SomeClass {

    private static final Logger log = LogManager.getLogger();
    private static final Marker FLOW_MARKER = MarkerManager.getMarker("FLOW");

    public static void main(String[] args){

        if(log.isDebugEnabled())
            log.debug(FLOW_MARKER,"This is some debug!");

        log.info("Here's some info!");
        log.error("Some erorr happened!");

        log.trace("Trace message, yeah!");
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我们有一个log4j2配置,其中包含一个CompositeFilter,其中包含2个过滤器:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
            <Filters>
                <ThresholdFilter level="INFO" onMatch="NEUTRAL" onMismatch="NEUTRAL"/>
                <MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="DENY"/>
            </Filters>
        </Console>

    </Appenders>

    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>
Run Code Online (Sandbox Code Playgroud)

当我们运行这个简单的类时,我们得到以下输出:

22:35:31.666 [main] DEBUG example.SomeClass - This is some debug!
Run Code Online (Sandbox Code Playgroud)

如果现在将ThresholdFilter的onMatch参数更改为ACCEPT

<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
Run Code Online (Sandbox Code Playgroud)

我们将获得以下输出:

22:36:00.939 [main] DEBUG example.SomeClass - This is some debug!
22:36:00.941 [main] INFO  example.SomeClass - Here's some info!
22:36:00.941 [main] ERROR example.SomeClass - Some erorr happened!
Run Code Online (Sandbox Code Playgroud)

最初,由于ThresholdFilter不会接受或拒绝任何日志事件,因此它们都传递给,MarkerFilter如果没有FLOW标记则被拒绝。当我们将更改为ThresholdFilter接受匹配事件时,INFOERROR级事件在到达之前就已接受MarkerFilter,因此已发布。我们仍然可以看到从日志消息DEBUG不是由被拒绝的级别活动ThresholdFilter,因为ThresholdFilterNEUTRAL到错配和MarkerFilter接受的事件,因为它有FLOW标记。