java - 用于日志记录和分布式跟踪的 Spring Boot 自定义启动器

标签 java spring spring-boot slf4j spring-cloud-sleuth

我正在开发一个自定义的 spring boot starter,目的是为我们分布式系统中的所有 spring boot 应用程序提供自动配置,这样,每次需要更改配置时,它可以在一个地方完成,而不是跨所有不同的应用程序应用更改,而只需对依赖项进行版本更新就足够了。

由于我想涵盖的主题是日志记录和分布式跟踪,所以现在坚持使用 logback,但考虑到将来也提供 log4j2 支持,启动器包括以下依赖项:

  • spring-boot-starter-web
  • spring-cloud-starter-sleuth

我的第一个想法是在启动器的自动配置模块的 src/main/resources 文件夹中包含一个 logback.xml 文件,并且应用程序使用启动器获取配置。

我遇到的问题是,当 Sleuth 在类路径中时,当 EnvironmentPostProcessor 使用 [app name, traceId, spanId, exported] 元组更新级别模式时,应用名称使用启动器的应用程序的application.yml文件中出现的是bootstrap而不是spring.application.name定义的名称,不知道为什么,找不到关于原因的线索:(

所以,为了解决这个问题,我做了以下事情:

  • 将模式 ${LOG_LEVEL_PATTERN:-%5p} 替换为 %5p,并在模式中的其他位置添加跟踪信息 [%X {X-B3-TraceId:-},%X{X-B3-SpanId:-}]
  • 使用过滤器,使用 @Value("${spring.application.name}") Autowiring ,然后使用 MDC#put 应用程序名称。

然后我意识到,这种方法只适用于 HTTP 请求,但不适用于其他请求,所以这还不够好,因为应用程序还使用与 JMS/Spring Cloud Stream 的异步通信。

然后我想到将应用程序名称添加到 MDC 中,包括一个 ApplicationContextInitializer,认为它可以用于所有用例(HTTP 请求、消息传递等)。但遗憾的是,该值在应用程序启动期间存在于日志中,然后在 HTTP 请求中消失了(还没有尝试过消息传递,但直觉是它也不会出现在那里)。

所以问题是,因为我有点卡住了,不知道还能去哪里找,什么是获得spring 值(value)的最佳方法/机制.application.name 到 MDC 中以便它可以出现在每个日志中?

提前致谢!

最佳答案

bootstrap.yml 中提供名称就足够了。这样您就会在所有日志中看到 spring 应用程序名称。

关于java - 用于日志记录和分布式跟踪的 Spring Boot 自定义启动器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43775907/

相关文章:

使用 'java' 编译类时,Java 11 不会生成 .class 文件

java - 避免让 JPA 自动持久化对象

spring - spring starter 项目中的服务 url 是什么?默认服务 url https ://start. spring.io 的替代方案

java - 为什么 ActivityCompat.requestPermissions() 只接受 0-255 之间的整数请求码?

java - 如何使用 doGet 方法捕获从 android 应用程序发送到 servlet 的 JSON 对象?

带有 Apache CXF 和 CDI 的 Spring Boot

spring - 由于 fatal error ,Kafka 中止生产者批处理

java - 按日期排序 聚合 mongodb

java - Spring Boot Autowiring 服务 java.lang.NullPointerException

java - 如何调用这个实例方法