特性概览

1. 上下文传播

使用头信息传播连接服务到服务。 默认格式是B3。相似于数据格式,也可以配置替代的标题格式,只要追踪和跨度ID与B3兼容。最重要的是,这意味跟踪ID和跨度ID是小写的十六进制,而不是UUID。除了跟踪标识符,其他属性(行李袋)也可以随请求一起传递。远程行李袋必须预先定义,但其他方面非常灵活。spring-doc.cadn.net.cn

To use the provided defaults you can set the spring.sleuth.propagation.type 属性。 该值可以是一个列表,在这种情况下将传播更多的追踪头。spring-doc.cadn.net.cn

为 Brave 我们支持 AWS, B3, W3C 传播类型。spring-doc.cadn.net.cn

你可以在此">how to 部分"中阅读更多关于如何提供自定义上下文传播的信息。spring-doc.cadn.net.cn

2. 采样

Spring Cloud Sleuth 将采样决策下推到跟踪器实现。 但是,您可以在运行时更改跟踪器实现。spring-doc.cadn.net.cn

其中一个这样的例子是跳过报告某些客户端跨度。spring-doc.cadn.net.cn

spring-doc.cadn.net.cn

要实现这一点,您可以设置spring.sleuth.web.client.skip-pattern,并使用要跳过的路径模式。spring-doc.cadn.net.cn

