ppkarwasz commented on code in PR #2717:
URL: https://github.com/apache/logging-log4j2/pull/2717#discussion_r1668336523


##########
src/site/antora/modules/ROOT/pages/manual/filters.adoc:
##########
@@ -17,1038 +17,1407 @@
 
 [id=filters]
 = Filters
+:stem:
 
-Log4j supports filtering of log events at each level of the logging pipeline 
using two features:
+Filters are Log4j plugins that evaluate the parameters of a logging call or a 
log event and return one of three results:
 
-* the `level` attributes that can be set on loggers and appender references,
-* filter components that can be attached to loggers, appenders, appender 
references or the global configuration object.
+ACCEPT:: The log event is accepted by the filter and goes to the next stage of 
the logging pipeline.
 
-Filters evaluate the parameters of a logging call (context-wide filter) or a 
log event and return one of three results:
+DENY:: The log event is unconditionally dropped.
 
-ACCEPT:: The log event is accepted by the filter and goes to the next stage of 
the logging pipeline,
+NEUTRAL:: Log4j behaves as if the filter was not present.
 
-DENY:: The log event is unconditionally dropped,
+Filters can be used at each level of the
+xref:manual/architecture.adoc#architecture-diagram[logging pipeline]:
 
-NEUTRAL:: Log4j behaves as if the filter was not present.
+* the global configuration element can contain a 
xref:manual/configuration.adoc#global-filters[global filter].
+* each xref:manual/configuration.adoc#configuring-loggers[logger] 
configuration element can contain a 
xref:manual/configuration.adoc#logger-elements-filters[logger filter].
+* each xref:manual/configuration.adoc#configuring-appenderrefs[appender 
reference] configuration element can contain an 
xref:manual/configuration.adoc#appenderrefs-elements-filters[appender reference 
filter].
+* each xref:manual/appenders.adoc[appender] configuration element can contain 
an xref:manual/appenders.adoc[appender filter].
+
+Additionally, the following configuration attributes take part in the 
filtering process:
+
+* the xref:manual/configuration.adoc#logger-attributes-level[`level` 
attribute] of logger configuration elements.
+* the xref:manual/configuration.adoc#appenderref-attributes-level[`level` 
attribute] of appender reference configuration elements.
+
+[#filtering-process]
+== Filtering process
+
+Due to the interaction of many elements,
+the filtering process in Log4j is quite complex and can be divided in four 
stages:
+
+. <<logger-stage,`Logger` stage>>
+. <<logger-config-stage,`LoggerConfig` stage>>
+. <<appender-control-stage,`AppenderControl` stage>>
+. <<appender-stage,`Appender` stage>>
+
+[IMPORTANT]
+====
+For performance reasons, log events should be filtered at the earliest 
possible stage.
+This reduces the cost of disabled log events:
+e.g., log event creation, population of context data, formatting, transfer 
through an asynchronous barrier.
+====
+
+[#logger-stage]
+=== 1. `Logger` stage
+
+[plantuml]
+....
+@startuml
+start
+group Logger
+
+:A Logger method;
+
+switch (Apply global filter)
+case (DENY)
+    #pink:Discard;
+    detach
+case (ACCEPT)
+case (NEUTRAL)
+    if (Is less severe than logger level?) then (yes)
+        #pink:Discard;
+        detach
+    else (no)
+        ' The label improves spacing
+        label a1
+    endif
+endswitch
+end group
+:Create LogEvent;
+stop
+....
+
+The parameters of the logging call are passed to the global filter.
+If the global filter returns:
+
+DENY:: The log message is immediately discarded.
+NEUTRAL:: If the level of the log message is less severe than the configured 
logger threshold, the message is discarded.
+Otherwise, a
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html[`LogEvent`]
 is created and processing continues.
+ACCEPT:: A `LogEvent` is created and processing continues in the next stage.
+
+[TIP]
+====
+Filtering logging calls at this stage provides the best performance:
+
+* this stage precedes the creation of log events, therefore operations like the
+xref:manual/thread-context.adoc[injection of context data],
+xref:manual/layouts.adoc#LocationInformation[computation of location 
information]
+will not be performed for disabled log statements.
+* this stage precedes the asynchronous calls performed by either
+xref:manual/async.adoc[asynchronous loggers]
+or
+xref:manual/appenders.adoc#AsyncAppender[asynchronous appenders].
+====
+
+[#logger-config-stage]
+=== 2. `LoggerConfig` stage
+
+[plantuml]
+....
+@startuml
+start
+group LoggerConfig
+repeat
+
+:LoggerConfig.log();
+
+if (Apply logger filter) then (DENY)
+    #pink:Discard;
+    detach
+else (not DENY)
+    ' The label improves spacing
+    label a1
+endif
+repeat while (Go to parent logger?) is (yes)
+-> no;
+end group
+stop
+@enduml
+....
+
+In this stage, log events are evaluated by all the
+xref:manual/configuration.adoc#logger-elements-filters[logger filters]
+that stand on the path from the logger to an appender.
+Due to the
+xref:manual/configuration.adoc#logger-attributes-additivity[additivity of 
logger configurations],
+this means that a log event must also pass the filters of all the parent 
loggers,
+until it reaches the logger that references the chosen appender.
+
+[#appender-control-stage]
+=== 3. `AppenderControl` stage
+
+[plantuml]
+....
+@startuml
+!pragma useVerticalIf on
+start
+group AppenderControl
+
+:AppenderControl.callAppender();
+
+if (Is less severe then appender reference level?) then (yes)
+    #pink:Discard;
+    detach
+else (no)
+    ' The label improves spacing
+    label a2
+endif
+if (Apply appender reference filter) then (DENY)
+    #pink:Discard;
+    detach
+else (not DENY)
+    ' The label improves spacing
+    label a1
+endif
+end group
+stop
+@enduml
+....
+
+To pass this stage, log events must satisfy both conditions:
+
+* the log event must be at least as severe as the
+xref:manual/configuration.adoc#appenderref-attributes-level[`level` attribute]
+of the appender reference.
+* the xref:manual/configuration.adoc#appenderrefs-elements-filters[appender 
reference filter] must return `ACCEPT` or `NEUTRAL`,
+
+[#appender-stage]
+=== 4. `Appender` stage
+
+[plantuml]
+....
+@startuml
+start
+group Appender
+
+:Appender.append();
+
+if (Apply appender filter) then (DENY)
+    #pink:Discard;
+    detach
+else (not DENY)
+    ' The label improves spacing
+    label a1
+endif
+end group
+#palegreen:Log message;
+@enduml
+....
+
+When log events reach an appender,
+the filter attached to an appender is evaluated and if the result is `DENY`,
+the log event is discarded.
+
+[NOTE]
+====
+Some appenders like the
+xref:manual/appenders.adoc#AsyncAppender[asynchronous appender]
+use appender references to transfer log events to other appenders.
+In such a case, the filtering process goes back to the 
<<appender-control-stage,`AppenderControl` stage>>.
+====
+
+[TIP]
+====
+Users migrating from Log4j 1 often replace the `threshold` property of a Log4j 
1 appender with a <<ThresholdFilter>> on the equivalent Log4j 2 appender.
+
+Using the `level` property of appender references will give a better 
performance.
+====
+
+[WARNING]
+====
+Configuring filters is a measure of last resort,
+since it adds a large overhead to disabled log events.
+You should rather configure the filtering in one of the previous stages.
+====
 
-To decide whether a log event from a certain logger is delivered to a specific 
appender, the following procedure is followed:
+[#example-configuration-file]
+=== Example configuration file
+
+The following example shows the order in which filters are evaluated:
 
 [tabs]
 ====
 XML::
 +
-.Snippet from an example 
{antora-examples-url}/manual/filters/filters.xml[`log4j2.xml`]
 [source,xml]
 ----
-include::example$manual/filters/filters.xml[lines=23..41,indent=0]
+include::example$manual/filters/filters.xml[lines=1;18..-1]
 ----
 
 JSON::
 +
-.Snippet from an example 
{antora-examples-url}/manual/filters/filters.json[`log4j2.json`]
 [source,json]
 ----
-include::example$manual/filters/filters.json[lines=3..35,indent=0]
+include::example$manual/filters/filters.json[]
 ----
 
 YAML::
 +
-.Snippet from an example 
{antora-examples-url}/manual/filters/filters.yaml[`log4j2.yaml`]
 [source,yaml]
 ----
-include::example$manual/filters/filters.yaml[lines=18..-1]
+include::example$manual/filters/filters.yaml[lines=17..-1]
 ----
 
 Properties::
 +
-.Snippet from an example 
{antora-examples-url}/manual/filters/filters.properties[`log4j2.properties`]
 [source,properties]
 ----
 include::example$manual/filters/filters.properties[lines=17..-1]
 ----
 ====
 
-<1> First the context-wide filter is consulted.
-If it returns `ACCEPT` the log message goes directly to point 3.
-<2> Then Log4j checks the message against the configured logger level.
-<3> The filter configured on a logger is applied next.
-If the logger is additive, the filter on the parent logger is applied 
recursively until we end up on the logger that references the given appender.
-<4> Next comes the turn of the filter configured on an appender reference,
-<5> followed by a level check against the configured level of the reference.
-<6> The process ends with the filter attached to an appender.
+<1> Global filter
+<2> Logger `level` attribute (it is skipped if the event matches the global 
filter)
+<3> Filter of the "org.example" logger
+<4> Filter of the root logger (it is the parent of the "org.example" logger)
+<5> Appender reference `level` attribute
+<6> Filter of the appender reference
+<7> Filter of the appender
 
-[WARNING]
-====
-For performance reasons, log events should be filtered as soon as possible in 
the logging pipeline.
-This reduces the costs (formatting, transfer through an asynchronous barrier) 
of disabled log events.
-====
+[#common-configuration]
+== Common configuration
 
-[TIP]
-====
-Users migrating from Log4j 1 often replace the `threshold` property of a Log4j 
1 appender with a <<ThresholdFilter>> on the equivalent Log4j 2 appender.
+[#common-configuration-attributes]
+=== Common configuration attributes
 
-Using the `level` property of appender references will give a better 
performance.
-====
+The default behavior of filters is in line with the `filter()` methods of 
functional interfaces, such as
+https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/Optional.html#filter-java.util.function.Predicate-[`Optional.filter()`]
+or
+https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/stream/Stream.html#filter-java.util.function.Predicate-[`Stream.filter()`]:
+filters pass matching events to the next filter and drop those that do not 
match.
+
+To allow for a larger spectrum of behaviors,
+all standard filters, except `CompositeFilter` and `DenyAllFilter`, accept the 
following configuration attributes:
+
+.Common filter configuration attributes
+[cols="1m,1,1,4"]
+|===
+|Attribute |Type | Default value |Description
+
+| [[onMatch]]onMatch
+| 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.Result.html[`Result`]
+| 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.Result.html#NEUTRAL[`NEUTRAL`]
+| Result returned if the condition matches.
+
+| [[onMismatch]]onMismatch
+| 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.Result.html[`Result`]
+| 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.Result.html#DENY[`DENY`]
+| Result returned if the condition does not match.
+
+|===
+
+[#CompositeFilter]
+=== Composing filters
+
+Filters usually test for a single condition.
+To express a more complex filtering logic, Log4j provides a
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-CompositeFilter[`Filters`]
+plugin.
+This plugin can contain a sequence of filters and has no other configuration 
option.
+
+The `Filters` plugin sequentially evaluates each sub-filter and:
+
+* if the sub-filter returns `ACCEPT` (resp. `DENY`), the `Filters` plugin 
returns `ACCEPT` (resp. `DENY`).
+* if the sub-filter return `NEUTRAL`, the `Filters` plugin evaluates the next 
sub-filter in the chain.
+* if the last sub-filter returns `NEUTRAL`, the `Filters` plugin returns 
`NEUTRAL`.
+
+The `Filters` plugin together with the ternary logic of filters, can be used 
to express all the boolean operators.
+In the following examples `A` and `B` are two filters.
+
+`NOT A`::
+You can invert the functionality of filter `A` by swapping the `onMatch` and 
`onMismatch`:
++
+[source,xml]
+----
+<A onMatch="DENY" onMismatch="NEUTRAL"/>
+----
+
+`A AND B`::
+To select the events that match both `A` and `B` you can use:
++
+[source,xml]
+----
+<Filters>
+  <A/>
+  <B/>
+</Filters>
+----
+
+`A OR B`::
+To select the events that match `A` or `B` we can replace `NEUTRAL` with 
`ACCEPT` in the `onMatch` attribute:
++
+[source,xml]
+----
+<Filters>
+  <A onMatch="ACCEPT"/>
+  <B onMatch="ACCEPT"/>
+</Filters>
+----
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-CompositeFilter[📖
 Plugin reference for `Filters`]
 
 [#collection]
 == Collection
 
-Log4j bundles several predefined filters to assist in several common 
deployment use cases.
-Following sections explain all these in detail.
+Log4j Core provides the following filters out-of-the-box.
+
+[#timestamp-filters]
+=== Timestamp filters
+
+Timestamp filters use the timestamp of log events to decide whether to log 
them or not.
 
 [#BurstFilter]
-=== BurstFilter
+==== `BurstFilter`
 
-The BurstFilter provides a mechanism to control the rate at which LogEvents 
are processed by silently discarding events after the maximum limit has been 
reached.
+The `BurstFilter` uses the _sliding window log_ algorithm to limit the rate of 
log events.
+The rate limit is only applied to log events less severe than a configured log 
level.
 
-.Burst Filter Parameters
-[cols="1m,1,4"]
+Besides the common configuration attributes,
+the `BurstFilter` supports the following parameters:
+
+.`BurstFilter` -- configuration attributes
+[cols="1m,1,1,4"]
 |===
-|Parameter Name |Type |Description
-
-|level
-|String
-|Level of messages to be filtered. Anything at or below
-this level will be filtered out if `maxBurst` has been exceeded. The
-default is WARN meaning any messages that are higher than warn will be
-logged regardless of the size of a burst.
-
-|rate
-|float
-|The average number of events per second to allow.
-
-|maxBurst
-|integer
-|The maximum number of events that can occur before
-events are filtered for exceeding the average rate. The default is 10
-times the rate.
-
-|onMatch
-|String
-|Action to take when the filter matches. Can be ACCEPT,
-DENY or NEUTRAL. The default value is NEUTRAL.
-
-|onMismatch
-|String
-|Action to take when the filter does not match. Can
-be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+|Attribute | Type | Default value | Description
+
+| level
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[`Level`]
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html#WARN[`WARN`]
+| The rate limit only applies to log events less severe than this level.
+Events at least as severe as this level will always match.
+
+| rate
+| `float`
+| `10`
+| The average number of events per second to allow.
+
+| maxBurst
+| `long`
+| `10 &times; rate`
+| The maximum number of events in a sliding window.
+
 |===
 
-A configuration containing the BurstFilter might look like:
+The sliding window can be easily computed as:
 
-[source,xml]
+[stem]
+++++
+wi\ndow = (m\axBurst) / (rate),
+++++
+
+where `window` is the duration of the sliding window in seconds.
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-BurstFilter[📖
 Plugin reference for `BurstFilter`]
+
+[#TimeFilter]
+==== `TimeFilter`
+
+The `TimeFilter` only matches log events emitted during a certain time of the 
day.
+
+Besides the common configuration attributes,
+the `TimeFilter` supports the following parameters:
+
+.`TimeFilter` -- configuration attributes
+[cols="1m,2,1,4"]
+|===
+| Attribute | Type | Default value | Description
+
+| start
+| 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/time/LocalTime.html[`LocalTime`]
 in `HH:mm:ss` format
+| 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/time/LocalTime.html#MIN[`LocalTime.MIN`]
+| The beginning of the time slot.
+
+| start
+| 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/time/LocalTime.html[`LocalTime`]
 in `HH:mm:ss` format
+| 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/time/LocalTime.html#MAX[`LocalTime.MAX`]
+| The end of the time slot.
+
+| timezone
+| 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/time/ZoneId.html[`ZoneId`]
+| 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/time/ZoneId.html#systemDefault--[`ZoneId.systemDefault()`]
+| The timezone to use when comparing `start` and `end` to the event timestamp.
+
+|===
+
+As a simple application of this filter,
+if you want to forward messages to your console during work hours and to your 
e-mail account after work hours,
+you can use a configuration snippet like:
+
+[tabs]
+====
+XML::
++
+.Snippet from an example 
{antora-examples-url}/manual/filters/TimeFilter.xml[`log4j2.xml`]
+[source,xml,indent=0]
 ----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
-  <Appenders>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>
+include::example$manual/filters/TimeFilter.xml[tag=filter]
 ----
 
-[#CompositeFilter]
-=== CompositeFilter
-
-The CompositeFilter provides a way to specify more than one filter.
-It is added to the configuration as a filter element and contains other 
filters to be evaluated.
-The filter element accepts no parameters.
+JSON::
++
+.Snippet from an example 
{antora-examples-url}/manual/filters/TimeFilter.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/filters/TimeFilter.json[tag=filter]
+----
 
-A configuration containing the CompositeFilter might look like:
+YAML::
++
+.Snippet from an example 
{antora-examples-url}/manual/filters/TimeFilter.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/filters/TimeFilter.yaml[tag=filter]
+----
 
-[source,xml]
+Properties::
++
+.Snippet from an example 
{antora-examples-url}/manual/filters/TimeFilter.properties[`log4j2.properties`]
+[source,properties,indent=0]
 ----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
-  <Filters>
-    <MarkerFilter marker="EVENT" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
-    <DynamicThresholdFilter key="loginId" defaultThreshold="ERROR"
-                            onMatch="ACCEPT" onMismatch="NEUTRAL">
-      <KeyValuePair key="User1" value="DEBUG"/>
-    </DynamicThresholdFilter>
-  </Filters>
-  <Appenders>
-    <File name="Audit" fileName="logs/audit.log">
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-    </File>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Logger name="EventLogger" level="info">
-      <AppenderRef ref="Audit"/>
-    </Logger>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>
+include::example$manual/filters/TimeFilter.properties[tag=filter]
 ----
+====
 
-[#DynamicThresholdFilter]
-=== DynamicThresholdFilter
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-TimeFilter[📖
 Plugin reference for `TimeFilter`]
 
-The DynamicThresholdFilter allows filtering by log level based on specific 
attributes.
-For example, if the user's loginId is being captured in the ThreadContext Map 
then it is possible to enable debug logging for only that user.
-If the log event does not contain the specified ThreadContext item NEUTRAL 
will be returned.
+[#level-filters]
+=== Level filters
 
-.Dynamic Threshold Filter Parameters
-[cols="1m,1,4"]
+The following filters allow you to filter log events based on their level.
+
+[#LevelMatchFilter]
+==== `LevelMatchFilter`
+
+The `LevelMatchFilter` matches log events that have exactly a certain log 
level.
+
+Besides the common configuration attributes, the `LevelMatchFilter` supports 
the following parameter:
+
+.`LevelMatchFilter` -- configuration attributes
+[cols="1m,1,1,4"]
 |===
-|Parameter Name |Type |Description
-
-|key
-|String
-|The name of the item in the ThreadContext Map to compare.
-
-|defaultThreshold
-|String
-|Level of messages to be filtered. The default
-threshold only applies if the log event contains the specified
-ThreadContext Map item and its value do not match any key in the
-key/value pairs.
-
-|keyValuePair
-|KeyValuePair[]
-|One or more KeyValuePair elements that
-define the matching value for the key and the Level to evaluate when the
-key matches.
-
-|onMatch
-|String
-|Action to take when the filter matches. Can be ACCEPT,
-DENY or NEUTRAL. The default value is NEUTRAL.
-
-|onMismatch
-|String
-|Action to take when the filter does not match. Can
-be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+| Attribute | Type | Default value | Description
+
+| level
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[`Level`]
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html#ERROR[`ERROR`]
+| The filter only matches log events of this level.
+
 |===
 
-Here is a sample configuration containing the DynamicThresholdFilter:
+[TIP]
+====
+If you wish to use a different log file for each log level, you can also use a

Review Comment:
   I think they should.
   
   Personally I don't find the practice of splitting each log level in a 
separate file very useful, since you need to look at several files to give a 
context to each event.
   However, in UNIX the `/var/log/mail.*.log` files have been traditionally 
split per level, so we want to give users the same opportunity here.
   
   Fixed in 4d0d7aa6c4c2ca8f9ad92621e50f8b513e59ec71.



##########
src/site/antora/modules/ROOT/pages/manual/filters.adoc:
##########
@@ -17,1038 +17,1407 @@
 
 [id=filters]
 = Filters
+:stem:
 
-Log4j supports filtering of log events at each level of the logging pipeline 
using two features:
+Filters are Log4j plugins that evaluate the parameters of a logging call or a 
log event and return one of three results:
 
-* the `level` attributes that can be set on loggers and appender references,
-* filter components that can be attached to loggers, appenders, appender 
references or the global configuration object.
+ACCEPT:: The log event is accepted by the filter and goes to the next stage of 
the logging pipeline.
 
-Filters evaluate the parameters of a logging call (context-wide filter) or a 
log event and return one of three results:
+DENY:: The log event is unconditionally dropped.
 
-ACCEPT:: The log event is accepted by the filter and goes to the next stage of 
the logging pipeline,
+NEUTRAL:: Log4j behaves as if the filter was not present.
 
-DENY:: The log event is unconditionally dropped,
+Filters can be used at each level of the
+xref:manual/architecture.adoc#architecture-diagram[logging pipeline]:
 
-NEUTRAL:: Log4j behaves as if the filter was not present.
+* the global configuration element can contain a 
xref:manual/configuration.adoc#global-filters[global filter].
+* each xref:manual/configuration.adoc#configuring-loggers[logger] 
configuration element can contain a 
xref:manual/configuration.adoc#logger-elements-filters[logger filter].
+* each xref:manual/configuration.adoc#configuring-appenderrefs[appender 
reference] configuration element can contain an 
xref:manual/configuration.adoc#appenderrefs-elements-filters[appender reference 
filter].
+* each xref:manual/appenders.adoc[appender] configuration element can contain 
an xref:manual/appenders.adoc[appender filter].
+
+Additionally, the following configuration attributes take part in the 
filtering process:
+
+* the xref:manual/configuration.adoc#logger-attributes-level[`level` 
attribute] of logger configuration elements.
+* the xref:manual/configuration.adoc#appenderref-attributes-level[`level` 
attribute] of appender reference configuration elements.
+
+[#filtering-process]
+== Filtering process
+
+Due to the interaction of many elements,
+the filtering process in Log4j is quite complex and can be divided in four 
stages:
+
+. <<logger-stage,`Logger` stage>>
+. <<logger-config-stage,`LoggerConfig` stage>>
+. <<appender-control-stage,`AppenderControl` stage>>
+. <<appender-stage,`Appender` stage>>
+
+[IMPORTANT]
+====
+For performance reasons, log events should be filtered at the earliest 
possible stage.
+This reduces the cost of disabled log events:
+e.g., log event creation, population of context data, formatting, transfer 
through an asynchronous barrier.
+====
+
+[#logger-stage]
+=== 1. `Logger` stage
+
+[plantuml]
+....
+@startuml
+start
+group Logger
+
+:A Logger method;
+
+switch (Apply global filter)
+case (DENY)
+    #pink:Discard;
+    detach
+case (ACCEPT)
+case (NEUTRAL)
+    if (Is less severe than logger level?) then (yes)
+        #pink:Discard;
+        detach
+    else (no)
+        ' The label improves spacing
+        label a1
+    endif
+endswitch
+end group
+:Create LogEvent;
+stop
+....
+
+The parameters of the logging call are passed to the global filter.
+If the global filter returns:
+
+DENY:: The log message is immediately discarded.
+NEUTRAL:: If the level of the log message is less severe than the configured 
logger threshold, the message is discarded.
+Otherwise, a
+link:../javadoc/log4j-core/org/apache/logging/log4j/core/LogEvent.html[`LogEvent`]
 is created and processing continues.
+ACCEPT:: A `LogEvent` is created and processing continues in the next stage.
+
+[TIP]
+====
+Filtering logging calls at this stage provides the best performance:
+
+* this stage precedes the creation of log events, therefore operations like the
+xref:manual/thread-context.adoc[injection of context data],
+xref:manual/layouts.adoc#LocationInformation[computation of location 
information]
+will not be performed for disabled log statements.
+* this stage precedes the asynchronous calls performed by either
+xref:manual/async.adoc[asynchronous loggers]
+or
+xref:manual/appenders.adoc#AsyncAppender[asynchronous appenders].
+====
+
+[#logger-config-stage]
+=== 2. `LoggerConfig` stage
+
+[plantuml]
+....
+@startuml
+start
+group LoggerConfig
+repeat
+
+:LoggerConfig.log();
+
+if (Apply logger filter) then (DENY)
+    #pink:Discard;
+    detach
+else (not DENY)
+    ' The label improves spacing
+    label a1
+endif
+repeat while (Go to parent logger?) is (yes)
+-> no;
+end group
+stop
+@enduml
+....
+
+In this stage, log events are evaluated by all the
+xref:manual/configuration.adoc#logger-elements-filters[logger filters]
+that stand on the path from the logger to an appender.
+Due to the
+xref:manual/configuration.adoc#logger-attributes-additivity[additivity of 
logger configurations],
+this means that a log event must also pass the filters of all the parent 
loggers,
+until it reaches the logger that references the chosen appender.
+
+[#appender-control-stage]
+=== 3. `AppenderControl` stage
+
+[plantuml]
+....
+@startuml
+!pragma useVerticalIf on
+start
+group AppenderControl
+
+:AppenderControl.callAppender();
+
+if (Is less severe then appender reference level?) then (yes)
+    #pink:Discard;
+    detach
+else (no)
+    ' The label improves spacing
+    label a2
+endif
+if (Apply appender reference filter) then (DENY)
+    #pink:Discard;
+    detach
+else (not DENY)
+    ' The label improves spacing
+    label a1
+endif
+end group
+stop
+@enduml
+....
+
+To pass this stage, log events must satisfy both conditions:
+
+* the log event must be at least as severe as the
+xref:manual/configuration.adoc#appenderref-attributes-level[`level` attribute]
+of the appender reference.
+* the xref:manual/configuration.adoc#appenderrefs-elements-filters[appender 
reference filter] must return `ACCEPT` or `NEUTRAL`,
+
+[#appender-stage]
+=== 4. `Appender` stage
+
+[plantuml]
+....
+@startuml
+start
+group Appender
+
+:Appender.append();
+
+if (Apply appender filter) then (DENY)
+    #pink:Discard;
+    detach
+else (not DENY)
+    ' The label improves spacing
+    label a1
+endif
+end group
+#palegreen:Log message;
+@enduml
+....
+
+When log events reach an appender,
+the filter attached to an appender is evaluated and if the result is `DENY`,
+the log event is discarded.
+
+[NOTE]
+====
+Some appenders like the
+xref:manual/appenders.adoc#AsyncAppender[asynchronous appender]
+use appender references to transfer log events to other appenders.
+In such a case, the filtering process goes back to the 
<<appender-control-stage,`AppenderControl` stage>>.
+====
+
+[TIP]
+====
+Users migrating from Log4j 1 often replace the `threshold` property of a Log4j 
1 appender with a <<ThresholdFilter>> on the equivalent Log4j 2 appender.
+
+Using the `level` property of appender references will give a better 
performance.
+====
+
+[WARNING]
+====
+Configuring filters is a measure of last resort,
+since it adds a large overhead to disabled log events.
+You should rather configure the filtering in one of the previous stages.
+====
 
-To decide whether a log event from a certain logger is delivered to a specific 
appender, the following procedure is followed:
+[#example-configuration-file]
+=== Example configuration file
+
+The following example shows the order in which filters are evaluated:
 
 [tabs]
 ====
 XML::
 +
-.Snippet from an example 
{antora-examples-url}/manual/filters/filters.xml[`log4j2.xml`]
 [source,xml]
 ----
-include::example$manual/filters/filters.xml[lines=23..41,indent=0]
+include::example$manual/filters/filters.xml[lines=1;18..-1]
 ----
 
 JSON::
 +
-.Snippet from an example 
{antora-examples-url}/manual/filters/filters.json[`log4j2.json`]
 [source,json]
 ----
-include::example$manual/filters/filters.json[lines=3..35,indent=0]
+include::example$manual/filters/filters.json[]
 ----
 
 YAML::
 +
-.Snippet from an example 
{antora-examples-url}/manual/filters/filters.yaml[`log4j2.yaml`]
 [source,yaml]
 ----
-include::example$manual/filters/filters.yaml[lines=18..-1]
+include::example$manual/filters/filters.yaml[lines=17..-1]
 ----
 
 Properties::
 +
-.Snippet from an example 
{antora-examples-url}/manual/filters/filters.properties[`log4j2.properties`]
 [source,properties]
 ----
 include::example$manual/filters/filters.properties[lines=17..-1]
 ----
 ====
 
-<1> First the context-wide filter is consulted.
-If it returns `ACCEPT` the log message goes directly to point 3.
-<2> Then Log4j checks the message against the configured logger level.
-<3> The filter configured on a logger is applied next.
-If the logger is additive, the filter on the parent logger is applied 
recursively until we end up on the logger that references the given appender.
-<4> Next comes the turn of the filter configured on an appender reference,
-<5> followed by a level check against the configured level of the reference.
-<6> The process ends with the filter attached to an appender.
+<1> Global filter
+<2> Logger `level` attribute (it is skipped if the event matches the global 
filter)
+<3> Filter of the "org.example" logger
+<4> Filter of the root logger (it is the parent of the "org.example" logger)
+<5> Appender reference `level` attribute
+<6> Filter of the appender reference
+<7> Filter of the appender
 
-[WARNING]
-====
-For performance reasons, log events should be filtered as soon as possible in 
the logging pipeline.
-This reduces the costs (formatting, transfer through an asynchronous barrier) 
of disabled log events.
-====
+[#common-configuration]
+== Common configuration
 
-[TIP]
-====
-Users migrating from Log4j 1 often replace the `threshold` property of a Log4j 
1 appender with a <<ThresholdFilter>> on the equivalent Log4j 2 appender.
+[#common-configuration-attributes]
+=== Common configuration attributes
 
-Using the `level` property of appender references will give a better 
performance.
-====
+The default behavior of filters is in line with the `filter()` methods of 
functional interfaces, such as
+https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/Optional.html#filter-java.util.function.Predicate-[`Optional.filter()`]
+or
+https://docs.oracle.com/javase/{java-target-version}/docs/api/java/util/stream/Stream.html#filter-java.util.function.Predicate-[`Stream.filter()`]:
+filters pass matching events to the next filter and drop those that do not 
match.
+
+To allow for a larger spectrum of behaviors,
+all standard filters, except `CompositeFilter` and `DenyAllFilter`, accept the 
following configuration attributes:
+
+.Common filter configuration attributes
+[cols="1m,1,1,4"]
+|===
+|Attribute |Type | Default value |Description
+
+| [[onMatch]]onMatch
+| 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.Result.html[`Result`]
+| 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.Result.html#NEUTRAL[`NEUTRAL`]
+| Result returned if the condition matches.
+
+| [[onMismatch]]onMismatch
+| 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.Result.html[`Result`]
+| 
link:../javadoc/log4j-core/org/apache/logging/log4j/core/Filter.Result.html#DENY[`DENY`]
+| Result returned if the condition does not match.
+
+|===
+
+[#CompositeFilter]
+=== Composing filters
+
+Filters usually test for a single condition.
+To express a more complex filtering logic, Log4j provides a
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-CompositeFilter[`Filters`]
+plugin.
+This plugin can contain a sequence of filters and has no other configuration 
option.
+
+The `Filters` plugin sequentially evaluates each sub-filter and:
+
+* if the sub-filter returns `ACCEPT` (resp. `DENY`), the `Filters` plugin 
returns `ACCEPT` (resp. `DENY`).
+* if the sub-filter return `NEUTRAL`, the `Filters` plugin evaluates the next 
sub-filter in the chain.
+* if the last sub-filter returns `NEUTRAL`, the `Filters` plugin returns 
`NEUTRAL`.
+
+The `Filters` plugin together with the ternary logic of filters, can be used 
to express all the boolean operators.
+In the following examples `A` and `B` are two filters.
+
+`NOT A`::
+You can invert the functionality of filter `A` by swapping the `onMatch` and 
`onMismatch`:
++
+[source,xml]
+----
+<A onMatch="DENY" onMismatch="NEUTRAL"/>
+----
+
+`A AND B`::
+To select the events that match both `A` and `B` you can use:
++
+[source,xml]
+----
+<Filters>
+  <A/>
+  <B/>
+</Filters>
+----
+
+`A OR B`::
+To select the events that match `A` or `B` we can replace `NEUTRAL` with 
`ACCEPT` in the `onMatch` attribute:
++
+[source,xml]
+----
+<Filters>
+  <A onMatch="ACCEPT"/>
+  <B onMatch="ACCEPT"/>
+</Filters>
+----
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-CompositeFilter[📖
 Plugin reference for `Filters`]
 
 [#collection]
 == Collection
 
-Log4j bundles several predefined filters to assist in several common 
deployment use cases.
-Following sections explain all these in detail.
+Log4j Core provides the following filters out-of-the-box.
+
+[#timestamp-filters]
+=== Timestamp filters
+
+Timestamp filters use the timestamp of log events to decide whether to log 
them or not.
 
 [#BurstFilter]
-=== BurstFilter
+==== `BurstFilter`
 
-The BurstFilter provides a mechanism to control the rate at which LogEvents 
are processed by silently discarding events after the maximum limit has been 
reached.
+The `BurstFilter` uses the _sliding window log_ algorithm to limit the rate of 
log events.
+The rate limit is only applied to log events less severe than a configured log 
level.
 
-.Burst Filter Parameters
-[cols="1m,1,4"]
+Besides the common configuration attributes,
+the `BurstFilter` supports the following parameters:
+
+.`BurstFilter` -- configuration attributes
+[cols="1m,1,1,4"]
 |===
-|Parameter Name |Type |Description
-
-|level
-|String
-|Level of messages to be filtered. Anything at or below
-this level will be filtered out if `maxBurst` has been exceeded. The
-default is WARN meaning any messages that are higher than warn will be
-logged regardless of the size of a burst.
-
-|rate
-|float
-|The average number of events per second to allow.
-
-|maxBurst
-|integer
-|The maximum number of events that can occur before
-events are filtered for exceeding the average rate. The default is 10
-times the rate.
-
-|onMatch
-|String
-|Action to take when the filter matches. Can be ACCEPT,
-DENY or NEUTRAL. The default value is NEUTRAL.
-
-|onMismatch
-|String
-|Action to take when the filter does not match. Can
-be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+|Attribute | Type | Default value | Description
+
+| level
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[`Level`]
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html#WARN[`WARN`]
+| The rate limit only applies to log events less severe than this level.
+Events at least as severe as this level will always match.
+
+| rate
+| `float`
+| `10`
+| The average number of events per second to allow.
+
+| maxBurst
+| `long`
+| `10 &times; rate`
+| The maximum number of events in a sliding window.
+
 |===
 
-A configuration containing the BurstFilter might look like:
+The sliding window can be easily computed as:
 
-[source,xml]
+[stem]
+++++
+wi\ndow = (m\axBurst) / (rate),
+++++
+
+where `window` is the duration of the sliding window in seconds.
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-BurstFilter[📖
 Plugin reference for `BurstFilter`]
+
+[#TimeFilter]
+==== `TimeFilter`
+
+The `TimeFilter` only matches log events emitted during a certain time of the 
day.
+
+Besides the common configuration attributes,
+the `TimeFilter` supports the following parameters:
+
+.`TimeFilter` -- configuration attributes
+[cols="1m,2,1,4"]
+|===
+| Attribute | Type | Default value | Description
+
+| start
+| 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/time/LocalTime.html[`LocalTime`]
 in `HH:mm:ss` format
+| 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/time/LocalTime.html#MIN[`LocalTime.MIN`]
+| The beginning of the time slot.
+
+| start
+| 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/time/LocalTime.html[`LocalTime`]
 in `HH:mm:ss` format
+| 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/time/LocalTime.html#MAX[`LocalTime.MAX`]
+| The end of the time slot.
+
+| timezone
+| 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/time/ZoneId.html[`ZoneId`]
+| 
https://docs.oracle.com/javase/{java-target-version}/docs/api/java/time/ZoneId.html#systemDefault--[`ZoneId.systemDefault()`]
+| The timezone to use when comparing `start` and `end` to the event timestamp.
+
+|===
+
+As a simple application of this filter,
+if you want to forward messages to your console during work hours and to your 
e-mail account after work hours,
+you can use a configuration snippet like:
+
+[tabs]
+====
+XML::
++
+.Snippet from an example 
{antora-examples-url}/manual/filters/TimeFilter.xml[`log4j2.xml`]
+[source,xml,indent=0]
 ----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
-  <Appenders>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>
+include::example$manual/filters/TimeFilter.xml[tag=filter]
 ----
 
-[#CompositeFilter]
-=== CompositeFilter
-
-The CompositeFilter provides a way to specify more than one filter.
-It is added to the configuration as a filter element and contains other 
filters to be evaluated.
-The filter element accepts no parameters.
+JSON::
++
+.Snippet from an example 
{antora-examples-url}/manual/filters/TimeFilter.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/filters/TimeFilter.json[tag=filter]
+----
 
-A configuration containing the CompositeFilter might look like:
+YAML::
++
+.Snippet from an example 
{antora-examples-url}/manual/filters/TimeFilter.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
+----
+include::example$manual/filters/TimeFilter.yaml[tag=filter]
+----
 
-[source,xml]
+Properties::
++
+.Snippet from an example 
{antora-examples-url}/manual/filters/TimeFilter.properties[`log4j2.properties`]
+[source,properties,indent=0]
 ----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
-  <Filters>
-    <MarkerFilter marker="EVENT" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
-    <DynamicThresholdFilter key="loginId" defaultThreshold="ERROR"
-                            onMatch="ACCEPT" onMismatch="NEUTRAL">
-      <KeyValuePair key="User1" value="DEBUG"/>
-    </DynamicThresholdFilter>
-  </Filters>
-  <Appenders>
-    <File name="Audit" fileName="logs/audit.log">
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-    </File>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Logger name="EventLogger" level="info">
-      <AppenderRef ref="Audit"/>
-    </Logger>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>
+include::example$manual/filters/TimeFilter.properties[tag=filter]
 ----
+====
 
-[#DynamicThresholdFilter]
-=== DynamicThresholdFilter
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-TimeFilter[📖
 Plugin reference for `TimeFilter`]
 
-The DynamicThresholdFilter allows filtering by log level based on specific 
attributes.
-For example, if the user's loginId is being captured in the ThreadContext Map 
then it is possible to enable debug logging for only that user.
-If the log event does not contain the specified ThreadContext item NEUTRAL 
will be returned.
+[#level-filters]
+=== Level filters
 
-.Dynamic Threshold Filter Parameters
-[cols="1m,1,4"]
+The following filters allow you to filter log events based on their level.
+
+[#LevelMatchFilter]
+==== `LevelMatchFilter`
+
+The `LevelMatchFilter` matches log events that have exactly a certain log 
level.
+
+Besides the common configuration attributes, the `LevelMatchFilter` supports 
the following parameter:
+
+.`LevelMatchFilter` -- configuration attributes
+[cols="1m,1,1,4"]
 |===
-|Parameter Name |Type |Description
-
-|key
-|String
-|The name of the item in the ThreadContext Map to compare.
-
-|defaultThreshold
-|String
-|Level of messages to be filtered. The default
-threshold only applies if the log event contains the specified
-ThreadContext Map item and its value do not match any key in the
-key/value pairs.
-
-|keyValuePair
-|KeyValuePair[]
-|One or more KeyValuePair elements that
-define the matching value for the key and the Level to evaluate when the
-key matches.
-
-|onMatch
-|String
-|Action to take when the filter matches. Can be ACCEPT,
-DENY or NEUTRAL. The default value is NEUTRAL.
-
-|onMismatch
-|String
-|Action to take when the filter does not match. Can
-be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+| Attribute | Type | Default value | Description
+
+| level
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[`Level`]
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html#ERROR[`ERROR`]
+| The filter only matches log events of this level.
+
 |===
 
-Here is a sample configuration containing the DynamicThresholdFilter:
+[TIP]
+====
+If you wish to use a different log file for each log level, you can also use a
+xref:manual/appenders.adoc#RoutingAppender[`Routing` appender] together with 
the
+xref:manual/lookups.adoc#EventLookup[`${event:Level}` lookup].
+====
 
-[source,xml]
-----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
-  <DynamicThresholdFilter key="loginId" defaultThreshold="ERROR"
-                          onMatch="ACCEPT" onMismatch="NEUTRAL">
-    <KeyValuePair key="User1" value="DEBUG"/>
-  </DynamicThresholdFilter>
-  <Appenders>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>
-----
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-LevelMatchFilter[📖
 Plugin reference for `LevelMatchFilter`]
 
 [#LevelRangeFilter]
-=== LevelRangeFilter
+==== `LevelRangeFilter`
+
+The `LevelRangeFilter` matches log events with a log level within a configured 
range.
 
-`LevelRangeFilter` allows filtering against a level range, where levels get 
compared by their associated integral values; `OFF` has an integral value of 0, 
`FATAL` 100, `ERROR` 200, and so on.
+Besides the common configuration attributes, the `LevelRangeFilter` supports 
the following parameter:
 
-.`LevelRangeFilter` parameters
-[cols="1m,1m,4"]
+.`LevelRangeFilter` -- configuration attributes
+[cols="1m,1,1,4"]
 |===
-|Parameter Name |Type |Description
+| Attribute | Type | Default value | Description
 
-|minLevel
-|Level
-|the minimum level threshold (defaults to `OFF`, which has an integral value 
of 0)
+| minLevel
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[`Level`]
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html#OFF[`OFF`]
+| The filter only matches log events at most as severe as this level.
 
-|maxLevel
-|Level
-|the maximum level threshold (defaults to `ALL`, which has an integral value 
of `Integer.MAX_VALUE`)
+| maxLevel
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[`Level`]
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html#ALL[`ALL`]
+| The filter only matches log events at least as severe as this level.
+
+|===
 
-|onMatch
-|Filter.Result
-|the result to return on a match, where allowed values are `ACCEPT`, `DENY`, 
or `NEUTRAL` (default)
+[TIP]
+====
+Make sure not to invert the bounds of the range.
+Starting from the smallest level, the Log4j API defines: `OFF`, `FATAL`, 
`ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE` and `ALL`.
+====
 
-|onMismatch
-|Filter.Result
-|the result to return on a mismatch, where allowed values are `ACCEPT`, `DENY` 
(default), or `NEUTRAL`
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-LevelRangeFilter[📖
 Plugin reference for `LevelRangeFilter`]
+
+[#ThresholdFilter]
+==== `ThresholdFilter`
+
+The `ThresholdFilter` matches log events at least as severe as a configured 
level.
+
+Besides the common configuration attributes, the `ThresholdFilter` supports 
the following parameter:
+
+.`ThresholdFilter`—configuration attributes
+[cols="1m,1,1,4"]
 |===
+| Attribute | Type | Default value | Description
 
-In the following example configuration, a `LevelRangeFilter` is configured 
with `maxLevel` set to `INFO`.
-The filter will return `onMismatch` result (i.e., `DENY`, the default) for log 
events of level with higher integral values than `INFO`; i.e., `DEBUG`, 
`TRACE`, etc.
+| level
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[`Level`]
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html#OFF[`OFF`]
+| The filter only matches log events at least as severe as this level.
 
-.Example configuration using `LevelRangeFilter`
-[source,xml]
-----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="WARN" name="MyApp">
-  <Appenders>
-    <Console name="STDOUT">
-      <LevelRangeFilter maxLevel="INFO"/>
-      <PatternLayout pattern="%d %p %c{1.} [%t] %m%n"/>
-    </Console>
-  </Appenders>
-  <Loggers>
-    <Root level="ERROR">
-      <AppenderRef ref="STDOUT"/>
-    </Root>
-  </Loggers>
-</Configuration>
-----
+|===
 
-[#MapFilter]
-=== MapFilter
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-ThresholdFilter[📖
 Plugin reference for `ThresholdFilter`]
+
+[#DynamicThresholdFilter]
+==== `DynamicThresholdFilter`
+
+The `DynamicThresholdFilter` is a variant of <<ThresholdFilter>>,
+which uses a different threshold for each log event.
+The effective threshold to use is determined by querying the
+xref:manual/thread-context.adoc[context data]
+of the log event.
+For each log event:
+
+. The filter retrieves the value of `key` in the context data map.
+. The filter checks the list of nested
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-util-KeyValuePair[`KeyValuePair`]
+configuration elements to decide which level to apply.
 
-The MapFilter allows filtering against data elements that are in a MapMessage.
+Besides the common configuration attributes, the `DynamicThresholdFilter` 
supports the following parameters:
 
-.Map Filter Parameters
+.`DynamicThresholdFilter`—configuration attributes
+[cols="1m,1,1,4"]
+|===
+| Attribute | Type | Default value | Description
+
+| key
+| `String`
+|
+| The key to a value in the context map of the log event.
+
+**Required**
+
+| defaultThreshold
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html[`Level`]
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Level.html#ERROR[`ERROR`]
+| Threshold to apply to log events that don't have a corresponding 
`KeyValuePair`.
+
+|===
+
+.`DynamicThresholdFilter`—nested elements
 [cols="1m,1,4"]
 |===
-|Parameter Name |Type |Description
-
-|keyValuePair
-|KeyValuePair[]
-|One or more KeyValuePair elements that
-define the key in the map and the value to match. If the same key is
-specified more than once then the check for that key will automatically
-be an "or" since a Map can only contain a single value.
-
-|operator
-|String
-|If the operator is "or" then a match by any one of
-the key/value pairs will be considered to be a match, otherwise all the
-key/value pairs must match.
-
-|onMatch
-|String
-|Action to take when the filter matches. Can be ACCEPT,
-DENY or NEUTRAL. The default value is NEUTRAL.
-
-|onMismatch
-|String
-|Action to take when the filter does not match. Can
-be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+| Type | Multiplicity | Description
+
+| 
xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-util-KeyValuePair[`KeyValuePair`]
+| One or more
+| Associates a log level with the context map value associated with `key`.
+
 |===
 
-As in this configuration, the MapFilter can be used to log particular events:
+For example, if `loginId` contains the login of the current user,
+you can use this configuration to apply different thresholds to different 
users:
 
-[source,xml]
+[tabs]
+====
+XML::
++
+.Snippet from an example 
{antora-examples-url}/manual/filters/DynamicThresholdFilter.xml[`log4j2.xml`]
+[source,xml,indent=0]
+----
+include::example$manual/filters/DynamicThresholdFilter.xml[tag=filter]
 ----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
-  <MapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
-    <KeyValuePair key="eventId" value="Login"/>
-    <KeyValuePair key="eventId" value="Logout"/>
-  </MapFilter>
-  <Appenders>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>
-----
-
-This sample configuration will exhibit the same behavior as the preceding 
example since the only logger configured is the root.
 
-[source,xml]
+JSON::
++
+.Snippet from an example 
{antora-examples-url}/manual/filters/DynamicThresholdFilter.json[`log4j2.json`]
+[source,json,indent=0]
+----
+include::example$manual/filters/DynamicThresholdFilter.json[tag=filter]
 ----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
-  <Appenders>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <MapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
-        <KeyValuePair key="eventId" value="Login"/>
-        <KeyValuePair key="eventId" value="Logout"/>
-      </MapFilter>
-      <AppenderRef ref="RollingFile">
-      </AppenderRef>
-    </Root>
-  </Loggers>
-</Configuration>
-----
-
-This third sample configuration will exhibit the same behavior as the 
preceding examples since the only logger configured is the root and the root is 
only configured with a single appender reference.
 
-[source,xml]
+YAML::
++
+.Snippet from an example 
{antora-examples-url}/manual/filters/DynamicThresholdFilter.yaml[`log4j2.yaml`]
+[source,yaml,indent=0]
 ----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
-  <Appenders>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile">
-        <MapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
-          <KeyValuePair key="eventId" value="Login"/>
-          <KeyValuePair key="eventId" value="Logout"/>
-        </MapFilter>
-      </AppenderRef>
-    </Root>
-  </Loggers>
-</Configuration>
+include::example$manual/filters/DynamicThresholdFilter.yaml[tag=filter]
 ----
 
+Properties::
++
+.Snippet from an example 
{antora-examples-url}/manual/filters/DynamicThresholdFilter.properties[`log4j2.properties`]
+[source,properties,indent=0]
+----
+include::example$manual/filters/DynamicThresholdFilter.properties[tag=filter]
+----
+====
+
+<1> If the `loginId` is `alice` a threshold level of `DEBUG` will be used.
+<2> If the `loginId` is `bob` a threshold level of `INFO` will be used.
+<3> For all the other values of `loginId` a threshold level of `ERROR` will be 
used.
+
+[TIP]
+====
+You can use Log4j Core's
+xref:manual/configuration.adoc#configuration-attribute-monitorInterval[automatic
 reconfiguration feature]
+to modify the ``KeyValuePair``s without restarting your application.
+====
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-DynamicThresholdFilter[📖
 Plugin reference for `DynamicThresholdFilter`]
+
+[#marker-filters]
+=== Marker filters
+
+The following filters use the
+xref:manual/markers.adoc[log event marker]
+to filter log events.
+
+[#NoMarkerFilter]
+==== `NoMarkerFilter`
+
+The `NoMarkerFilter` matches log events that do not have any markers.
+
+This filter does not have any additional configuration attribute, except the 
common attributes.
+
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-NoMarkerFilter[📖
 Plugin reference for `NoMarkerFilter`]
+
 [#MarkerFilter]
-=== MarkerFilter
+==== `MarkerFilter`
 
-The MarkerFilter compares the configured Marker value against the Marker that 
is included in the LogEvent.
-A match occurs when the Marker name matches either the Log Event's Marker or 
one of its parents.
+The `MarkerFilter` matches log events marked with a specific marker or **any** 
of its descendants.
 
-.Marker Filter Parameters
-[cols="1m,1,4"]
+Besides the common configuration attributes, the `MarkerFilter` supports the 
following parameter:
+
+.`MarkerFilter`—configuration attributes
+[cols="1m,1,1,4"]
 |===
-|Parameter Name |Type |Description
+|Attribute | Type | Default value | Description
 
-|marker
-|String
-|The name of the Marker to compare.
+| marker
+| link:../javadoc/log4j-api/org/apache/logging/log4j/Marker.html[`Marker`]
+|
+| The filter only matches log events of marker with the given marker or one of 
its descendants.
 
-|onMatch
-|String
-|Action to take when the filter matches. Can be ACCEPT,
-DENY or NEUTRAL. The default value is NEUTRAL.
+**Required**
 
-|onMismatch
-|String
-|Action to take when the filter does not match. Can
-be ACCEPT, DENY or NEUTRAL. The default value is DENY.
 |===
 
-A sample configuration that only allows the event to be written by the 
appender if the Marker matches:
+xref:plugin-reference.adoc#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-filter-MarkerFilter[📖
 Plugin reference for `MarkerFilter`]
 
-[source,xml]
-----
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp">
-  <Appenders>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="DENY"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>
-----
+[#message-filters]
+=== Message filters
 
-[#MutableThreadContextMapFilter]
-=== MutableThreadContextMapFilter
+Message filters allow filtering log events based on the
+xref:manual/messages.adoc[`Message`]
+contained in the log event.
 
-The MutableThreadContextMapFilter or MutableContextMapFilter allows filtering 
against data elements that are in the current context.
-By default, this is the ThreadContext Map.
-The values to compare are defined externally and can be periodically polled 
for changes.
+include::partial$manual/log-event.adoc[]
 
-.Mutable Context Map Filter Parameters
-[cols="1m,1,4"]
+[#RegexFilter]
+==== `RegexFilter`
+
+The `RegexFilter` matches a regular expression against either the result of
+link:../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html#getFormat()[`Message.getFormat()`]
+or
+link:../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html#getFormat()[`Message.getFormattedMessage()`].

Review Comment:
   Fixed in 4d0d7aa6c4c2ca8f9ad92621e50f8b513e59ec71.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to