【问题标题】:Log4j2 Different appender for different levelLog4j2不同级别的不同appender
【发布时间】:2017-04-16 20:22:09
【问题描述】:

我有一个小问题,找不到解决方案。我想为级别信息设置模式布局,而不是级别警告。如果我有一个登录级别 INFO 一切正常,但如果日志是 levelWARN 它会被写入控制台两次(作为级别信息和级别警告)。只需将特定级别的所有日志都写出我们在该级别和以下级别的日志。

我想将级别 INFO 登录到控制台,例如:"%-5level %d{dd-MM-yyyy HH:mm:ss} %msg%n" 和级别 WARN,例如 "%-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>

【问题讨论】:

    标签: log4j2


    【解决方案1】:

    据我了解,您希望将具有 WARN 或更高级别(WARN、ERROR、FATAL)的日志事件仅转到“ConsoleWarning”附加程序,而不是同时转到“ConsoleWarning”和“ConsoleInfo”。

    执行此操作的最简单方法是修改“ConsoleInfo”附加程序中的过滤器配置,以基本上执行相反的方法,如下所示:

    <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>   
    

    这是因为log4j2 manual states

    如果 LogEvent 中的级别与配置的级别相同或更具体,则此过滤器返回 onMatch 结果,否则返回 onMismatch 值。例如,如果 ThresholdFilter 配置了 Level ERROR,并且 LogEvent 包含 Level DEBUG,则将返回 onMismatch 值,因为 ERROR 事件比 DEBUG 更具体。

    这将导致 appender 只接受级别低于 WARN 的事件。

    另一种可能的解决方案是使用RoutingAppender 来指定每个级别的目的地。如果你这样做,那么你根本不需要 ThresholdFilters。另请注意,您可以通过不提供默认路由和不提供该级别的路由来忽略特定级别的事件。例如,如果您从下面的配置中删除 &lt;Route ref="ConsoleInfo" key="DEBUG" /&gt;,那么路由附加程序将忽略所有 DEBUG 事件,并且不会打印到控制台。这是配置:

    <?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>
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-10
      相关资源
      最近更新 更多