另一个选项是提供您自己的自定义org.springframework.cloud.sleuth.SamplerFunction<`org.springframework.cloud.sleuth.http.HttpRequest>实现,并定义何时不应采样给定的HttpRequestspring-doc.cadn.net.cn

spring-doc.cadn.net.cn

3. 包装

分布式跟踪通过在服务内部和跨服务传播字段来连接整个跟踪:特别是 traceId 和 spanId。 持有这些字段的上下文可以选择性地推送其他字段,无论涉及多少服务,这些字段都需要保持一致。 这些额外字段的简单名称是“Baggage”。spring-doc.cadn.net.cn

Sleuth 允许你定义哪些 baggage 被允许存在于 trace 上下文中,包括使用哪些 header 名称。spring-doc.cadn.net.cn

The following example shows setting baggage values using Spring Cloud Sleuth's API:spring-doc.cadn.net.cn

try (Tracer.SpanInScope ws = this.tracer.withSpan(initialSpan)) {
    BaggageInScope businessProcess = this.tracer.createBaggage(BUSINESS_PROCESS).set("ALM");
    BaggageInScope countryCode = this.tracer.createBaggage(COUNTRY_CODE).set("FO");
    try {
当前暂无行李件数或大小限制。请记住,太多行李会降低系统吞吐量或增加 RPC 延迟。在极端情况下,过多的行李可能导致应用程序崩溃,因为超过了传输层消息或标题容量。

你可以使用属性来定义没有特殊配置的字段,例如名称映射:spring-doc.cadn.net.cn

不使用前缀的键。 你设置的内容就是实际使用的内容。spring-doc.cadn.net.cn

在这些属性中的任意一个设置的名称将导致同名的Baggage值。spring-doc.cadn.net.cn

为了能够自动地设置行李值到Slf4j的MDC,您必须设置spring.sleuth.baggage.correlation-fields属性与一个允许本地或远程密钥的列表。例如spring.sleuth.baggage.correlation-fields=country-code会把country-code行李值设置到MDC。spring-doc.cadn.net.cn

请注意,额外的字段会传播并添加到从下一个下游跟踪上下文开始的MDC中。<br/> 要立即在当前跟踪上下文中将额外的字段添加到MDC,请配置该字段以在更新时刷新:<br/>spring-doc.cadn.net.cn

// configuration
@Bean
BaggageField countryCodeField() {
    return BaggageField.create("country-code");
}

@Bean
ScopeDecorator mdcScopeDecorator() {
    return MDCScopeDecorator.newBuilder()
            .clear()
            .add(SingleCorrelationField.newBuilder(countryCodeField())
                    .flushOnUpdate()
                    .build())
            .build();
}

// service
@Autowired
BaggageField countryCodeField;

countryCodeField.updateValue("new-value");
注意,向MDC添加条目会大大降低你应用程序的性能!

如果您想将行李条目作为标签添加,以便可以通过行李条目搜索跨度,可以使用允许的行李键列表设置spring.sleuth.baggage.tag-fields值。要禁用此功能,您必须传递spring.sleuth.propagation.tag.enabled=false属性。spring-doc.cadn.net.cn

3.1. 行李与标签

与跟踪 ID 类似,行李(Baggage)通常作为请求头附加到消息或请求中。标签(Tags)是以键值对形式发送到 Zipkin 的跨度(Span)中的数据。默认情况下,行李值不会被添加到跨度中,这意味着除非您选择加入,否则无法根据行李进行搜索。spring-doc.cadn.net.cn

要使行李也带有标签,请使用属性spring.sleuth.baggage.tag-fields,如下所示:spring-doc.cadn.net.cn

spring:
  sleuth:
    baggage:
      foo: bar
      remoteFields:
        - country-code
        - x-vcap-request-id
      tagFields:
        - country-code

4. OpenZipkin Brave Tracer 集成

Spring Cloud Sleuth通过spring-cloud-sleuth-brave模块中可用的桥梁与OpenZipkin Brave跟踪器集成。在本节中,您可以了解特定Brave集成。spring-doc.cadn.net.cn

您可以选择在代码中直接使用 Sleuth 的 API 或者 Brave 的 API(例如,Sleuth 的 Tracer 或 Brave 的 Tracer)。如果您希望直接使用此跟踪器实现的 API,请阅读他们的文档以了解更多信息spring-doc.cadn.net.cn

4.1. Brave Basics

以下是最核心的类型,您可能会使用到:spring-doc.cadn.net.cn

以下是 OpenZipkin Brave 项目中最相关的链接:spring-doc.cadn.net.cn

4.2. 勇敢采样

仅对追踪后端(例如 Zipkin)应用采样。 无论采样率如何,跟踪 ID 都会出现在日志中。 通过有选择地一致追踪部分请求而非全部请求,采样是一种防止系统过载的方法。spring-doc.cadn.net.cn

默认速率为每秒10个跟踪,由spring.sleuth.sampler.rate属性控制,并在我们知道除了日志记录以外Sleuth被使用时适用。如果每秒的跟踪速率超过100,则需非常小心,因为它可能会使您的跟踪系统过载。spring-doc.cadn.net.cn

采样器也可以通过 Java 配置来设置,如下例所示:spring-doc.cadn.net.cn

@Bean
public Sampler defaultSampler() {
    return Sampler.ALWAYS_SAMPLE;
}
您可以设置 HTTP 头 b31,或者在进行消息传递时,可以设置 spanFlags 头到 1

spring-doc.cadn.net.cn

这样做会强制当前请求被采样,而不考虑配置。spring-doc.cadn.net.cn

默认情况下,采样器将使用刷新范围机制。
这意味着您可以在运行时更改采样属性,重新加载应用程序,这些更改将会被反映出来。
然而,在某些情况下,围绕采样器创建代理并在太早的时间(从@PostConstruct注解方法)调用它可能会导致死锁。
在这种情况下,请显式地创建一个采样器bean,或者设置属性spring.sleuth.sampler.refresh.enabledfalse来禁用刷新范围支持。spring-doc.cadn.net.cn

4.3. Brave Baggage Java 配置

如果您需要执行上述之外的更高级操作,请不要定义属性,而是为使用的行李字段使用@Bean配置。spring-doc.cadn.net.cn

4.4 聪明的定制

brave.Tracer 对象完全由 sleuth 管理,因此您很少需要对其进行干预。 也就是说,Sleuth 支持多种 Customizer 类型,允许您通过自动配置或属性来配置 Sleuth 尚未完成的任何内容。spring-doc.cadn.net.cn

你可以尝试将下面的仅一个定义为Bean,Sleuth 会调用它来自定义行主:spring-doc.cadn.net.cn

4.4.1. Brave采样自定义

如果需要客户端/服务器采样,请注册一个类型为brave.sampler.SamplerFunction<HttpRequest>的bean,并将该bean命名为sleuthHttpClientSampler以进行客户端采样,sleuthHttpServerSampler用于服务器采样。spring-doc.cadn.net.cn

为了方便起见,@HttpClientSampler@HttpServerSampler 注解可用于注入适当的 bean 或通过其静态 String NAME 字段引用 bean 名称。spring-doc.cadn.net.cn

查看 Brave 的代码以了解如何制作基于路径的采样器 github.com/openzipkin/brave/tree/master/instrumentation/http#sampling-policyspring-doc.cadn.net.cn

如果您想完全重写HttpTracing Bean,可以使用SkipPatternProvider接口来检索URL Pattern,以便对不需要采样的跨度进行处理。以下是SkipPatternProvider在服务器端Sampler<HttpRequest>中使用的示例。spring-doc.cadn.net.cn

@Configuration(proxyBeanMethods = false)
    class Config {
  @Bean(name = HttpServerSampler.NAME)
  SamplerFunction<HttpRequest> myHttpSampler(SkipPatternProvider provider) {
      Pattern pattern = provider.skipPattern();
      return request -> {
          String url = request.path();
          boolean shouldSkip = pattern.matcher(url).matches();
          if (shouldSkip) {
              return false;
          }
          return null;
      };
  }
}

4.5. 勇敢的消息传递

Sleuth 自动配置 MessagingTracing bean,该 bean 作为消息传递仪器化(如 Kafka 或 JMS)的基础。spring-doc.cadn.net.cn

如果需要对消息跟踪的生产者/消费者采样进行自定义,只需注册类型为brave.sampler.SamplerFunction<MessagingRequest>的bean,并将该bean命名为sleuthProducerSampler作为生产者采样器和sleuthConsumerSampler作为消费者采样器。spring-doc.cadn.net.cn

为了方便起见,@ProducerSampler@ConsumerSampler 注解可用于注入适当的 bean 或通过其静态 String NAME 字段引用 bean 名称。spring-doc.cadn.net.cn

例如,此采样器每秒跟踪100个消费者请求(“alerts”通道除外)。其他请求将使用Tracing组件提供的全局速率。spring-doc.cadn.net.cn

@Configuration(proxyBeanMethods = false)
    class Config {
  @Bean(name = ConsumerSampler.NAME)
  SamplerFunction<MessagingRequest> myMessagingSampler() {
      return MessagingRuleSampler.newBuilder().putRule(channelNameEquals("alerts"), Sampler.NEVER_SAMPLE)
              .putRule(Matchers.alwaysMatch(), RateLimitingSampler.create(100)).build();
  }
}

4.6. 勇敢的OpenTracing

您可以使用 OpenTracing 桥接与 Brave 集成。只需将其添加到类路径中,OpenTracing Tracer 就会自动设置。spring-doc.cadn.net.cn

5. 将跨度发送到 Zipkin

Spring Cloud Sleuth 提供了与 OpenZipkin 分布式追踪系统的各种集成。
无论选择哪种跟踪器实现,只需将 spring-cloud-sleuth-zipkin 添加到类路径中即可开始向 Zipkin 发送跨度信息。
您可以选择通过 HTTP 或消息传递来完成此操作。
有关如何执行此操作的更多信息,请参阅 "如何部分"。spring-doc.cadn.net.cn

当跨度关闭时,它会通过HTTP发送到Zipkin。通信是异步的。
您可以设置spring.zipkin.baseUrl属性来配置URL,如下所示:spring-doc.cadn.net.cn

spring.zipkin.baseUrl: https://192.168.99.100:9411/

如果你想通过服务发现找到Zipkin,可以在URL中传递Zipkin的服务ID,如下面为zipkinserver服务ID的例子所示:spring-doc.cadn.net.cn

spring.zipkin.baseUrl: https://zipkinserver/

要禁用此功能,请将spring.zipkin.discovery-client-enabled设置为falsespring-doc.cadn.net.cn

启用发现客户端功能后,Sleuth 使用 LoadBalancerClient 来查找 Zipkin Server 的 URL。这意味着您可以设置负载均衡配置。spring-doc.cadn.net.cn

如果您在类路径中同时拥有 webrabbitactivemqkafka,您可能需要选择将跨度发送到 Zipkin 的方式。为了做到这一点,请将 webrabbitactivemqkafka 设置为 spring.zipkin.sender.type 属性。以下示例展示了如何设置 web 的发送程序类型:spring-doc.cadn.net.cn

spring.zipkin.sender.type: web

要自定义通过 HTTP 将跨度发送到 Zipkin 的 RestTemplate,可以注册 ZipkinRestTemplateCustomizer Bean。spring-doc.cadn.net.cn

@Configuration(proxyBeanMethods = false)
    class MyConfig {
    @Bean ZipkinRestTemplateCustomizer myCustomizer() {
        return new ZipkinRestTemplateCustomizer() {
            @Override
            void customize(RestTemplate restTemplate) {
                // customize the RestTemplate
            }
        };
    }
}

如果,但是,您希望完全控制创建RestTemplate对象的过程,则必须创建zipkin2.reporter.Sender类型的bean。spring-doc.cadn.net.cn

@Bean Sender myRestTemplateSender(ZipkinProperties zipkin,
        ZipkinRestTemplateCustomizer zipkinRestTemplateCustomizer) {
    RestTemplate restTemplate = mySuperCustomRestTemplate();
    zipkinRestTemplateCustomizer.customize(restTemplate);
    return myCustomSender(zipkin, restTemplate);
}

默认情况下,api path 将设置为 0 或 1,具体取决于编码器版本。如果要使用自定义 api 路径,可以使用以下属性进行配置(空情况,设置为空):spring-doc.cadn.net.cn

spring.zipkin.api-path: v2/path2

5.1. 自定义服务名称

默认情况下,Sleuth 假定当您将一个跨度发送到 Zipkin 时,您希望该跨度的服务名称等于 spring.application.name 属性的值。 但情况并非总是如此。 有时您希望为来自您的应用程序的所有跨度显式提供一个不同的服务名称。 为了实现这一点,您可以将以下属性传递给您的应用程序以覆盖该值(示例针对名为 myService 的服务):spring-doc.cadn.net.cn

spring.zipkin.service.name: myService

5.2. 主机定位器

本节介绍如何通过服务发现来定义主机。这不是指通过服务发现寻找Zipkin。

要定义与特定跨度对应的主机,我们需要解析主机名和端口。默认方法是从服务器属性中获取这些值。如果未设置,则尝试从网络接口中检索主机名。spring-doc.cadn.net.cn

如果您启用了发现客户端并希望从服务注册表中已注册的实例获取主机地址,则必须设置spring.zipkin.locator.discovery.enabled属性(该属性适用于基于HTTP和Stream的跨度报告),如下所示:spring-doc.cadn.net.cn

spring.zipkin.locator.discovery.enabled: true

5.3. 报告跨度的自定义

在 Sleuth 中,我们使用固定名称生成跨度。一些用户希望根据标记的值修改名称。spring-doc.cadn.net.cn

Sleuth 注册了一个 SpanFilter Bean,该 Bean 可自动跳过报告给定名称模式的跨度。
属性 spring.sleuth.span-filter.span-name-patterns-to-skip 包含跨度名称的默认跳过模式。
属性 spring.sleuth.span-filter.additional-span-name-patterns-to-skip 将提供的跨度名称模式追加到现有的模式中。
要禁用此功能,请将 spring.sleuth.span-filter.enabled 设置为 falsespring-doc.cadn.net.cn

5.3.1. Brave 自定义报告跨度

本节仅适用于 Brave 追踪器。

在报告跨度(例如,向 Zipkin 报告)之前,您可能希望以某种方式修改该跨度。
您可以实现一个 SpanHandler 来做到这一点。spring-doc.cadn.net.cn

以下示例展示了如何注册两个实现SpanHandler的bean:spring-doc.cadn.net.cn

@Bean
SpanHandler handlerOne() {
    return new SpanHandler() {
        @Override
        public boolean end(TraceContext traceContext, MutableSpan span, Cause cause) {
            span.name("foo");
            return true; // keep this span
        }
    };
}

@Bean
SpanHandler handlerTwo() {
    return new SpanHandler() {
        @Override
        public boolean end(TraceContext traceContext, MutableSpan span, Cause cause) {
            span.name(span.name() + " bar");
            return true; // keep this span
        }
    };
}

前面的示例会导致在报告之前(例如,到Zipkin)将报告跨度的名称更改为foo barspring-doc.cadn.net.cn

5.4. 覆盖Zipkin的自动配置

从版本 2.1.0 开始,Spring Cloud Sleuth 支持将跟踪信息发送到多个追踪系统。为了实现这一点,每个追踪系统都需要有 Reporter<Span>Sender。 如果要覆盖提供的 Bean,则需要为它们指定特定名称。 为此,您可以分别使用 ZipkinAutoConfiguration.REPORTER_BEAN_NAMEZipkinAutoConfiguration.SENDER_BEAN_NAMEspring-doc.cadn.net.cn

@Configuration(proxyBeanMethods = false)
protected static class MyConfig {

    @Bean(ZipkinAutoConfiguration.REPORTER_BEAN_NAME)
    Reporter<zipkin2.Span> myReporter(@Qualifier(ZipkinAutoConfiguration.SENDER_BEAN_NAME) MySender mySender) {
        return AsyncReporter.create(mySender);
    }

    @Bean(ZipkinAutoConfiguration.SENDER_BEAN_NAME)
    MySender mySender() {
        return new MySender();
    }

    static class MySender extends Sender {

        private boolean spanSent = false;

        boolean isSpanSent() {
            return this.spanSent;
        }

        @Override
        public Encoding encoding() {
            return Encoding.JSON;
        }

        @Override
        public int messageMaxBytes() {
            return Integer.MAX_VALUE;
        }

        @Override
        public int messageSizeInBytes(List<byte[]> encodedSpans) {
            return encoding().listSizeInBytes(encodedSpans);
        }

        @Override
        public Call<Void> sendSpans(List<byte[]> encodedSpans) {
            this.spanSent = true;
            return Call.create(null);
        }

    }

}

6. 日志集成

跟踪配置了日志上下文,其中包含服务名称(%{spring.zipkin.service.name}%{spring.application.name},如果前一个未设置)、跨度ID(%{spanId})和跟踪ID(%{traceId})。这些信息帮助您将日志与分布式跟踪连接起来,并允许您选择使用哪些工具来排查您的服务问题。spring-doc.cadn.net.cn

一旦您找到带有错误的日志,就可以在消息中查找跟踪 ID。将其粘贴到分布式追踪系统中,即可可视化整个调用链路,无论初始请求最终触发了多少个服务。spring-doc.cadn.net.cn

backend.log:  2020-04-09 17:45:40.516 ERROR [backend,5e8eeec48b08e26882aba313eb08f0a4,dcc1df555b5777b3] 97203 --- [nio-9000-exec-1] o.s.c.s.i.web.ExceptionLoggingFilter     : Uncaught exception thrown
frontend.log:2020-04-09 17:45:40.574 ERROR [frontend,5e8eeec48b08e26882aba313eb08f0a4,82aba313eb08f0a4] 97192 --- [nio-8081-exec-2] o.s.c.s.i.web.ExceptionLoggingFilter     : Uncaught exception thrown

在上方,您会注意到跟踪ID为5e8eeec48b08e26882aba313eb08f0a4。例如。
此日志配置由Sleuth自动设置。
您可以禁用它通过使用spring.sleuth.enabled=false属性禁用Sleuth或放置您自己的logging.pattern.level属性。spring-doc.cadn.net.cn

如果您使用日志聚合工具(如KibanaSplunk等),您可以对发生的事件进行排序。来自 Kibana 的一个示例如下图所示:spring-doc.cadn.net.cn

Log correlation with Kibana

你可以使用 Logstash , 下面的列表显示了 Logstash 的 Grok 模式:spring-doc.cadn.net.cn

filter {
  # pattern matching logback pattern
  grok {
    match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}\s+%{LOGLEVEL:severity}\s+\[%{DATA:service},%{DATA:trace},%{DATA:span}\]\s+%{DATA:pid}\s+---\s+\[%{DATA:thread}\]\s+%{DATA:class}\s+:\s+%{GREEDYDATA:rest}" }
  }
  date {
    match => ["timestamp", "ISO8601"]
  }
  mutate {
    remove_field => ["timestamp"]
  }
}
如果您想将Grok与Cloud Foundry的日志一起使用,您必须使用以下模式:
filter {
  # pattern matching logback pattern
  grok {
    match => { "message" => "(?m)OUT\s+%{TIMESTAMP_ISO8601:timestamp}\s+%{LOGLEVEL:severity}\s+\[%{DATA:service},%{DATA:trace},%{DATA:span}\]\s+%{DATA:pid}\s+---\s+\[%{DATA:thread}\]\s+%{DATA:class}\s+:\s+%{GREEDYDATA:rest}" }
  }
  date {
    match => ["timestamp", "ISO8601"]
  }
  mutate {
    remove_field => ["timestamp"]
  }
}

6.1. 使用 Logstash 的 JSON Logback

通常情况下,您并不希望将日志存储在文本文件中,而是存储在一个JSON文件中,以便Logstash能够立即提取。
为此,您需要执行以下操作(为了便于阅读,我们使用groupId:artifactId:version表示法传递依赖项)。spring-doc.cadn.net.cn

  1. 确保 Logback 在类路径上(ch.qos.logback:logback-core)。spring-doc.cadn.net.cn

  2. 添加 Logstash Logback 编码器。
    例如,要使用版本 4.6,请添加 net.logstash.logback:logstash-logback-encoder:4.6spring-doc.cadn.net.cn

日志框架设置spring-doc.cadn.net.cn

考虑以下Logback配置文件(logback-spring.xml)的示例。spring-doc.cadn.net.cn

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <springProperty scope="context" name="springAppName" source="spring.application.name"/>
    <!-- Example for logging into the build folder of your project -->
    <property name="LOG_FILE" value="${BUILD_FOLDER:-build}/${springAppName}"/>

    <!-- You can override this to have a custom pattern -->
    <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%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>

    <!-- Appender to log to console -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <!-- Minimum logging level to be presented in the console logs-->
            <level>DEBUG</level>
        </filter>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <!-- Appender to log to file -->
    <appender name="flatfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.gz</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>
    <!-- Appender to log to file in a JSON format -->
    <appender name="logstash" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_FILE}.json</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_FILE}.json.%d{yyyy-MM-dd}.gz</fileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <timestamp>
                    <timeZone>UTC</timeZone>
                </timestamp>
                <pattern>
                    <pattern>
                        {
                        "timestamp": "@timestamp",
                        "severity": "%level",
                        "service": "${springAppName:-}",
                        "trace": "%X{traceId:-}",
                        "span": "%X{spanId:-}",
                        "pid": "${PID:-}",
                        "thread": "%thread",
                        "class": "%logger{40}",
                        "rest": "%message"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
    </appender>
    <root level="INFO">
        <appender-ref ref="console"/>
        <!-- uncomment this to have also JSON logs -->
        <!--<appender-ref ref="logstash"/>-->
        <!--<appender-ref ref="flatfile"/>-->
    </root>
</configuration>

该 Logback 配置文件:spring-doc.cadn.net.cn

如果您使用自定义的 logback-spring.xml,则必须通过spring.application.name传递bootstrap而不是在application属性文件中进行传递。

spring-doc.cadn.net.cn

否则,您的自定义 logback 文件无法正确读取该属性。spring-doc.cadn.net.cn

7. 接下来阅读什么

如果您想了解本节中讨论的任何类的更多信息,可以直接浏览源代码。如果您有任何具体问题,请参阅常见问题解答部分。spring-doc.cadn.net.cn

如果您熟悉 Spring Cloud Sleuth 的核心功能,可以继续阅读关于 Spring Cloud Sleuth 的集成spring-doc.cadn.net.cn