Spring 启动用于日志记录和分布式跟踪的自定义启动程序
Spring Boot custom starter for logging and distributed tracing
我正在开发自定义 spring 引导启动器,目的是为分布式系统中的所有 spring 引导应用程序提供自动配置,所以这样,每次需要更改配置时,都可以在一个地方完成,而不是在所有不同的应用程序中应用更改,而只需对依赖项进行版本更新就足够了。
由于我想涵盖的主题是日志记录和分布式跟踪,所以现在坚持使用 logback,但考虑在将来也提供 log4j2 支持,启动器包括以下依赖项:
spring-boot-starter-web
spring-cloud-starter-sleuth
我的第一个想法是在启动器的自动配置模块的 src/main/resources
文件夹中包含一个 logback.xml
文件,使用启动器的应用程序将获得配置。
我遇到的问题是,当 Sleuth 在类路径中时,当 EnvironmentPostProcessor 使用 [app name, traceId, spanId, exported]
元组更新级别模式时,出现的应用程序名称是 bootstrap
而不是使用启动器的应用程序的 application.yml 文件中用 spring.application.name
定义的名称,不知道为什么,找不到原因的线索:(
所以,为了解决这个问题,我做了以下事情:
- 将模式
${LOG_LEVEL_PATTERN:-%5p}
替换为 %5p
,并在模式的其他地方添加跟踪信息 [%X{X-B3-TraceId:-},%X{X-B3-SpanId:-}]
- 使用过滤器,使用
@Value("${spring.application.name}")
自动装配,然后 MDC#put
应用程序名称。
然后我意识到,这种方法只适用于 HTTP 请求,但不适用于其他,所以这还不够好,因为应用程序还使用与 JMS / Spring Cloud Stream 的异步通信。
然后我想到将应用程序名称添加到 MDC
,包括一个 ApplicationContextInitializer,认为它可用于所有用例(HTTP 请求、消息传递等)。但遗憾的是,该值在应用程序启动期间存在于日志中,然后在 HTTP 请求中消失了(还没有尝试过消息传递,但直觉是它也不会出现在那里)。
所以 问题 是,因为我有点卡住了,不知道还能去哪里找,什么是最好的 approach/mechanism 来实现将 spring.application.name
的值写入 MDC,以便它可以出现在每个日志中?
提前致谢!
提供bootstrap.yml
中的名字即可。这样您将在所有日志中看到 spring 应用程序名称。
我正在开发自定义 spring 引导启动器,目的是为分布式系统中的所有 spring 引导应用程序提供自动配置,所以这样,每次需要更改配置时,都可以在一个地方完成,而不是在所有不同的应用程序中应用更改,而只需对依赖项进行版本更新就足够了。
由于我想涵盖的主题是日志记录和分布式跟踪,所以现在坚持使用 logback,但考虑在将来也提供 log4j2 支持,启动器包括以下依赖项:
spring-boot-starter-web
spring-cloud-starter-sleuth
我的第一个想法是在启动器的自动配置模块的 src/main/resources
文件夹中包含一个 logback.xml
文件,使用启动器的应用程序将获得配置。
我遇到的问题是,当 Sleuth 在类路径中时,当 EnvironmentPostProcessor 使用 [app name, traceId, spanId, exported]
元组更新级别模式时,出现的应用程序名称是 bootstrap
而不是使用启动器的应用程序的 application.yml 文件中用 spring.application.name
定义的名称,不知道为什么,找不到原因的线索:(
所以,为了解决这个问题,我做了以下事情:
- 将模式
${LOG_LEVEL_PATTERN:-%5p}
替换为%5p
,并在模式的其他地方添加跟踪信息[%X{X-B3-TraceId:-},%X{X-B3-SpanId:-}]
- 使用过滤器,使用
@Value("${spring.application.name}")
自动装配,然后MDC#put
应用程序名称。
然后我意识到,这种方法只适用于 HTTP 请求,但不适用于其他,所以这还不够好,因为应用程序还使用与 JMS / Spring Cloud Stream 的异步通信。
然后我想到将应用程序名称添加到 MDC
,包括一个 ApplicationContextInitializer,认为它可用于所有用例(HTTP 请求、消息传递等)。但遗憾的是,该值在应用程序启动期间存在于日志中,然后在 HTTP 请求中消失了(还没有尝试过消息传递,但直觉是它也不会出现在那里)。
所以 问题 是,因为我有点卡住了,不知道还能去哪里找,什么是最好的 approach/mechanism 来实现将 spring.application.name
的值写入 MDC,以便它可以出现在每个日志中?
提前致谢!
提供bootstrap.yml
中的名字即可。这样您将在所有日志中看到 spring 应用程序名称。