Will Log4j2 support pre-level-check dynamic log filtering (similar to Logback's TurboFilter
I’ve been researching per-request dynamic logging and came across a limitation in Log4j2’s filtering model compared to Logback.
In Logback, the TurboFilter feature allows log events to be conditionally filtered before the logger’s level check is applied. This enables powerful use cases like enabling DEBUG logs for specific requests, even when the logger’s configured level is INFO.
From my understanding and recent testing, Log4j2 does not currently support this behavior. Specifically:
If a logger is configured at INFO, then all DEBUG messages are short-circuited before any Filter or ThreadContext logic is evaluated.
As a result, it's not currently possible to emit DEBUG logs on a per-request basis using MDC or filters without globally lowering the logger level to DEBUG first.
My question is:
Are there any plans for Log4j2 to support pre-level-check filtering (similar to Logback’s TurboFilter), to allow dynamic log level evaluation per request or thread context?
I understand this design may be for performance reasons, but it would be helpful to know if this kind of feature is on the roadmap or technically feasible within the current architecture.
Thank you for your excellent work on Log4j2, and I appreciate your time and insights.
Best regards,
Amy
Hi @little-hue,
Log4j Core does support pre-level-check filtering, and it has since version 2.0.
While it doesn’t use the term TurboFilter like Logback, the equivalent functionality is implemented via what we call global filters — filters defined directly under the <Configuration> element. These are evaluated before the logger’s level check and can accept or deny events regardless of the configured log level.
Example: Accepting Specific Events Regardless of Logger Level
Here’s a minimal example that unconditionally accepts log events with the marker "AUDIT", even if the logger level is set higher than the event level:
<Configuration xmlns="https://logging.apache.org/xml/ns">
<Appenders>
<Console name="CONSOLE"/>
</Appenders>
<!-- Global filter: evaluated before any level checks -->
<MarkerFilter marker="AUDIT" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<Loggers>
<!-- The event is accepted immediately if the global filter returns ACCEPT.
If it returns NEUTRAL, the logger level check still applies. -->
<Root level="WARN">
<AppenderRef ref="CONSOLE"/>
</Root>
</Loggers>
</Configuration>
With this setup, even DEBUG-level events tagged with marker "AUDIT" will be logged, despite the logger being set to WARN.
For More Information
Log4j Core supports four types of filters and two types of level checks. The official Filters documentation provides a detailed explanation — including a comprehensive example demonstrating all filtering mechanisms working together.