Log4j2 Different appender for different level

2019-07-26 17:20发布

问题:

I have a little problem and can´t find a solution. I want to set pattern layout for level info another than for level warn. If I have a log in level INFO everything is OK, but if the log is levelWARN it is written out into console two times (as level info and as level warn). Simply all logs at a specific level is written out us log at that level and the level below.

I want to logs in level INFO write out to console like: "%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n" and level WARN like "%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n".

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>        
        <Console name="ConsoleInfo" target="SYSTEM_OUT">
            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n"/>
        </Console>     
        <Console name="ConsoleWarning" target="SYSTEM_OUT">
            <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"/>
        </Console>   
        <File name="File" fileName="logs/cli.log">
            <PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"/>
        </File>
    </Appenders>

    <Loggers> 
        <Root level="ALL">
            <AppenderRef ref="ConsoleInfo"/>
            <AppenderRef ref="ConsoleWarning"/>
            <AppenderRef ref="File"/>    
        </Root>
    </Loggers>
</Configuration>

回答1:

As I understand it you want to have log events with a level of WARN or higher (WARN,ERROR,FATAL) go to the "ConsoleWarning" appender only rather than going to both "ConsoleWarning" and "ConsoleInfo".

The simplest way to do this would be to modify your filter configuration in your "ConsoleInfo" appender to basically do the opposite approach like this:

<Console name="ConsoleInfo" target="SYSTEM_OUT">
    <ThresholdFilter level="WARN" onMatch="DENY" onMismatch="ACCEPT"/>
    <PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n"/>
</Console>   

This works because as the log4j2 manual states:

This filter returns the onMatch result if the level in the LogEvent is the same or more specific than the configured level and the onMismatch value otherwise. For example, if the ThresholdFilter is configured with Level ERROR and the LogEvent contains Level DEBUG then the onMismatch value will be returned since ERROR events are more specific than DEBUG.

This will cause the appender to accept only events that have a level less than WARN.

Another possible solution would be to use a RoutingAppender to specify the destination for each level. If you do it this way then you don't need the ThresholdFilters at all. Also note that you can ignore events of specific levels by not providing a default route and not providing a route for that level. For example, if you remove <Route ref="ConsoleInfo" key="DEBUG" /> from the configuration below then all DEBUG events will be ignored by the routing appender and will not be printed to console. Here is the configuration:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>        
        <Console name="ConsoleInfo" target="SYSTEM_OUT">
            <PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n"/>
        </Console>     
        <Console name="ConsoleWarning" target="SYSTEM_OUT">
            <PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"/>
        </Console>   
        <File name="File" fileName="logs/cli.log">
            <PatternLayout pattern="%-5level %d{dd-MM-yyyy HH:mm:ss} [%l] %msg%n"/>
        </File>
        <Routing name="Routing">
            <Routes>
                <Script name="RoutingInit" language="JavaScript"><![CDATA[
                    logEvent.getLevel();]]>
                </Script>
                <Route ref="ConsoleInfo" key="TRACE" />
                <Route ref="ConsoleInfo" key="DEBUG" />
                <Route ref="ConsoleInfo" key="INFO" />
                <Route ref="ConsoleWarning" key="WARN" />
                <Route ref="ConsoleWarning" key="ERROR" />
                <Route ref="ConsoleWarning" key="FATAL" />
            </Routes>
        </Routing>
    </Appenders>

    <Loggers> 
        <Root level="ALL">
            <AppenderRef ref="Routing"/>
            <AppenderRef ref="File"/>    
        </Root>
    </Loggers>
</Configuration>

Hope this helps!



标签: log4j2