Logback中spring.application.name变量无法解析显示var_IS_UNDEFINED的解决方法
问题:Logback无法解析spring.application.name变量,显示varName_IS_UNDEFINED
我正在修复logback-spring.xml文件的一个Bug,该配置用于将日志发送至Logstash服务器,尝试传递applicationName等额外参数,但Logback无法解析spring.application.name变量,仅显示varName_IS_UNDEFINED。以下是我的logback-spring.xml代码:
<property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m | %mdc %n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/> <property resource="application.yml"/> <include resource="org/springframework/boot/logging/logback/base.xml"/> <property resource="application.yml"/> <springProfile name="test,prod"> <springProperty scope="system" name="swarmTaskName" source="swarm.task.name" defaultValue="N.A."/> <springProperty scope="system" name="logstashEndpoint" source="logstash.endpoint" defaultValue="localhost:1234"/> <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <destination>${logstashEndpoint}</destination> <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"> <providers> <mdc/> <!-- MDC variables on the Thread will be written as JSON fields --> <context/> <!--Outputs entries from logback's context --> <version/> <!-- Logstash json format version, the @version field in the output --> <logLevel/> <loggerName/> <pattern> <pattern> <!-- we can add some custom fields to be sent with all the log entries. --> { <!--make filtering easier in Logstash --> "appName": "${spring.application.name}",<!--or searching with Kibana --> } </pattern> </pattern> <threadName/> <message/> <logstashMarkers/> <!-- Useful so we can add extra information for specific log lines as Markers --> <arguments/> <!--or through StructuredArguments --> <stackTrace/> </providers> </encoder> </appender> </springProfile> <!-- Root logger writes to file, console and sends the data to Logstash --> <root level="INFO"> <appender-ref ref="FILE"/> <appender-ref ref="CONSOLE"/> <springProfile name="test,prod"> <appender-ref ref="LOGSTASH"/> </springProfile> </root> <logger name="org.springframework.cache" level="DEBUG"/>
解决方法
核心原因
直接在Logstash的pattern中使用${spring.application.name}无效,因为Logback原生属性解析无法直接读取Spring环境变量,必须通过Spring Boot提供的<springProperty>标签将Spring变量导入到Logback上下文。
具体修复步骤
- 导入spring.application.name到Logback上下文
在<springProfile name="test,prod">代码块内,新增一个<springProperty>标签,将Spring的spring.application.name映射为Logback可识别的属性:
<springProperty scope="context" name="appName" source="spring.application.name" defaultValue="unknown-app"/>
scope="context":让该属性在Logback全局上下文可用defaultValue:避免变量未定义时出现异常
- 修改Logstash编码器中的属性引用
把原代码里的"appName": "${spring.application.name}"替换为上面定义的Logback属性:
"appName": "${appName}",
- 清理重复配置
配置中重复加载了application.yml,保留一个即可,避免潜在加载冲突。
修复后的完整配置片段
<property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m | %mdc %n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/> <property resource="application.yml"/> <include resource="org/springframework/boot/logging/logback/base.xml"/> <springProfile name="test,prod"> <springProperty scope="system" name="swarmTaskName" source="swarm.task.name" defaultValue="N.A."/> <springProperty scope="system" name="logstashEndpoint" source="logstash.endpoint" defaultValue="localhost:1234"/> <!-- 新增导入spring.application.name --> <springProperty scope="context" name="appName" source="spring.application.name" defaultValue="unknown-app"/> <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <destination>${logstashEndpoint}</destination> <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"> <providers> <mdc/> <!-- MDC variables on the Thread will be written as JSON fields --> <context/> <!--Outputs entries from logback's context --> <version/> <!-- Logstash json format version, the @version field in the output --> <logLevel/> <loggerName/> <pattern> <pattern> <!-- we can add some custom fields to be sent with all the log entries. --> { <!--make filtering easier in Logstash --> "appName": "${appName}",<!--or searching with Kibana --> } </pattern> </pattern> <threadName/> <message/> <logstashMarkers/> <!-- Useful so we can add extra information for specific log lines as Markers --> <arguments/> <!--or through StructuredArguments --> <stackTrace/> </providers> </encoder> </appender> </springProfile> <!-- Root logger writes to file, console and sends the data to Logstash --> <root level="INFO"> <appender-ref ref="FILE"/> <appender-ref ref="CONSOLE"/> <springProfile name="test,prod"> <appender-ref ref="LOGSTASH"/> </springProfile> </root> <logger name="org.springframework.cache" level="DEBUG"/>
额外注意事项
<springProperty>是Spring Boot扩展标签,仅在logback-spring.xml中生效,不能用于普通的logback.xml- 确保Spring Boot版本在1.3及以上(该标签从1.3版本开始支持)
内容的提问来源于stack exchange,提问作者notforward
相关产品推荐
相关产品推荐

