追踪
Spring Boot Actuator 为 Micrometer Tracing 提供了依赖管理和自动配置,它是流行追踪器库的门面。
要了解更多关于 Micrometer Tracing 的能力,请参阅其参考文档。 |
支持的追踪器
Spring Boot 为以下追踪器提供了自动配置
-
OpenTelemetry 与 Zipkin, Wavefront, 或 OTLP
入门
我们需要一个示例应用来开始追踪。为此,开发你的第一个 Spring Boot 应用部分介绍的简单“Hello World!” web 应用就足够了。我们将使用 OpenTelemetry 追踪器并以 Zipkin 作为追踪后端。
回顾一下,我们的主应用代码如下所示
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);
}
}
在 home() 方法中添加了一个日志语句,这稍后会很重要。 |
现在我们需要添加以下依赖项
-
org.springframework.boot:spring-boot-starter-actuator
-
io.micrometer:micrometer-tracing-bridge-otel
- 将 Micrometer Observation API 桥接到 OpenTelemetry。 -
io.opentelemetry:opentelemetry-exporter-zipkin
- 将 追踪数据 报告给 Zipkin。
添加以下应用属性
-
属性
-
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 提供了一种有用的方式,可以将日志文件中的行与 span/trace 关联起来。如果你使用 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 格式
-
属性
-
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 Tracing 支持多种追踪器实现,因此与 Spring Boot 可能有多种依赖组合。
所有追踪器实现都需要 org.springframework.boot:spring-boot-starter-actuator
依赖。
OpenTelemetry 与 Zipkin
使用 OpenTelemetry 进行追踪并报告给 Zipkin 需要以下依赖项
-
io.micrometer:micrometer-tracing-bridge-otel
- 将 Micrometer Observation API 桥接到 OpenTelemetry。 -
io.opentelemetry:opentelemetry-exporter-zipkin
- 将追踪数据报告给 Zipkin。
使用 management.zipkin.tracing.*
配置属性来配置报告给 Zipkin。
OpenTelemetry 与 Wavefront
使用 OpenTelemetry 进行追踪并报告给 Wavefront 需要以下依赖项
-
io.micrometer:micrometer-tracing-bridge-otel
- 将 Micrometer Observation API 桥接到 OpenTelemetry。 -
io.micrometer:micrometer-tracing-reporter-wavefront
- 将追踪数据报告给 Wavefront。
使用 management.wavefront.*
配置属性来配置报告给 Wavefront。
OpenTelemetry 与 OTLP
使用 OpenTelemetry 进行追踪并使用 OTLP 进行报告需要以下依赖项
-
io.micrometer:micrometer-tracing-bridge-otel
- 将 Micrometer Observation API 桥接到 OpenTelemetry。 -
io.opentelemetry:opentelemetry-exporter-otlp
- 将追踪数据报告给可接受 OTLP 的收集器。
使用 management.otlp.tracing.*
配置属性来配置使用 OTLP 进行报告。
与 Micrometer Observation 集成
一个 TracingAwareMeterObservationHandler
会自动注册到 ObservationRegistry
上,它会为每个完成的观测创建 span。
创建自定义 Span
你可以通过启动一个观测来创建自己的 span。为此,将 ObservationRegistry
注入到你的组件中
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 ...
});
}
}
这将创建一个名为“some-operation”的观测,并带有一个标签“some-tag=some-value”。
如果你只想创建一个 span 而不创建指标 (metric),你需要使用 Micrometer 提供的较低级别的 Tracer API。 |
Baggage
你可以使用 Tracer
API 创建 baggage
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
}
}
}
此示例创建一个名为 baggage1
、值为 value1
的 baggage。如果你使用 W3C propagation,baggage 会在网络上自动传播。如果你使用 B3 propagation,baggage 不会自动传播。要在网络上手动传播 baggage,请使用 management.tracing.baggage.remote-fields
配置属性(这也适用于 W3C)。对于上面的示例,将此属性设置为 baggage1
将生成 HTTP 头 baggage1: value1
。
如果你想将 baggage 传播到 MDC,请使用 management.tracing.baggage.correlation.fields
配置属性。对于上面的示例,将此属性设置为 baggage1
将生成一个名为 baggage1
的 MDC 条目。
测试
当使用 @SpringBootTest
时,负责报告数据的追踪组件不会自动配置。详情请参阅使用追踪。