Use Spring boot application properties in log4j2.xml

后端 未结 2 1735
醉酒成梦
醉酒成梦 2020-12-31 09:14

I am working on a web application based on spring boot and want to use log4j2 as the logger implementation.
Everything works fine with the logging configuration defined

2条回答
  •  执念已碎
    2020-12-31 09:45

    I've faced similiar problem with injecting Spring Boot YAML properties into log4j xml configuration, and I found a solution for Spring Boot 1.5.X (and probably 2.0, I didn't test it) which is a little bit hacky and operates on system properties lookup but it certainly works.

    Let say you have profile "dev" in your application and some property to inject, then your application-dev.yml looks like this:

    property:
        toInject: someValue
    

    In your xml configuration log4j2-spring-dev.xml you put something like this:

    
        ${sys:property.toInject}
    
    

    Now you have to somehow transfer this spring property to system property. You have to do that after application environment will be prepared and before logging system will initialize. In Spring Boot there is a listener LoggingApplicationListener, which initialize whole logging system and it's triggered by event ApplicationEnvironmentPreparedEvent, so let's create listener with order with higher precedence than 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 activeProfiles = Arrays.asList(environment.getActiveProfiles());
            if (!activeProfiles.contains("dev")) {
                return;
            }
    
            String someProp = environment.getProperty("property.toInject")
            validateProperty(someProp);
    
            System.setProperty("property.toInject", someProp);
        }
    }
    

    Now register this listener in your application:

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

    And that's it. Your Spring Boot properties should be "injected" in your log4j2 configuration file. This solution works with classpath properties and --spring.config.location properties. Note, it would not work with with some external configuration system like Spring Cloud Config.

    Hope it helps

提交回复
热议问题