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?
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.
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.
Note that level names are case sensitive.
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.
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.
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:
- 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.
- 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.
- Appender Filters are used to determine if a specific Appender should handle the formatting and publication of the event.
- 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With