Log4j2 Filter particular level in apender
Asked Answered
N

7

14

What filter should I use to define particular level to be logged with appender? For example:

java:

LOGGER.debug("Debug message");
LOGGER.info("Info message");
LOGGER.warn("Warn message");
LOGGER.error("Error message");
LOGGER.fatal("Fatal message");

log4j2.xml:

<Configuration>
    <Appenders>
        <Console name="info-stdout-message">
            <PatternLayout pattern="[%logger{36}] %message %n" />
            <ThresholdFilter level="info"/>
        </Console>

        <Console name="detailed-stdout-message">
            <PatternLayout pattern="[%logger{36}] [%level] %message %n" />
        </Console>

        <File name="file-appender" fileName="logs/debug.log">
            <PatternLayout pattern="%d{HH:mm:ss dd.mm} [%t] [%-5level] %logger{36} - %msg %n" />
        </File>
    </Appenders>

    <Loggers>
        <Root level="debug">
            <AppenderRef ref="file-appender" level="debug" />
            <AppenderRef ref="info-stdout-message" level="info"/>
            <AppenderRef ref="detailed-stdout-message" level="info"/>
        </Root>
    </Loggers>
</Configuration>

The file output is fine, but in console I have such result:

[application.Main] [INFO] Info message
[application.Main] Info message
[application.Main] [WARN] Warn message
[application.Main] Warn message
[application.Main] [ERROR] Error message
[application.Main] Error message
[application.Main] [FATAL] Fatal message
[application.Main] Fatal message

I need info-stdout-message appender to output only INFO messages, while detailed-stdout-message to output all except INFO. So, the console output should looks like:

[application.Main] Info message
[application.Main] [WARN] Warn message
[application.Main] [ERROR] Error message
[application.Main] [FATAL] Fatal message

I can't find out how to prevent filters respect level inheritance. Is it possible to do this?

Nucleoplasm answered 11/7, 2014 at 10:0 Comment(0)
F
21

This works:

<Console name="info-stdout-message">
    <PatternLayout pattern="[%logger{36}] %message %n" />
    <Filters>
  
        <!-- Now deny warn, error and fatal messages -->
        <ThresholdFilter level="warn"  onMatch="DENY"   onMismatch="NEUTRAL"/>

        <!-- This filter accepts info, warn, error, fatal and denies debug/trace -->
        <ThresholdFilter level="info"  onMatch="ACCEPT" onMismatch="DENY"/>
    </Filters>
</Console>
Finch answered 11/7, 2014 at 11:49 Comment(0)
A
23

Here are two console appenders. One logs all trace, debug and info levels to std_out, the other logs all warn, error and fatal levels to std_err. This is very useful, for example, within Eclipse since std_err is displayed in red.

<Console name="STDOUT" target="SYSTEM_OUT">
    <PatternLayout pattern="%d{HH:mm:ss.SSS} (%6r) %-5p [%-7t] %F:%L %x - %m%n" />
    <Filters>
        <ThresholdFilter level="warn" onMatch="DENY" onMismatch="ACCEPT" />
    </Filters>
</Console>

<Console name="STDERR" target="SYSTEM_ERR">
    <PatternLayout pattern="%d{HH:mm:ss.SSS} (%6r) %-5p [%-7t] %F:%L %x - %m%n" />
    <Filters>
        <ThresholdFilter level="WARN" onMatch="ACCEPT" />
    </Filters>
</Console>
Adman answered 1/11, 2014 at 18:31 Comment(0)
F
21

This works:

<Console name="info-stdout-message">
    <PatternLayout pattern="[%logger{36}] %message %n" />
    <Filters>
  
        <!-- Now deny warn, error and fatal messages -->
        <ThresholdFilter level="warn"  onMatch="DENY"   onMismatch="NEUTRAL"/>

        <!-- This filter accepts info, warn, error, fatal and denies debug/trace -->
        <ThresholdFilter level="info"  onMatch="ACCEPT" onMismatch="DENY"/>
    </Filters>
</Console>
Finch answered 11/7, 2014 at 11:49 Comment(0)
A
6

It took me very long to figure out how to filter a range of log levels via the log4j2.xml configuration file.

In the end this worked for me:

<Filters>
    <ThresholdFilter level="trace" />
    <ThresholdFilter level="info" onMatch="DENY" onMismatch="NEUTRAL" />
</Filters>

In this case Log4J will log all messages from Level.TRACE to Level.DEBUG, all levels below Level.DEBUG will be ignored.

Anhedral answered 5/9, 2016 at 10:43 Comment(0)
S
1

Please check all log4j2 filtering possibilities at https://logging.apache.org/log4j/2.0/manual/filters.html

Sample configuration fragment

...
<Console name="DEFAULT" target="SYSTEM_OUT">
    <PatternLayout>
        <Pattern>[%d][%p][%c:%L:%M] - %m%n</Pattern>
    </PatternLayout>
    <Filters>
        <RegexFilter regex="(?s).*(sql01|sql02|sql03).*" onMatch="DENY" onMismatch="NEUTRAL"/>
    </Filters>
</Console>
...
Sizar answered 18/2, 2017 at 12:6 Comment(0)
E
1

From your question, it looks like you don't want two different appenders, but two different patterns that are used under different circumstances. For that you should just use a PatternSelector.

<Console name="stdout-message">
  <ScriptPatternSelector defaultPattern="[%logger{36}] [%level] %message %n">
    <Script name="BeanShellSelector" language="bsh"><![CDATA[
      if (logEvent.getLevel() == Level.INFO) {
        return "INFO";
      } else {
        return null;
      }]]>
    </Script>
    <PatternMatch key="INFO" pattern="[%logger{36}] %message %n"/>
   </ScriptPatternSelector>
</Console>
Epicedium answered 18/2, 2017 at 17:25 Comment(0)
A
0

While all these workarounds were necessary in 2014, when the question was posted:

  • in version 2.4 a LevelRangeFilter was introduced (cf. LOG4J2-1106), which allows to write:

    <LevelRangeFilter minLevel="INFO" maxLevel="INFO"/>
    

    to select only INFO messages or:

    <LevelRangeFilter minLevel="WARN" maxLevel="INFO"/>
    

    to select a range (from most to least specific level).

  • version 2.13.0 saw the appearance of a LevelMatchFilter that further simplifies the configuration:

    <LevelMatchFilter level="INFO"/>
    
Aver answered 16/12, 2022 at 17:7 Comment(0)
H
-1

Here is the Log4j2 config to ignore "warn" logs only for docxj4. Check out the code below.

<configuration>

    <conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel"/>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>DENY</onMatch>
            <onMismatch>NEUTRAL</onMismatch>
        </filter>

        <encoder>
            <pattern>%date %coloredLevel %logger{15} - %message%n%xException{10}</pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">

        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>DENY</onMatch>
            <onMismatch>NEUTRAL</onMismatch>
        </filter>

        <file>${application.home:-.}/logs/application.log</file>
        <encoder>
            <pattern>%date [%level] from %logger in %thread - %message%n%xException</pattern>
        </encoder>
    </appender>

    <logger name="org.docx4j" level="INFO"/>

    <root level="INFO">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>
Hinda answered 16/12, 2022 at 15:52 Comment(2)
The question asked about Log4j2 Core, you are giving a solution for Logback.Aver
@PiotrP.Karwasz I have shared the configuration for Log4j2 to ignore "warn" logs specifically for docx4j.Hinda

© 2022 - 2024 — McMap. All rights reserved.