Log4j为每个appender设置不同的日志记录级别

时间:2018-01-31 12:16:49

标签: java logging log4j

我正在使用Log4j 2来记录我的应用程序的事件。但是我遇到了以下问题。

目前,所有日志消息都写入两个不同的appender。一个具有RollingFile类型,而另一个具有Console类型。

我想要的是RollingFile appender记录INFO级别或更高级别(ERROR,FATAL)的消息,以及Console appender记录ERROR级别或更高级别(FATAL)的消息。

在我的log4j2.xml文件中,我似乎只能声明整个记录器(包括其所有appender)的日志记录级别。这是我的log4j2.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="30">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout>
                <Pattern>%d %level %msg%n</Pattern>
            </PatternLayout>
        </Console>
        
        <RollingFile name="Log" fileName="log/Log.log" filePattern="log/Log-%d{yyyy-MM-dd}-%i.log" append="false">
            <PatternLayout>
                <Pattern>%d %level %msg%n</Pattern>
            </PatternLayout>
            <Policies>
                <SizeBasedTriggeringPolicy size="1 MB" />
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>
    </Appenders>

    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console" />
            <AppenderRef ref="Log" />
        </Root>
    </Loggers>
</Configuration>

这样做有简单的方法吗?我搜索了log4j文档,但找不到我要找的东西(也许我错过了吗?)。如果可能的话,我真的更希望解决方案适用于任何appender的类型;不是特定于RollingFile和Console。

修改

我看到很多问题要求将来自某个级别的消息写入文件,同时将消息从不同级别写入不同的文件。在我的情况下,我需要将具有一定级别 HIGHER 的消息写入不同的文件。例如,在我提供的级别为ERROR或FATAL的消息将写入RollingFile和Console的情况下,而具有级别INFO的消息将仅写入RollingFile。

2 个答案:

答案 0 :(得分:4)

要限制log4j2中特定附加程序的日志记录级别,应使用附加程序的ThresholdFilter元素。

在您的情况下,log4j2.xml文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="30">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout>
                <Pattern>%d %level %msg%n</Pattern>
            </PatternLayout>
        </Console>
    
        <RollingFile name="Log" fileName="log/Log.log" filePattern="log/Log-%d{yyyy-MM-dd}-%i.log" append="false">
            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout>
                <Pattern>%d %level %msg%n</Pattern>
            </PatternLayout>
            <Policies>
                <SizeBasedTriggeringPolicy size="1 MB" />
            </Policies>
            <DefaultRolloverStrategy max="10"/>
        </RollingFile>
    </Appenders>

    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console" />
            <AppenderRef ref="Log" />
        </Root>
    </Loggers>
</Configuration>

这是一个简单的测试:

public class Log4jTest {
    private static final Logger logger = LogManager.getLogger(Log4jTest.class);

    public static void main(String[] args) {
        logger.debug("Debug");
        logger.info("Info");
        logger.warn("Warning");
        logger.error("Error");
        logger.fatal("Fatal");
    }
}

控制台输出:

2020-02-25 12:33:50,587 ERROR Error
2020-02-25 12:33:50,589 FATAL Fatal

Log.log内容:

2020-02-25 12:33:50,585 INFO Info
2020-02-25 12:33:50,587 WARN Warning
2020-02-25 12:33:50,587 ERROR Error
2020-02-25 12:33:50,589 FATAL Fatal

在log4j的第一个版本中,它是添加程序的Threshold属性。关于如何解决log4j see the answer on question中的问题。

借助过滤器Log4j2,可以将输出配置为特定的附加器,比log4j灵活得多。

答案 1 :(得分:1)

这应该可以解决问题。

<Loggers>
    <Root level="debug" additivity="false">
        <AppenderRef ref="Console"/>
    </Root>
    <Logger name="com.project.package" level="info" additivity="false">
        <AppenderRef ref="Log" />
    </Logger>
</Loggers>

或者,您可以这样做 - Different level of logs in different log files

BTW,这在Log4j2文档中得到了很好的解释。见 - https://logging.apache.org/log4j/2.x/manual/configuration.html