Spring Cloud Sleuth是如何将跟踪信息添加到logback日志行的?

cld4siwp  于 2023-02-19  发布在  Spring
关注(0)|答案(2)|浏览(284)

我有基于Sping Boot 的Web应用程序,它使用Logback进行日志记录。
我还使用以下命令从spring Boot 继承了一些回登录默认值:

<include resource="org/springframework/boot/logging/logback/base.xml"/>

我想开始记录跟踪信息,所以我添加了:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

Sleuth将跟踪信息添加到日志行,但我在模式中找不到任何%X%mdchttps://github.com/spring-projects/spring-boot/blob/2.3.x/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml
Sleuth如何将跟踪信息添加到日志行中?
我使用了spring-cloud-starter-parentHoxton.SR9父节点,这将带来Spring Boot 2.3.5.RELEASEspring-cloud-starter-sleuth2.2.6.RELEASE

jogvjijk

jogvjijk1#

  • (tl;dr在底部)*

从这个问题中,我想您已经了解到traceIdspanId被放置到MDC中。
如果您查看一下sleuth文档的日志集成部分,您会发现示例中的跟踪信息介于日志级别(ERROR)和pid(97192)之间。如果您尝试将此信息与logback配置匹配,您会发现日志级别和pid之间没有任何内容:${LOG_LEVEL_PATTERN:-%5p} ${PID:- },因此跟踪信息如何到达那里可能是一个有效的问题。
如果你再看一下文档,它是这样说的:
此日志配置是由Sleuth自动设置的。您可以通过spring.sleuth.enabled=false属性禁用Sleuth或放置您自己的logging.pattern.level属性来禁用它。
它仍然没有明确地解释机制,但它给了你一个巨大的提示:
放置您自己的logging.pattern.level属性
基于此,你可能会认为日志级别和pid之间没有任何东西,Sleuth只是简单地覆盖日志级别,并将跟踪信息放入其中。如果你搜索文档在代码中提到的属性,你会发现这正是所发生的事情:

TL;DR

Sleuth覆盖日志级别模式并向其中添加跟踪信息:

map.put("logging.pattern.level", "%5p [${spring.zipkin.service.name:" + "${spring.application.name:}},%X{traceId:-},%X{spanId:-}]");
inkz8wg9

inkz8wg92#

为了将其恢复到不再提供Sleuth的 Boot ,必须复制TraceEnvironmentPostProcessor,沿着在META-INF/spring.factories中具有一个条目
下面是我在原始代码的基础上稍微修改的代码,以使其通过SonarLint。

import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;

class TraceEnvironmentPostProcessor implements EnvironmentPostProcessor {

  private static final String DEFAULT_PROPERTIES_SOURCE_NAME = "defaultProperties";

  @Override
  public void postProcessEnvironment(
      final ConfigurableEnvironment environment, final SpringApplication application) {

    final Map<String, Object> map = new HashMap<>();
    final boolean sleuthEnabled =
        environment.getProperty("spring.sleuth.enabled", Boolean.class, true);
    final boolean sleuthDefaultLoggingPatternEnabled =
        environment.getProperty(
            "spring.sleuth.default-logging-pattern-enabled", Boolean.class, true);
    if (sleuthEnabled && sleuthDefaultLoggingPatternEnabled) {
      map.put(
          "logging.pattern.level",
          "%5p [${spring.zipkin.service.name:${spring.application.name:}},%X{traceId:-},%X{spanId:-}]");
      String neverRefreshables =
          environment.getProperty(
              "spring.cloud.refresh.never-refreshable", "com.zaxxer.hikari.HikariDataSource");
      map.put(
          "spring.cloud.refresh.never-refreshable",
          neverRefreshables
              + ",org.springframework.cloud.sleuth.instrument.jdbc.DataSourceWrapper");
    }
    final var propertySources = environment.getPropertySources();

    if (propertySources.contains(DEFAULT_PROPERTIES_SOURCE_NAME)) {
      final var source = propertySources.get(DEFAULT_PROPERTIES_SOURCE_NAME);
      if (source instanceof MapPropertySource target) {
        map.entrySet().stream()
            .filter(e -> !(target.containsProperty(e.getKey())))
            .forEach(e -> target.getSource().put(e.getKey(), e.getValue()));
      }
    } else {
      propertySources.addLast(new MapPropertySource(DEFAULT_PROPERTIES_SOURCE_NAME, map));
    }
  }
}

还有

org.springframework.boot.env.EnvironmentPostProcessor=\
net.trajano.swarm.logging.autoconfig.TraceEnvironmentPostProcessor

相关问题