spring-boot - 如何在 Logback 的 Logstash 编码器中使用来自配置服务器的 Spring 环境值
问题描述
我想在Logback appender的 Logstash 编码器中使用 Spring 环境值作为自定义字段。
有一个通用的配置标签来使用属性
<property resource="logstash.properties" />
Spring为此提供了一个特殊的配置标签
<springProperty name="appEnv" source="environment"/>
然后可以在Logstash 编码器的自定义字段中使用这两个标签的属性
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"application.environment":"${appEnv}"</customFields>
</encoder>
问题是,据我了解,这仅在某些情况下有效。问题大概是在Spring环境搭建的时候Logback已经配置好了。
它似乎在什么时候起作用
- 该属性是本地和静态的(在配置时可用)
- 该属性位于 bootstrap.properties
它似乎不起作用
- 从Spring 配置服务器检索时,该属性是动态的
我从配置服务器传递的属性值是null
在配置 Logback 时,因此日志将它们显示appEnv_IS_UNDEFINED
为一个名为appEnv
.
因为大多数示例只是使用spring.application.name
this 似乎几乎没有被注意到。
为了解决时间问题,我搜索了一种重新加载 Logback 配置 onApplicationEvent
的方法。我发现这个答案证实了我的问题并提供了一个框架解决方案。
我找到了其他解决方案,其中使用 Logstash 编码器的 Logback appender 完全以编程方式构建并添加到LoggerContext
.
但是,我想知道是否还有一种方法可以坚持使用 appender 的 XML 配置,并在 Spring 环境准备好时以编程方式“重新加载”配置。我该怎么做?
我找到了这个答案来重新加载,但它不适用于我的情况。appEnv_IS_UNDEFINED
继续出现在日志文件中。
解决方案
我能够通过实施 Spring 来解决我的问题ApplicationContextInitializer
。
在被调用的initialize
方法中,我可以通过 RootLogger 访问我的 Logback Appender 和 Encoder。
Logger rootLogger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
RollingFileAppender jsonFileAppender = (RollingFileAppender) rootLogger.getAppender(LOGSTASH_APPENDER_NAME);
LogstashEncoder encoder = (LogstashEncoder) jsonFileAppender.getEncoder();
从 LogstashEncoder,我可以得到 customFields
String customFields = encoder.getCustomFields();
在那里我按预期在 JSON 字符串中找到了未解析的属性
{"application.environment":"appEnv_IS_UNDEFINED"}
因为我可以Environment
从传递的ApplicationContext
springEnvironment = applicationContext.getEnvironment();
我可以将未解析的属性与正则表达式匹配(\w+)_IS_UNDEFINED
,并将它们替换为 Spring 环境中的实际值。
令人惊讶的是,我不需要重新加载或重新启动任何东西。只需在 Encoder 上设置固定的 customFields 就足够了。紧接着,日志消息包含正确的值。
encoder.setCustomFields(fixedCustomFields);
logback-spring.xml
有了这个初始化器,我可以在或包含的文件中完全配置我的 appender 和 LogstashEncoder 。
推荐阅读
- encoding - Avro 序列化和反序列化列表
- python-requests - 如何移植使用 Beautiful Soup 4 的 python urllib2 应用程序(一个网络爬虫)来使用 requests 包
- c# - 如何保持 splitcontainer 面板大小成比例?
- java - 如何删除字符串中的额外换行符
- sql - 使用 UNIQUE NOT NULL 列时我真的需要 PRIMARY KEY 吗?
- html - 视频未下载 HTML 视频标签
- r - 正态分布bayesAB - 负均值
- r - 使用循环序列的值创建和命名新变量
- salesforce - NLP算法可以在Force.com平台上运行吗?
- groovy - java.lang.ClassCastException:将两个数字作为字符串进行比较时抛出 geb.content.TemplateDerivedPageContent