|
此版本仍在开发中,尚未视为稳定版。如需最新稳定版本,请使用 Spring Boot 4.0.4! |
追踪
Spring Boot Actuator 为 Micrometer Tracing 提供了依赖管理和自动配置,Micrometer Tracing 是一个面向流行追踪器库的外观(facade)。
| 要了解更多关于 Micrometer Tracing 功能的信息,请参阅其参考文档。 |
支持的追踪器
Spring Boot 为以下追踪器提供了自动配置:
-
OpenZipkin Brave 与 Zipkin 或 Wavefront 一起使用
快速开始
我们需要一个示例应用程序,以便开始使用追踪功能。 就我们的目的而言,《开发你的第一个 Spring Boot 应用程序》一节中介绍的简单“Hello World!” Web 应用程序就足够了。 我们将使用 OpenTelemetry 追踪器,并以 Zipkin 作为追踪后端。
回顾一下,我们的主应用程序代码如下所示:
-
Java
-
Kotlin
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class MyApplication {
private static final Log logger = LogFactory.getLog(MyApplication.class);
@RequestMapping("/")
String home() {
logger.info("home() has been called");
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@SpringBootApplication
class MyApplication {
private val logger: Log = LogFactory.getLog(MyApplication::class.java)
@RequestMapping("/")
fun home(): String {
logger.info("home() has been called")
return "Hello, World!"
}
}
fun main(args: Array<String>) {
runApplication<MyApplication>(*args)
}
home() 方法中添加了一条日志记录语句,这在后面会很重要。 |
现在我们必须添加以下依赖项:
-
org.springframework.boot:spring-boot-starter-actuator -
io.micrometer:micrometer-tracing-bridge-otel- 将 Micrometer Observation API 桥接到 OpenTelemetry。 -
io.opentelemetry:opentelemetry-exporter-zipkin- 将追踪数据上报至 Zipkin。
添加以下应用程序属性:
-
Properties
-
YAML
management.tracing.sampling.probability=1
management:
tracing:
sampling:
probability: 1.0
默认情况下,Spring Boot 仅对 10% 的请求进行采样,以防止追踪后端过载。 此属性将其调整为 100%,以便每个请求都会发送到追踪后端。
为了收集和可视化追踪数据,我们需要一个正在运行的追踪后端。 这里我们使用 Zipkin 作为追踪后端。 Zipkin 快速入门指南 提供了如何在本地启动 Zipkin 的说明。
Zipkin 启动运行后,您就可以启动您的应用程序了。
如果您在web浏览器中打开localhost:8080,您应该会看到以下输出:
Hello World!
在幕后,已为该 HTTP 请求创建了一个观测(observation),该观测随后被桥接到 OpenTelemetry,由 OpenTelemetry 向 Zipkin 报告一条新的追踪(trace)。
现在在 localhost:9411 打开 Zipkin UI,点击“运行查询”(Run Query)按钮以列出所有已收集的追踪信息。
你应该能看到一条追踪记录。
点击“显示”(Show)按钮以查看该追踪的详细信息。
日志关联 ID
关联 ID(Correlation IDs)提供了一种有效的方式,可将日志文件中的日志行与跨度(spans)/追踪(traces)关联起来。 如果您使用的是 Micrometer Tracing,Spring Boot 默认会在您的日志中包含关联 ID。
默认的相关性 ID 由 traceId 和 spanId 的 MDC 值构建而成。
例如,如果 Micrometer Tracing 已添加了一个 MDC traceId 值 803B448A0489F84084905D3093480352 和一个 MDC spanId 值 3425F23BB2432450,则日志输出将包含相关性 ID [803B448A0489F84084905D3093480352-3425F23BB2432450]。
如果你希望为你的关联 ID 使用不同的格式,可以使用 logging.pattern.correlation 属性来定义一个。
例如,以下配置将为 Logback 提供一个 Spring Cloud Sleuth 之前所使用的关联 ID 格式:
-
Properties
-
YAML
logging.pattern.correlation=[${spring.application.name:},%X{traceId:-},%X{spanId:-}]
logging.include-application-name=false
logging:
pattern:
correlation: "[${spring.application.name:},%X{traceId:-},%X{spanId:-}] "
include-application-name: false
在上面的示例中,logging.include-application-name 被设置为 false,以避免应用程序名称在日志消息中重复出现(因为 logging.pattern.correlation 中已经包含了该名称)。
另外值得一提的是,logging.pattern.correlation 的末尾包含一个空格,以便默认情况下与紧随其后的记录器名称分隔开。 |
| 关联ID依赖于上下文传播。 请阅读此文档以获取更多详细信息。 |
传播追踪
要在网络上自动传播追踪信息,请使用自动配置的 RestTemplateBuilder、RestClient.Builder 或 WebClient.Builder 来构建客户端。
如果您在不使用自动配置的构建器的情况下创建 RestTemplate、RestClient 或 WebClient,自动追踪传播将无法生效! |
跟踪器实现
由于 Micrometer Tracer 支持多种追踪器实现,因此在 Spring Boot 中可以使用多种依赖组合。
所有追踪器(tracer)实现都需要 org.springframework.boot:spring-boot-starter-actuator 依赖。
使用 Zipkin 的 OpenTelemetry
使用 OpenTelemetry 进行追踪并将数据上报到 Zipkin 需要以下依赖项:
-
io.micrometer:micrometer-tracing-bridge-otel- 将 Micrometer Observation API 桥接到 OpenTelemetry。 -
io.opentelemetry:opentelemetry-exporter-zipkin- 将追踪数据上报至 Zipkin。
使用 management.zipkin.tracing.* 配置属性来配置向 Zipkin 报告追踪数据。
使用 Wavefront 的 OpenTelemetry
使用 OpenTelemetry 进行追踪并将数据上报到 Wavefront 需要以下依赖项:
-
io.micrometer:micrometer-tracing-bridge-otel- 将 Micrometer Observation API 桥接到 OpenTelemetry。 -
io.micrometer:micrometer-tracing-reporter-wavefront- 将追踪数据上报到 Wavefront。
使用 management.wavefront.* 配置属性来配置向 Wavefront 报告数据。
使用 OTLP 的 OpenTelemetry
使用 OpenTelemetry 进行追踪并通过 OTLP 上报需要以下依赖项:
-
io.micrometer:micrometer-tracing-bridge-otel- 将 Micrometer Observation API 桥接到 OpenTelemetry。 -
io.opentelemetry:opentelemetry-exporter-otlp- 将追踪数据上报给能够接收 OTLP 的收集器。
使用 management.otlp.tracing.* 配置属性来配置通过 OTLP 进行上报。
如果您需要对 OTLP span 导出器应用高级自定义,请考虑注册 OtlpHttpSpanExporterBuilderCustomizer 或 OtlpGrpcSpanExporterBuilderCustomizer Bean。
这些将在创建 OtlpHttpSpanExporter 或 OtlpGrpcSpanExporter 之前被调用。
自定义器的优先级高于自动配置所应用的任何设置。 |
与 Micrometer 观测的集成
TracingAwareMeterObservationHandler 会自动注册到 ObservationRegistry,从而为每个已完成的观测创建跨度(spans)。
创建自定义跨度
您可以通过启动一个观测来创建自己的跨度。
为此,请将 ObservationRegistry 注入到您的组件中:
-
Java
-
Kotlin
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
import org.springframework.stereotype.Component;
@Component
class CustomObservation {
private final ObservationRegistry observationRegistry;
CustomObservation(ObservationRegistry observationRegistry) {
this.observationRegistry = observationRegistry;
}
void someOperation() {
Observation observation = Observation.createNotStarted("some-operation", this.observationRegistry);
observation.lowCardinalityKeyValue("some-tag", "some-value");
observation.observe(() -> {
// Business logic ...
});
}
}
import io.micrometer.observation.Observation
import io.micrometer.observation.ObservationRegistry
import org.springframework.stereotype.Component
@Component
class CustomObservation(private val observationRegistry: ObservationRegistry) {
fun someOperation() {
Observation.createNotStarted("some-operation", observationRegistry)
.lowCardinalityKeyValue("some-tag", "some-value")
.observe {
// Business logic ...
}
}
}
这将创建一个名为“some-operation”的观测(observation),并带有标签“some-tag=some-value”。
如果您想创建一个 span 而不创建指标,则需要使用 Micrometer 提供的底层 Tracer API。 |
行李
您可以使用 Tracer API 创建行李:
-
Java
-
Kotlin
import io.micrometer.tracing.BaggageInScope;
import io.micrometer.tracing.Tracer;
import org.springframework.stereotype.Component;
@Component
class CreatingBaggage {
private final Tracer tracer;
CreatingBaggage(Tracer tracer) {
this.tracer = tracer;
}
void doSomething() {
try (BaggageInScope scope = this.tracer.createBaggageInScope("baggage1", "value1")) {
// Business logic
}
}
}
import io.micrometer.tracing.Tracer
import org.springframework.stereotype.Component
@Component
class CreatingBaggage(private val tracer: Tracer) {
fun doSomething() {
tracer.createBaggageInScope("baggage1", "value1").use {
// Business logic
}
}
}
此示例创建了一个名为 baggage1 的 baggage,其值为 value1。
如果您使用的是 W3C 传播方式,该 baggage 会自动通过网络进行传播。
如果您使用的是 B3 传播方式,则 baggage 不会自动传播。
要手动通过网络传播 baggage,请使用 management.tracing.baggage.remote-fields 配置属性(该属性对 W3C 也同样有效)。
对于上述示例,将此属性设置为 baggage1 将生成一个 HTTP 头部 baggage1: value1。
如果要将 baggage(随行数据)传播到 MDC,请使用 management.tracing.baggage.correlation.fields 配置属性。
对于上面的示例,将此属性设置为 baggage1 会生成一个名为 baggage1 的 MDC 条目。
测试
使用 @SpringBootTest 时,报告数据的追踪组件不会自动配置。
请参阅 使用追踪 了解更多详情。