如何以编程方式替换默认的log4j2配置?

时间:2016-07-26 09:52:10

标签: logging log4j2

今天我有一个问题是正确地重新配置log4j2配置。为了解释这个问题,我创建了一个几乎匹配生产代码的示例应用程序。示例项目结构如下图所示:

enter image description here

出于开发人员的目的,我们希望使用包装器类来启动主应用程序,以配置一些参数,例如日志配置或系统属性,这些参数不应放在生产代码中。因此,生成器log4j2配置应由开发人员替换,以更具体地设置日志级别,并避免添加日志条目的文件。以下是生产主类的代码:

package logging.log4j2;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MainApp {

    private final Log LOG = LogFactory.getLog(MainApp.class);
    private final String[] commandLineArgs;

    public static void main(String[] args) {
        MainApp app = new MainApp(args);
        app.start();
    }

    protected MainApp(String[] args) {
        commandLineArgs = args;
    }

    public void start() {
        LOG.info("Starting MainApp application ...");

        // ... do main application stuff here
        LOG.debug("This is only for DEBUG mode.");
    }
}

现在是开发人员包装器主类的代码:

package logging.log4j2;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.net.URL;

public class DevWrapperMainApp extends MainApp {

    private static final Log LOG = LogFactory.getLog(DevWrapperMainApp.class);
    public static final String PROP_LOG4J_CONFIGURATION_FILE = "log4j.configurationFile";

    protected DevWrapperMainApp(String[] args) {
        super(args);
    }

    public static void main(String[] args) {
        preconfigureDevMode();
        DevWrapperMainApp devApp = new DevWrapperMainApp(args);
        devApp.start();
    }

    private static void preconfigureDevMode() {
        LOG.debug("Preconfigure application for deveoper mode ...");
        String log4j2ConfigFilePath =    System.getProperty(PROP_LOG4J_CONFIGURATION_FILE);
        if(log4j2ConfigFilePath == null || log4j2ConfigFilePath.isEmpty()) {
            URL configResource = DevWrapperMainApp.class.getResource("/dev-log4j2.xml");
            if(configResource != null) {
                System.setProperty(PROP_LOG4J_CONFIGURATION_FILE, configResource.toExternalForm());
            } else {
                LOG.error("Set log4j2 configuration file property failed. Resource file could not be detected correctly.");
            }
        }
    }
}

生产应用程序的日志记录由 log4j2.xml 配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration name="productiveConfig" status="WARN" monitorInterval="5">
    <properties>
        <property name="log.pattern.layout">%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</property>
    </properties>

    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${sys:log.pattern.layout}"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

对于示例应用程序,没有文件追加者,但是日志记录级别和配置名称与以下 dev-log4j2.xml 不同:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration name="developerConfig" status="DEBUG" monitorInterval="5">
    <properties>
        <property name="log.pattern.layout">DEV-MODE: %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</property>
    </properties>

    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="${sys:log.pattern.layout}"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="DEBUG">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

通过运行 DevWrapperMainApp 类,我得到以下输出:

"C:\Program Files\Java\jdk1.8.0_66\bin\java" ...
11:40:14.553 [main] INFO  logging.log4j2.MainApp - Starting MainApp application ...

Process finished with exit code 0

除了 INFO 日志记录外,我还希望输出 DEBUG 。因此,通过在此时覆盖系统属性,似乎不会重新配置日志配置。也许是为了迟到,log4j2已经由高效的配置文件配置了?如何在应用程序启动时更改整个配置?文档说:

  

但是,如果在调用Configurator.initialize()之前尝试进行任何日志记录,则默认配置将用于这些日志事件。 (部分:Reconfigure Log4j Using ConfigurationBuilder with the Configurator

也许有人暗示我走向正确的方向?我也知道为开发目的创建 log4j2-test.xml 的可能性,但是想要避免这种情况并且还要设置系统属性。应该知道代码在哪里找到配置文件。

提前致谢。

哈迪

1 个答案:

答案 0 :(得分:1)

Log4j 2支持使用单独的配置进行测试。您可以拥有两个配置文件,一个名为log4j2.xml用于生产,另一个名为log4j2-test.xml用于测试。如果两者都存在,Log4j 2将使用测试配置。在生产中,您根本不会部署测试配置。请参阅文档了解确切的order in which Log4j 2 initializes