在log4j2.xml中使用Spring启动应用程序属性

Ank*_*pta 11 log4j2 spring-boot

我正在开发基于spring boot的Web应用程序,并希望使用log4j2作为记录器实现.
使用log4j2-spring.xml文件中定义的日志记录配置,一切正常.

什么不起作用:我想在log4j2-spring.xml文件中使用属性占位符,该文件应该从用于配置spring boot 的application.yml文件中定义的属性中解析.

这可能吗?如果有,怎么样?

Bon*_*ond 9

无法log4j2-spring.xml通过via属性占位符直接替换属性,因为它不在Spring的范围之内,仅用于配置目的。log4j2-spring.xml

但是,您可以利用此处Log4j2概述的属性替换的即用型功能。

步骤1-log4j2-spring.xml下面指定属性名称及其变量

<Configuration status="warn">
    <Properties>
        <Property name="someProp">${bundle:test:someKey}</Property>
    </Properties> 
    <!--other configs -->
</Configuration>
Run Code Online (Sandbox Code Playgroud)

第2步 -在日志配置中使用上面定义的属性,例如后缀以记录文件名

<Appenders>
    <File name="file" fileName="/path/to/logs/app-${someProp}.log">
        <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %-40c{1.} - %m%n"/>
    </File>
</Appenders>
Run Code Online (Sandbox Code Playgroud)

第3步 -创建一个捆绑包即属性文件)以保存属性值,例如test.properties

# properties for log4j2
someKey=someValue
someKey1=someValue1
Run Code Online (Sandbox Code Playgroud)

在您的情况下,此文件将包含您希望在log4j2配置中使用的yaml中的值。如果这些属性也可以在应用程序中使用,它们将在yaml中复制,并且捆绑包(即属性文件)应该是可以接受的折衷方案,因为spring不能将它们注入log4j2配置中。

如果需要更多信息,请在评论中告知。


小智 6

我在将 Spring Boot YAML 属性注入 log4j xml 配置时遇到了类似的问题,我找到了 Spring Boot 1.5.X(可能是 2.0,我没有测试它)的解决方案,它有点笨拙并且在系统上运行属性查找,但它肯定有效。

假设您的应用程序中有配置文件“dev”和一些要注入的属性,那么您的application-dev.yml如下所示:

property:
    toInject: someValue
Run Code Online (Sandbox Code Playgroud)

在您的 xml 配置log4j2-spring-dev.xml 中,您放置了如下内容:

<Properties>
    <property name="someProp">${sys:property.toInject}</property>
</Properties>
Run Code Online (Sandbox Code Playgroud)

现在您必须以某种方式将此弹簧属性转移到系统属性。您必须在准备好应用程序环境之后和日志系统初始化之前执行此操作。在 Spring Boot 中有一个监听器 LoggingApplicationListener,它初始化整个日志系统,它由事件 ApplicationEnvironmentPreparedEvent 触发,所以让我们创建一个优先级高于 LoggingApplicationListener 的监听器:

public class LoggingListener implements ApplicationListener, Ordered {

@Override
public int getOrder() {
    return LoggingApplicationListener.DEFAULT_ORDER - 1;
}

@Override
public void onApplicationEvent(ApplicationEvent event) {
    if (event instanceof ApplicationEnvironmentPreparedEvent) {
        ConfigurableEnvironment environment = ((ApplicationEnvironmentPreparedEvent) event).getEnvironment();
        List<String> activeProfiles = Arrays.asList(environment.getActiveProfiles());
        if (!activeProfiles.contains("dev")) {
            return;
        }

        String someProp = environment.getProperty("property.toInject")
        validateProperty(someProp);

        System.setProperty("property.toInject", someProp);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在您的应用程序中注册此侦听器:

public static void main(String[] args) {
    SpringApplication application = new SpringApplication(MyApplication.class);
    application.addListeners(new LoggingListener());
    application.run(args);
}
Run Code Online (Sandbox Code Playgroud)

就是这样。您的 Spring Boot 属性应该“注入”到您的 log4j2 配置文件中。此解决方案适用于类路径属性和 --spring.config.location 属性。请注意,它不适用于某些外部配置系统,例如 Spring Cloud Config。

希望能帮助到你

  • 这是唯一对我完全有效的解决方案。我的应用程序需要一个配置文件。用户需要能够使用更高优先级的配置文件来覆盖打包的默认配置,这与接受的答案不起作用。 (2认同)