Filters
Filters are Log4j plugins that evaluate the parameters of a logging call or a log event and return one of three results:
- ACCEPT
-
The filter accepts the log event. This effectively causes other filters in the same filtering stage to be skipped.
- DENY
-
The filter drops the log event.
- NEUTRAL
-
Log4j behaves as if the filter was not present. It is evaluated by the next filter in the filter chain.
Filters can be used at each level of the logging pipeline:
-
the global configuration element can contain a global filter.
-
each logger configuration element can contain a logger filter.
-
each appender reference configuration element can contain an appender reference filter.
-
each appender configuration element can contain an appender filter.
Additionally, the following configuration attributes take part in the filtering process:
-
the
level
attribute of logger configuration elements. -
the
level
attribute of appender reference configuration elements.
Filtering process
Due to the interaction of many elements, the filtering process in Log4j is quite complex and can be divided in four stages:
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. |
1. Logger
stage
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
LogEvent
is created and processing continues. - ACCEPT
-
A
LogEvent
is created and processing continues in the next stage.
This is the only stage, which differentiates between an |
Filtering logging calls at this stage provides the best performance:
|
2. LoggerConfig
stage
In this stage, log events are evaluated by all the logger filters that stand on the path from the logger to an appender. Due to the 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.
3. AppenderControl
stage
To pass this stage, log events must satisfy both conditions:
-
the log event must be at least as severe as the
level
attribute of the appender reference. -
the appender reference filter must return
ACCEPT
orNEUTRAL
,
4. Appender
stage (optional)
If the appender implements
Filterable
an additional filtering stage is available.
When log events reach such an appender,
the filter attached to an appender is evaluated and if the result is DENY
,
the log event is discarded.
All standard appenders implement Filterable
.
Some appenders like the
asynchronous appender
use appender references to transfer log events to other appenders.
In such a case, the filtering process goes back to the |
Users migrating from Log4j 1 often replace the Using the |
Configuring filters at this stage 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. |
Example configuration file
The following example configuration file employs filters at all possible stages to explain their evaluation order:
-
XML
-
JSON
-
YAML
-
Properties
<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="https://logging.apache.org/xml/ns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
https://logging.apache.org/xml/ns
https://logging.apache.org/xml/ns/log4j-config-2.xsd">
<Appenders>
<Console name="CONSOLE">
<ThresholdFilter level="FATAL"/> (7)
</Console>
</Appenders>
<Loggers>
<Root level="OFF">
<ThresholdFilter level="WARN"/> (4)
<AppenderRef ref="CONSOLE" level="ERROR"> (5)
<MarkerFilter marker="SECURITY_ALERT"/> (6)
</AppenderRef>
</Root>
<Logger name="org.example" level="DEBUG"> (2)
<ThresholdFilter level="INFO"/> (3)
</Logger>
</Loggers>
<MarkerFilter marker="ALERT"
onMatch="ACCEPT"
onMismatch="NEUTRAL"/> (1)
</Configuration>
{
"Configuration": {
"Appenders": {
"Console": {
"name": "CONSOLE",
"ThresholdFilter": {
"level": "FATAL" (6)
}
}
},
"Loggers": {
"Root": {
"level": "OFF",
"ThresholdFilter": { (3)
"level": "WARN"
},
"AppenderRef": {
"ref": "CONSOLE",
"level": "ERROR", (4)
"MarkerFilter": { (5)
"marker": "SECURITY_ALERT"
}
}
},
"Logger": {
"name": "org.example",
"level": "DEBUG", (2)
"ThresholdFilter": { (3)
"level": "INFO"
}
}
}
},
"MarkerFilter": { (1)
"marker": "ALERT",
"onMatch": "ACCEPT",
"onMismatch": "NEUTRAL"
}
}
Configuration:
Appenders:
Console:
name: "CONSOLE"
ThresholdFilter: (7)
level: "FATAL"
Loggers:
Root:
level: "OFF"
ThresholdFilter: (4)
level: "WARN"
AppenderRef:
ref: "CONSOLE"
level: "ERROR" (5)
MarkerFilter: (6)
marker: "SECURITY_ALERT"
Logger:
name: "org.example"
level: "DEBUG" (2)
ThresholdFilter: (3)
level: "INFO"
MarkerFilter: (1)
marker: "ALERT"
onMatch: "ACCEPT"
onMismatch: "NEUTRAL"
appender.0.type = Console
appender.0.name = CONSOLE
(7)
appender.0.filter.type = ThresholdFilter
appender.0.filter.level = FATAL
rootLogger.level = OFF
(4)
rootLogger.filter.type = ThresholdFilter
rootLogger.filter.level = WARN
rootLogger.appenderRef.0.ref = CONSOLE
(5)
rootLogger.appenderRef.0.level = ERROR
(6)
rootLogger.appenderRef.0.filter.type = MarkerFilter
rootLogger.appenderRef.0.filter.marker = SECURITY_ALERT
logger.0.name = org.example
(2)
logger.0.level = DEBUG
(3)
logger.0.filter.type = ThresholdFilter
logger.0.filter.level = INFO
(1)
filter.0.type = MarkerFilter
filter.0.marker = ALERT
filter.0.onMatch = ACCEPT
filter.0.onMismatch = NEUTRAL
1 | Global filter |
2 | Logger level attribute. This setting is ignored unless the global filter returns NEUTRAL . |
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 |
Common configuration
Common configuration attributes
The default behavior of filters is in line with the filter()
methods of functional interfaces, such as
Optional.filter()
or
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:
Attribute | Type | Default value | Description |
---|---|---|---|
Result returned if the condition matches. |
|||
Result returned if the condition does not match. |
Composing filters
Filters usually test for a single condition.
To express a more complex filtering logic, Log4j provides a
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
), theFilters
plugin returnsACCEPT
(resp.DENY
). -
if the sub-filter return
NEUTRAL
, theFilters
plugin evaluates the next sub-filter in the chain. -
if the last sub-filter returns
NEUTRAL
, theFilters
plugin returnsNEUTRAL
.
The Filters
plugin together with the ternary logic of filters, can be used to express most boolean operators.
In the following examples A
and B
are two filters.
NOT A
-
You can invert the functionality of filter
A
by swapping theonMatch
andonMismatch
:<A onMatch="DENY" onMismatch="NEUTRAL"/>
A AND B
-
To select the events that match both
A
andB
you can use:<Filters> <A/> <B/> </Filters>
A OR B
-
To select the events that match
A
orB
we can replaceNEUTRAL
withACCEPT
in theonMatch
attribute:<Filters> <A onMatch="ACCEPT"/> <B onMatch="ACCEPT"/> </Filters>
Collection
Log4j Core provides the following filters out-of-the-box.
Timestamp filters
Timestamp filters use the timestamp of log events to decide whether to accept them or not.
BurstFilter
The BurstFilter
limits the rate of log events.
The rate limit is only applied to log events less severe than a configured log level.
Besides the common configuration attributes,
the BurstFilter
supports the following parameters:
Attribute | Type | Default value | Description |
---|---|---|---|
|
The rate limit only applies to log events less severe than this level. Events at least as severe as this level will always match. |
||
|
|
|
The average number of events per second to allow. |
|
|
|
The maximum number of events that can be logged at once, without incurring in rate limiting. |
The The filter maintains a list of recently logged events.
If in the interval of time of duration To control the size of the log files only the |
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:
Attribute | Type | Default value | Description |
---|---|---|---|
|
|
The beginning of the time slot. |
|
|
|
The end of the time slot. |
|
|
The timezone to use when comparing |
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:
-
XML
-
JSON
-
YAML
-
Properties
log4j2.xml
<AppenderRef ref="CONSOLE">
<TimeFilter start="08:00:00" end="16:00:00"/>
</AppenderRef>
<AppenderRef ref="SMTP">
<TimeFilter start="16:00:00" end="08:00:00"/>
</AppenderRef>
log4j2.json
"AppenderRef": [
{
"ref": "CONSOLE",
"TimeFilter": {
"start": "08:00:00",
"end": "16:00:00"
}
},
{
"ref": "SMTP",
"TimeFilter": {
"start": "16:00:00",
"end": "08:00:00"
}
}
]
log4j2.yaml
AppenderRef:
- ref: "CONSOLE"
TimeFilter:
start: "08:00:00"
end: "16:00:00"
- ref: "SMTP"
TimeFilter:
start: "16:00:00"
end: "08:00:00"
log4j2.properties
rootLogger.appenderRef.0.ref = CONSOLE
rootLogger.appenderRef.0.filter.0.type = TimeFilter
rootLogger.appenderRef.0.filter.0.start = 08:00:00
rootLogger.appenderRef.0.filter.0.end = 16:00:00
rootLogger.appenderRef.1.ref = SMTP
rootLogger.appenderRef.1.filter.0.type = TimeFilter
rootLogger.appenderRef.1.filter.0.start = 16:00:00
rootLogger.appenderRef.1.filter.0.end = 08:00:00
Level filters
The following filters allow you to filter log events based on their levels.
LevelMatchFilter
The LevelMatchFilter
matches log events that have exactly a certain log level.
Besides the common configuration attributes,
the LevelMatchFilter
supports the following parameter:
Attribute | Type | Default value | Description |
---|---|---|---|
|
The filter only matches log events of this level. |
If you wish to use a different log file for each log level, you should also use a
|
LevelRangeFilter
The LevelRangeFilter
matches log events with a log level within a configured range.
Besides the common configuration attributes,
the LevelRangeFilter
supports the following parameter:
Attribute | Type | Default value | Description |
---|---|---|---|
|
The filter only matches log events at most as severe as this level. |
||
|
The filter only matches log events at least as severe as this level. |
Make sure not to invert the bounds of the range.
Starting from the smallest level,
the Log4j API defines: |
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:
Attribute | Type | Default value | Description |
---|---|---|---|
|
The filter only matches log events at least as severe as this level. |
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
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
KeyValuePair
configuration elements to decide which level to apply.
Besides the common configuration attributes,
the DynamicThresholdFilter
supports the following parameters:
Attribute | Type | Default value | Description |
---|---|---|---|
|
|
The key to a value in the context map of the log event. Required |
|
|
Threshold to apply to log events that don’t have a corresponding |
Type | Multiplicity | Description |
---|---|---|
One or more |
Associates a log level with the context map value associated with |
For example, if loginId
contains the login of the current user,
you can use this configuration to apply different thresholds to different users:
-
XML
-
JSON
-
YAML
-
Properties
log4j2.xml
<DynamicThresholdFilter key="loginId"
defaultThreshold="ERROR"> (3)
<KeyValuePair key="alice" value="DEBUG"/> (1)
<KeyValuePair key="bob" value="INFO"/> (2)
</DynamicThresholdFilter>
log4j2.json
"DynamicThresholdFilter": {
"key": "loginId", (3)
"defaultThreshold": "ERROR",
"KeyValuePair": [
{ (1)
"key": "alice",
"value": "DEBUG"
},
{ (2)
"key": "bob",
"value": "INFO"
}
]
}
log4j2.yaml
DynamicThresholdFilter:
key: "loginId"
defaultThreshold: "ERROR" (3)
KeyValuePair:
- key: "alice" (1)
value: "DEBUG"
- key: "bob" (2)
value: "INFO"
log4j2.properties
filter.0.type = DynamicThresholdFilter
filter.0.key = loginId
(3)
filter.0.defaultThreshold = ERROR
(1)
filter.0.kv0.type = KeyValuePair
filter.0.kv0.key = alice
filter.0.kv0.value = DEBUG
(2)
filter.0.kv1.type = KeyValuePair
filter.0.kv1.key = bob
filter.0.kv1.value = INFO
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. |
You can use Log4j Core’s
automatic reconfiguration feature
to modify the |
Marker filters
The following filters use the log event marker to filter log events.
NoMarkerFilter
The NoMarkerFilter
matches log events that do not have any markers.
This filter does not have any additional configuration attribute, except the common configuration attributes.
MarkerFilter
The MarkerFilter
matches log events marked with a specific marker or any of its descendants.
Besides the common configuration attributes,
the MarkerFilter
supports the following parameter:
Attribute | Type | Default value | Description |
---|---|---|---|
|
The filter only matches log events of marker with the given marker or one of its descendants. Required |
Message filters
Message filters allow filtering log events based on the
Message
contained in the log event.
Log messages are often used interchangeably with log events.
While this simplification holds for several cases, it is not technically correct.
A log event, capturing the logging context (level, logger name, instant, etc.) along with the log message, is generated by the logging implementation (e.g., Log4j Core) when a user issues a log using a logger, e.g., Click for an introduction to log event fieldsLog events contain fields that can be classified into three categories:
For clarity’s sake let us look at a log event formatted as JSON:
|
RegexFilter
The RegexFilter
matches a regular expression against messages.
Besides the common configuration attributes, the RegexFilter
supports the following parameters:
Attribute | Type | Default value | Description |
---|---|---|---|
|
The regular expression used to match log messages. Required |
||
|
|
|
If |
|
StringMatchFilter
The StringMatchFilter
matches a log event, if its message contains the given string.
Besides the common configuration attributes,
the StringMatchFilter
supports the following parameters:
Attribute | Type | Default value | Description |
---|---|---|---|
|
|
The text to look for. Required |
This filter decreases performance, since it forces the formatting of all log messages, including the disabled ones. |
Map filters
The following filters match log events based on the content of one of these map structures:
-
The map contained in a
MapMessage
object. SeeMapMessage.getData()
for details. -
The context data map contained in a
LogEvent
. SeeLogEvent.getContextData()
for details.
Configuration map
These filters are configured with a configuration map of type Map<String, String[]>
,
which,
depending on the filter,
is encoded as either JSON:
{
"configs": {
"clientId": [
"1234"
],
"userId": [
"alice",
"bob"
]
}
}
or as a sequence of
KeyValuePair
plugins:
<KeyValuePair key="clientId" value="1234"/>
<KeyValuePair key="userId" value="alice"/>
<KeyValuePair key="userId" value="bob"/>
The configuration map associates to each key a list of allowed values for that key.
In the example above the allowed values for the loginId
key are either alice
or bob
.
The only allowed value for the clientId
key is 1234
.
The map filters can work in two matching modes:
- AND
-
A map structure matches if the value associated with each key that appears in the configuration map is one of the allowed values.
- OR
-
A map structure matches if the value associated with at least one key that appears in the configuration map is one of the allowed values.
MapFilter
The MapFilter
allows filtering based on the contents of all
structured Message
s.
This filter encodes the Configuration map introduced above as a list of
KeyValuePair
elements.
Besides the common configuration attributes,
the MapFilter
supports the following parameters:
Attribute | Type | Default value | Description |
---|---|---|---|
|
enumeration |
|
Type | Multiplicity | Description |
---|---|---|
One or more |
Adds a value as allowed value for a key. See Configuration map for more details. |
For example,
if you want to filter all MapMessage
s
that have an eventType
key with value authentication
and an eventId
key with value either login
or logout
,
you can use the following configuration:
-
XML
-
JSON
-
YAML
-
Properties
log4j2.xml
<MapFilter operator="AND">
<KeyValuePair key="eventType" value="authentication"/>
<KeyValuePair key="eventId" value="login"/>
<KeyValuePair key="eventId" value="logout"/>
</MapFilter>
log4j2.json
"MapFilter": {
"operator": "AND",
"KeyValuePair": [
{
"key": "eventType",
"value": "authentication"
},
{
"key": "eventId",
"value": "login"
},
{
"key": "eventId",
"value": "logout"
}
]
}
log4j2.yaml
MapFilter:
operator: "AND"
KeyValuePair:
- key: "eventType"
value: "authentication"
- key: "eventId"
value: "login"
- key: "eventId"
value: "logout"
log4j2.properties
filter.0.type = MapFilter
filter.0.operator = AND
filter.0.kv0.type = KeyValuePair
filter.0.kv0.key = eventType
filter.0.kv0.value = authentication
filter.0.kv1.type = KeyValuePair
filter.0.kv1.key = eventId
filter.0.kv1.value = login
filter.0.kv2.type = KeyValuePair
filter.0.kv2.key = eventId
filter.0.kv2.value = logout
You can use Log4j Core’s
automatic reconfiguration feature
to modify the |
StructuredDataFilter
The StructuredDataFilter
is a variant of MapFilter
that only matches
StructureDataMessage
s.
In addition to matching the map structure contained in a StructuredDataMessage
(which corresponds to RFC 5424 SD-PARAM
elements)
it provides the following virtual keys:
Key | RFC5424 field | Description |
---|---|---|
|
The
|
|
|
The
|
|
|
The
|
|
|
The result of a
|
The StructuredDataFilter
encodes the Configuration map introduced above as a list of
KeyValuePair
and supports the following parameters,
besides the common configuration attributes:
Attribute | Type | Default value | Description |
---|---|---|---|
|
enumeration |
|
Type | Multiplicity | Description |
---|---|---|
One or more |
Adds a value as allowed value for a key. See Configuration map for more details. |
If you want
to match all log messages with an SD-ID
equal to authentication
and the value of the userId
SD-PARAM
equal to either alice
or bob
,
you can use the following configuration:
-
XML
-
JSON
-
YAML
-
Properties
log4j2.xml
<StructuredDataFilter operator="AND">
<KeyValuePair key="id" value="authentication"/>
<KeyValuePair key="userId" value="alice"/>
<KeyValuePair key="userId" value="bob"/>
</StructuredDataFilter>
log4j2.json
"StructuredDataFilter": {
"operator": "AND",
"KeyValuePair": [
{
"key": "id",
"value": "authentication"
},
{
"key": "userId",
"value": "alice"
},
{
"key": "userId",
"value": "bob"
}
]
}
log4j2.yaml
StructuredDataFilter:
operator: "AND"
KeyValuePair:
- key: "id"
value: "authentication"
- key: "userId"
value: "alice"
- key: "userId"
value: "bob"
log4j2.properties
filter.0.type = StructuredDataFilter
filter.0.operator = AND
filter.0.kv0.type = KeyValuePair
filter.0.kv0.key = id
filter.0.kv0.value = authentication
filter.0.kv1.type = KeyValuePair
filter.0.kv1.key = userId
filter.0.kv1.value = alice
filter.0.kv2.type = KeyValuePair
filter.0.kv2.key = userId
filter.0.kv2.value = bob
You can use Log4j Core’s
automatic reconfiguration feature
to modify the |
ContextMapFilter
The ContextMapFilter
works in the same way as the MapFilter
above,
except it checks the
context map data
of the log event instead of the log message.
This filter also encodes the Configuration map introduced above as a list of
KeyValuePair
elements.
Besides the common configuration attributes,
the ContextMapFilter
supports the following parameters:
Attribute | Type | Default value | Description |
---|---|---|---|
|
enumeration |
|
Type | Multiplicity | Description |
---|---|---|
One or more |
Adds a value as allowed value for a key. See Configuration map for more details. |
For example,
if the clientId
and userId
keys in the context data map identify your client and his end users,
you can filter the log events generated by users alice
and bob
of client 1234
using this configuration:
-
XML
-
JSON
-
YAML
-
Properties
log4j2.xml
<ContextMapFilter operator="AND">
<KeyValuePair key="clientId" value="1234"/>
<KeyValuePair key="userId" value="alice"/>
<KeyValuePair key="userId" value="bob"/>
</ContextMapFilter>
log4j2.json
"ContextMapFilter": {
"operator": "AND",
"KeyValuePair": [
{
"key": "clientId",
"value": "1234"
},
{
"key": "userId",
"value": "alice"
},
{
"key": "userId",
"value": "bob"
}
]
}
log4j2.yaml
ContextMapFilter:
operator: "AND"
KeyValuePair:
- key: "clientId"
value: "1234"
- key: "userId"
value: "alice"
- key: "userId"
value: "bob"
log4j2.properties
filter.0.type = ContextMapFilter
filter.0.operator = AND
filter.0.kv0.type = KeyValuePair
filter.0.kv0.key = clientId
filter.0.kv0.value = 1234
filter.0.kv1.type = KeyValuePair
filter.0.kv1.key = userId
filter.0.kv1.value = alice
filter.0.kv2.type = KeyValuePair
filter.0.kv2.key = userId
filter.0.kv2.value = bob
You can use Log4j Core’s
automatic reconfiguration feature
to modify the |
MutableContextMapFilter
The MutableContextMapFilter
is an alternative version of ContextMapFilter
that also uses the
context data map
to filter messages, but externalizes the Configuration map, so it can be kept in a separate location.
This filter encodes the Configuration map as JSON. The configuration map must be stored in an external location and will be regularly polled for changes.
Besides the common configuration attributes,
the MutableContextMapFilter
supports the following parameters:
Attribute | Type | Default value | Description |
---|---|---|---|
|
The location of the JSON Configuration map. Required |
||
|
|
|
Determines the polling interval used by Log4j to check for changes to the configuration map. If set to |
Unlike other map filters that have a configurable matching mode, this filter always uses the OR matching mode. |
To use this filter, you need to:
-
Create a JSON configuration map and place it at a known location (e.g.
https://server.example/configs.json
):{ "configs": { "clientId": [ "1234" (1) ], "userId": [ "root" (2) ] } }
1 The filter will match all events for client 1234
regardless of theuserId
.2 The filter will match all events for the root
account regardless of theclientId
. -
Reference the configuration map location in your configuration file:
-
XML
-
JSON
-
YAML
-
Properties
Snippet from an examplelog4j2.xml
<MutableContextMapFilter configLocation="https://server.example/configs.json" pollInterval="10"/>
Snippet from an examplelog4j2.json
"MutableContextMapFilter": { "configLocation": "https://server.example/configs.json", "pollInterval": 10 }
Snippet from an examplelog4j2.yaml
MutableContextMapFilter: configLocation: "https://server.example/configs.json" pollInterval: 10
Snippet from an examplelog4j2.properties
filter.0.type = MutableContextMapFilter filter.0.configLocation = https://server.example/configs.json filter.0.pollInterval = 10
-
Other filters
DenyFilter
The DenyFilter
always returns DENY
.
It does not support any configuration attribute, even the common configuration attributes.
ScriptFilter
The ScriptFilter
executes a script that must return true
if the event matches and false
otherwise.
Besides the common configuration attributes, it accepts a single nested element:
Type | Multiplicity | Description |
---|---|---|
one |
A reference to the script to execute. See Scripts for more details about scripting. |
Additional runtime dependencies are required to use ScripFilter
-
Maven
-
Gradle
We assume you use log4j-bom
for dependency management.
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-script</artifactId>
<scope>runtime</scope>
</dependency>
We assume you use log4j-bom
for dependency management.
runtimeOnly 'org.apache.logging.log4j:log4j-script'
The bindings available to the script depend
on whether the ScriptFilter
is used as a global filter in the Logger stage or in the remaining stages.
For global filters, the following bindings are available:
Binding name | Type | Description |
---|---|---|
|
The logger used in the log statement. |
|
|
The level used in the log statement. |
|
|
The marker used in the log statement. |
|
|
The message used in the log event if the user directly supplied one. Otherwise:
|
|
|
|
The parameters passed to the logging call.
Some logging calls include the parameters as part of |
|
|
The |
|
The |
For the remaining filters, only these bindings are available:
Binding name | Type | Description |
---|---|---|
|
The log event being processed. |
|
|
The |
As an example, if you wish to match only log events that contain a certain exception, you can use a simple Groovy script:
scripts/local.groovy
return logEvent.throwable instanceof DataAccessException;
You can then integrate the script in a Log4j configuration:
-
XML
-
JSON
-
YAML
-
Properties
log4j2.xml
<Root level="ALL">
<ScriptFilter>
<ScriptFile language="groovy" path="scripts/local.groovy"/>
</ScriptFilter>
<AppenderRef ref="CONSOLE"/>
</Root>
log4j2.json
"Root": {
"level": "ALL",
"ScriptFilter": {
"ScriptFile": {
"language": "groovy",
"path": "scripts/local.groovy"
}
},
"AppenderRef": {
"ref": "CONSOLE"
}
}
log4j2.yaml
Root:
level: "ALL"
ScriptFilter:
ScriptFile:
language: "groovy"
path: "scripts/local.groovy"
AppenderRef:
ref: "CONSOLE"
log4j2.properties
rootLogger.level = ALL
rootLogger.filter.0.type = ScriptFilter
rootLogger.filter.0.script.type = ScriptFile
rootLogger.filter.0.script.language = groovy
rootLogger.filter.0.script.path = scripts/local.groovy
rootLogger.appenderRef.0.ref = CONSOLE
Writing an equivalent global script is a little bit more complex, since you need to take into account all the places where a throwable can be passed as a parameter. The script becomes:
scripts/global.groovy
Throwable lastParam = parameters?.last() instanceof Throwable ? parameters.last() : null
Throwable actualThrowable = throwable ?: message?.throwable ?: lastParam
return actualThrowable instanceof DataAccessException
You can use it as a global filter:
-
XML
-
JSON
-
YAML
-
Properties
log4j2.xml
<ScriptFilter>
<ScriptFile language="groovy" path="scripts/global.groovy"/>
</ScriptFilter>
log4j2.json
"ScriptFilter": {
"ScriptFile": {
"language": "groovy",
"path": "scripts/global.groovy"
}
}
log4j2.yaml
ScriptFilter:
ScriptFile:
language: "groovy"
path: "scripts/global.groovy"
log4j2.properties
filter.0.type = ScriptFilter
filter.0.script.type = ScriptFile
filter.0.script.language = groovy
filter.0.script.path = scripts/global.groovy
Extending
Filters are plugins implementing the Filter
interface.
This section will guide you on how to create custom ones.
While the predefined filter collection should address most common use cases, you might find yourself needing to implement a custom one. If this is the case, we really appreciate it if you can share your use case in a user support channel. |
Plugin preliminaries
Log4j plugin system is the de facto extension mechanism embraced by various Log4j components. Plugins make it possible for extensible components to receive feature implementations without any explicit links in between. It is analogous to a dependency injection framework, but curated for Log4j-specific needs.
In a nutshell, you annotate your classes with @Plugin
and their (static
) factory methods with @PluginFactory
.
Last, you inform the Log4j plugin system to discover these custom classes.
This is done using running the PluginProcessor
annotation processor while building your project.
Refer to Plugins for details.
Extending filters
Filters are plugins
implementing the Filter
interface.
We recommend users
to extend from AbstractFilter
,
which provides implementation convenience.
While annotating your filter with @Plugin
, you need to make sure that
-
It has a unique
name
attribute across all availableFilter
plugins -
The
category
attribute is set toNode.CATEGORY
You can check out the following files for examples:
-
MarkerFilter.java
–MarkerFilter
matching on markers associated with the effectiveLogEvent
in the context -
RegexFilter.java
–RegexFilter
matching on the message associated with the effectiveLogEvent
in the context