You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Log4j2 YAML配置中引用属性?占位符未替换问题求助

Log4j2 YAML配置中Spring属性占位符未替换的解决方法

问题现象

使用以下Log4j2.yaml配置:

Configuration:
 Appenders:
    Console:
      name: Console
      target: SYSTEM_OUT
      JSONLayout:
        compact: true
        eventEol: true
        properties: true
        stacktraceAsString: true
        includeTimeMillis: true
        KeyValuePair:
          - key: appName
            value: ${spring.application.name} 
          - key: version
            value: ${spring.application.version} 
          
 Loggers:
    Root:
      level: INFO
      AppenderRef:
        ref: Console
    Logger:
      - name: org.apache
        level: WARN
        AppenderRef:
          ref: Console
      - name: org.springframework.beans.factory
        level: WARN
        AppenderRef:
          ref: Console

生成的日志中,appName和version的占位符未被替换:

{"instant":{"epochSecond":1705250772,"nanoOfSecond":209226000},"thread":"main","level":"INFO","loggerName":"com.hyperbank.architecture.base.AbstractHyperBankApplication","message":"Hello, it's me, 'config-provider' !!!","endOfBatch":false,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","contextMap":{},"threadId":1,"threadPriority":5,"appName":"${spring.application.name}","version":"${spring.application.version}"}

但相同的属性引用在banner.txt中能正常显示实际值:

_  _                    ___            _      ___           __ _        ___             _    _         
 | || |_  _ _ __  ___ _ _| _ ) __ _ _ _ | |__  / __|___ _ _  / _(_)__ _  | _ \_ _ _____ _(_)__| |___ _ _ 
 | __ | || | '_ \/ -_) '_| _ \/ _` | ' \| / / | (__/ _ \ ' \|  _| / _` | |  _/ '_/ _ \ V / / _` / -_) '_|
 |_||_|\_, | .__/\___|_| |___/\__,_|_||_|_\_\  \___\___/_||_|_| |_\__, | |_| |_| \___/\_/|_\__,_\___|_|  
       |__/|_|                                                    |___/                                 

Name: config-provider 
Version: 1.0.0
Powered by Spring Boot 3.1.2

问题原因

Log4j2的配置加载时机早于Spring上下文初始化,默认无法直接识别并解析Spring环境中的${spring.application.name}这类属性;而banner.txt的属性替换由Spring Boot直接处理,因此能正常生效。

解决方案

方法1:使用Spring集成的Log4j2属性语法

在Log4j2配置中通过${spring:属性名}的语法直接引用Spring环境属性,这是Spring Boot集成Log4j2的标准方式,无需额外配置即可实现属性替换。修改后的配置如下:

Configuration:
  Appenders:
    Console:
      name: Console
      target: SYSTEM_OUT
      JSONLayout:
        compact: true
        eventEol: true
        properties: true
        stacktraceAsString: true
        includeTimeMillis: true
        KeyValuePair:
          - key: appName
            value: ${spring:spring.application.name}
          - key: version
            value: ${spring:spring.application.version}
  Loggers:
    Root:
      level: INFO
      AppenderRef:
        ref: Console
    Logger:
      - name: org.apache
        level: WARN
        AppenderRef:
          ref: Console
      - name: org.springframework.beans.factory
        level: WARN
        AppenderRef:
          ref: Console

该方式依赖Spring Boot的Log4j2集成模块,需确保项目已引入spring-boot-starter-log4j2依赖(若使用Web场景,可引入spring-boot-starter-web并排除默认的logback依赖)。

方法2:通过系统属性传递属性值

将Spring属性提前设置为JVM系统属性,让Log4j2直接解析占位符:

  • 启动时通过JVM参数传递:
java -jar your-app.jar -Dspring.application.name=config-provider -Dspring.application.version=1.0.0
  • 在application.properties中配置:
spring.application.name=config-provider
spring.application.version=1.0.0
logging.log4j2.config=classpath:log4j2.yaml

此方法需确保属性在Log4j2配置加载前已被设置为系统属性,灵活性不如方法1。

方法3:自定义Log4j2属性源(进阶)

实现org.springframework.boot.logging.log4j2.Log4j2PropertySource接口,将Spring环境属性注入到Log4j2属性上下文,适合有特殊属性处理需求的场景。示例代码如下:

import org.springframework.boot.logging.log4j2.Log4j2PropertySource;
import org.springframework.core.env.Environment;

public class SpringEnvironmentLog4j2PropertySource extends Log4j2PropertySource {
    private final Environment environment;

    public SpringEnvironmentLog4j2PropertySource(Environment environment) {
        super("spring-environment");
        this.environment = environment;
    }

    @Override
    public boolean containsProperty(String key) {
        return environment.containsProperty(key);
    }

    @Override
    public String getProperty(String key) {
        return environment.getProperty(key);
    }
}

在Spring启动类中注册该属性源:

import org.apache.logging.log4j.core.config.Configurator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class ConfigProviderApplication {
    public static void main(String[] args) {
        SpringApplication application = new SpringApplication(ConfigProviderApplication.class);
        application.addInitializers((ApplicationContextInitializer<ConfigurableApplicationContext>) context -> {
            Configurator.initialize(new SpringEnvironmentLog4j2PropertySource(context.getEnvironment()));
        });
        application.run(args);
    }
}

此方法复杂度较高,仅在其他方法无法满足需求时使用。

内容的提问来源于stack exchange,提问作者Paul Marcelin Bejan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 01:07:58