Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ACCEPT vs NEUTRAL in treshold filter for log4j

Tags:

log4j2

If I use a simple Threshold filter in a log4j xml file , this simply means log everything from filter level up. So

<ThresholdFilter level="INFO" onMatch="NEUTRAL"/>

logs INFO, WARNING, ERROR and FATAL. So it seams that NEUTRAL, which is the default value, means: don't filter out anything and let the log go through.

If I change this to

<ThresholdFilter level="INFO" onMatch="ACCEPT"/>

what is it supposed to do?

like image 395
BetaRide Avatar asked Aug 17 '17 05:08

BetaRide


People also ask

What is threshold in log4j?

Threshold is second filter for messages to be logged if Logger is set at level DEBUG and appender Threshold is set at Error then with the appender TextProcessor only Error and higher severity messages would be logged.

What is filter in log4j?

Filters allow Log Events to be evaluated to determine if or how they should be published. A Filter will be called on one of its filter methods and will return a Result, which is an Enum that has one of 3 values - ACCEPT, DENY or NEUTRAL.

Is log4j case sensitive?

Note that level names are case sensitive.

What are Appenders and loggers in log4j?

Apache log4j provides Appender objects which are primarily responsible for printing logging messages to different destinations such as consoles, files, sockets, NT event logs, etc. Each Appender object has different properties associated with it, and these properties indicate the behavior of that object.


2 Answers

First I just want to mention one item before I answer your question. You wrote:

logs INFO, WARNING, ERROR and FATAL. So it seams that NEUTRAL, which is the default value, means: don't filter out anything and let the log go through.

That's not entirely accurate in that TRACE and DEBUG level events are not published because they are filtered out by the default value of the onMismatch parameter of your filter. According to the ThresholdFilter documentation:

onMismatch [is the] Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is DENY.

Getting back to your question, the difference between NEUTRAL and ACCEPT when using a single filter is nothing, they behave the same. When you use a CompositeFilter, however, there's a huge difference.

Let's say I have a simple class that generates some logs:

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!");
    }
}

Now let's say I have a log4j2 configuration that includes a CompositeFilter that contains 2 filters:

<?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>

When we run this simple class we get the following output:

22:35:31.666 [main] DEBUG example.SomeClass - This is some debug!

If we now change the ThresholdFilter's onMatch parameter to ACCEPT:

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

We will get this output instead:

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!

At first, since the ThresholdFilter did not accept or deny any log events they all pass through to the MarkerFilter and are denied if they do not have the FLOW marker. When we changed the ThresholdFilter to accept matching events the INFO and ERROR level events were accepted before reaching the MarkerFilter and therefore were published. We still see the log message from the DEBUG level event that was not denied by the ThresholdFilter because ThresholdFilter is NEUTRAL to mismatches and MarkerFilter accepted the event because it had the FLOW marker.

like image 138
D.B. Avatar answered Sep 26 '22 02:09

D.B.


Answering your question in short: Effectively, nothing changes when you change your code from "NEUTRAL" to "ACCEPT". But this is only true if you have just one single filter (as D.B. also mentioned).

"NEUTRAL" and "ACCEPT" only makes a difference when you use several filters.

If you like thinking in sets:
You can devide all logs into two sets regarding one single filter:
* either the log-message (/event) is matched by this filter
* or the log-message (/event) is not matched by this filter

If you always use "NEUTRAL"-"DENY" combinations (onMatch="NEUTRAL"+onMismatch="DENY" or onMatch="DENY"+onMismatch="NEUTRAL") then you get an intersection of all "NEUTRAL"-subsets regarding to the filters. With "NEUTRAL"-"ACCEPT" combinations you get union sets.

But you need to be aware of the following rule: As soon as a filter triggers an "ACCEPT" or a "DENY" then no other filters will be evaluated. So the order of your filters is important. This is especially true for composite filters (the <filters>-tag).

And you can have filters in different locations. I think, but I'm still not absolutely sure, that the order is evaluated in the following order:

  1. Context-wide Filters are configured directly in the configuration. Events that are rejected by these filters will not be passed to loggers for further processing. Once an event has been accepted by a Context-wide filter it will not be evaluated by any other Context-wide Filters nor will the Logger's Level be used to filter the event. The event will be evaluated by Logger and Appender Filters however.
  2. Logger Filters are configured on a specified Logger. These are evaluated after the Context-wide Filters and the Log Level for the Logger. Events that are rejected by these filters will be discarded and the event will not be passed to a parent Logger regardless of the additivity setting.
  3. Appender Filters are used to determine if a specific Appender should handle the formatting and publication of the event.
  4. Appender Reference Filters are used to determine if a Logger should route the event to an appender.

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

like image 36
armin.miedl Avatar answered Sep 23 '22 02:09

armin.miedl