文章目录
- [1. 概览](#1. 概览)
- [2. 上下文传播(Context Propagation)](#2. 上下文传播(Context Propagation))
- [3. 公共标签(Common Tags)](#3. 公共标签(Common Tags))
- [4. 禁用观测采集](#4. 禁用观测采集)
- [5. Micrometer Observation 注解支持](#5. Micrometer Observation 注解支持)
- [6. OpenTelemetry 支持](#6. OpenTelemetry 支持)
-
- [6.1 自动配置](#6.1 自动配置)
- [6.2 关闭 OpenTelemetry](#6.2 关闭 OpenTelemetry)
- [6.3 环境变量映射](#6.3 环境变量映射)
- [6.4 日志(Logging)](#6.4 日志(Logging))
- [6.5 指标(Metrics)](#6.5 指标(Metrics))
- [6.6 链路追踪(Tracing)](#6.6 链路追踪(Tracing))
1. 概览
可观测性 指能够从外部观察运行中系统内部状态的能力。它包含三大支柱:日志、指标、链路追踪(Traces)。
针对指标与链路追踪,Spring Boot 使用 Micrometer Observation。如果你希望创建自定义观测(自动生成指标和追踪数据),可以注入 ObservationRegistry。
示例代码:
java
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
import org.springframework.stereotype.Component;
@Component
public class MyCustomObservation {
private final ObservationRegistry observationRegistry;
public MyCustomObservation(ObservationRegistry observationRegistry) {
this.observationRegistry = observationRegistry;
}
public void doSomething() {
Observation.createNotStarted("doSomething", this.observationRegistry)
.lowCardinalityKeyValue("locale", "en-US")
.highCardinalityKeyValue("userId", "42")
.observe(() -> {
// 执行业务逻辑
});
}
}
标签说明:
- 低基数标签(
low cardinality tags)会同时作用于指标和链路; - 高基数标签(
high cardinality tags)仅会出现在链路追踪中。
类型为 ObservationPredicate、GlobalObservationConvention、ObservationFilter、ObservationHandler 的 Bean 会自动注册到 ObservationRegistry。你还可以注册任意数量 ObservationRegistryCustomizer Bean,对注册器进行进一步自定义配置。
JDBC 的可观测能力需要引入独立项目配置。Datasource Micrometer 提供 Spring Boot Starter,在执行 JDBC 操作时自动创建观测。更多信息请查阅官方参考文档。
R2DBC 可观测能力内置在 Spring Boot中,启用方式:引入依赖 io.r2dbc:r2dbc-proxy。
2. 上下文传播(Context Propagation)
可观测能力依赖上下文传播库,用来在线程之间、响应式调用链中传递当前观测上下文。
默认情况下,响应式算子不会自动恢复 ThreadLocal 上下文。该行为由配置项 spring.reactor.context-propagation 控制,设置为 auto 开启自动传播。
如果你使用 @Async 方法且依赖自动配置的 AsyncTaskExecutor,需要通过配置 spring.task.execution.propagate-context=true 主动开启上下文传播。
如果你手动配置 AsyncTaskExecutor,需要注册 ContextPropagatingTaskDecorator Bean,示例如下:
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.support.ContextPropagatingTaskDecorator;
@Configuration(proxyBeanMethods = false)
class ContextPropagationConfiguration {
@Bean
ContextPropagatingTaskDecorator contextPropagatingTaskDecorator() {
return new ContextPropagatingTaskDecorator();
}
}
关于 Observation 的更多细节,请查阅 Micrometer Observation 官方文档。
3. 公共标签(Common Tags)
公共标签一般用于运行环境维度下钻分析,例如主机、实例、区域、部署环境等。公共标签会以低基数标签形式作用于所有观测。
配置示例:
yaml
management.observations.key-values.region=us-east-1
management.observations.key-values.stack=prod
上面配置会给所有观测添加标签:region=us-east-1、stack=prod。
4. 禁用观测采集
如果你需要阻止部分观测上报,可以使用 management.observations.enable.* 配置:
yaml
management.observations.enable.denied.prefix=false
management.observations.enable.another.denied.prefix=false
以上配置会禁止名称以 denied.prefix、another.denied.prefix 开头的所有观测上报。
如需关闭 Spring Security 相关观测上报:
yaml
management.observations.enable.spring.security=false
想要更灵活地控制观测上报,可以实现 ObservationPredicate 并注册为 Bean。只有所有 ObservationPredicate 返回 true,对应的观测才会被上报。
java
import io.micrometer.observation.Observation.Context;
import io.micrometer.observation.ObservationPredicate;
import org.springframework.stereotype.Component;
@Component
class MyObservationPredicate implements ObservationPredicate {
@Override
public boolean test(String name, Context context) {
// 拦截名称包含 denied 的观测
return !name.contains("denied");
}
}
5. Micrometer Observation 注解支持
如需开启 @Observed、@Timed、@Counted、@MeterTag、@NewSpan 等可观测注解扫描,配置:
yaml
management.observations.annotations.enabled=true
同时需要引入 org.aspectj:aspectjweaver(包含在 spring-boot-starter-aspectj)。该能力由 Micrometer 原生提供,详情参考 Micrometer、Micrometer Observation、Micrometer Tracing 文档。
⚠️ 注意:如果给已经内置埋点的类/方法添加注解(例如 Spring Data Repository、Spring MVC Controller),会产生重复观测。
解决方案二选一:
- 通过配置或
ObservationPredicate关闭自动埋点,只使用自定义注解; - 删除自定义注解,使用框架内置观测。
6. OpenTelemetry 支持
6.1 自动配置
应用接入 OpenTelemetry 存在多种方式:可以使用 OpenTelemetry Java Agent,或是社区维护的 OpenTelemetry Spring Boot Starter;指标与链路遵循 OTel 规范语义约定。
本文档描述 Spring 官方支持的 OpenTelemetry 集成方案:基于 Micrometer + OTLP Exporter;指标与链路语义规范遵循 Spring 系列项目文档定义。
Spring Boot Actuator 模块内置基础 OpenTelemetry 支持:
- 框架自动提供
OpenTelemetryBean; - 如果上下文中存在
SdkTracerProvider、ContextPropagators、SdkLoggerProvider、SdkMeterProvider,会自动注册。 - 自动创建
ResourceBean,自动配置的Resource属性可通过management.opentelemetry.resource-attributes指定。配置中的属性会和环境变量OTEL_RESOURCE_ATTRIBUTES、OTEL_SERVICE_NAME合并,配置文件优先级高于环境变量。
如果你自行定义了 Resource Bean,则上述自动合并逻辑不再生效。
Spring Boot 不会自动导出 OpenTelemetry 原生指标与日志 ;只有搭配 Micrometer Tracing 使用时,链路追踪导出才会自动配置。
6.2 关闭 OpenTelemetry
配置 management.opentelemetry.enabled=false 关闭 OpenTelemetry 支持。
行为类似环境变量 OTEL_SDK_DISABLED(逻辑取反):SDK 关闭后,指标、链路、日志使用空实现;上下文传播器不受影响,正常工作。
重要提醒:
Spring Boot本身不使用OpenTelemetry原生指标能力,因此即使关闭OpenTelemetry,Micrometer指标依然可能正常采集。
6.3 环境变量映射
Spring Boot 支持一部分 OpenTelemetry SDK 环境变量,启动时自动映射为 Spring Boot 配置项。
当同时存在「信号专属变量」(例如 OTEL_EXPORTER_OTLP_TRACES_ENDPOINT)和通用变量(OTEL_EXPORTER_OTLP_ENDPOINT)时,信号专属变量优先 。通用变量作为兜底时,框架自动追加路径后缀:v1/traces、v1/metrics、v1/logs。
示例:配置 OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318,链路地址自动拼接为 http://collector:4318/v1/traces。
关闭自动映射:
yaml
management.opentelemetry.map-environment-variables=false
通用配置映射:
| 环境变量 | Spring Boot 配置项 |
|---|---|
| OTEL_SDK_DISABLED | management.opentelemetry.enabled(逻辑取反) |
| OTEL_PROPAGATORS | management.tracing.propagation.type、management.tracing.baggage.enabled |
| OTEL_TRACES_SAMPLER | management.opentelemetry.tracing.sampler |
| OTEL_TRACES_SAMPLER_ARG | management.tracing.sampling.probability |
| OTEL_METRICS_EXEMPLAR_FILTER | management.tracing.exemplars.include |
指标导出器映射:
| 环境变量 | Spring Boot 配置项 |
|---|---|
| OTEL_EXPORTER_OTLP_METRICS_ENDPOINT / OTEL_EXPORTER_OTLP_ENDPOINT | management.otlp.metrics.export.url |
| OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE | management.otlp.metrics.export.aggregation-temporality |
| OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION | management.otlp.metrics.export.histogram-flavor |
| OTEL_EXPORTER_OTLP_METRICS_COMPRESSION / OTEL_EXPORTER_OTLP_COMPRESSION | management.otlp.metrics.export.compression-mode |
| OTEL_EXPORTER_OTLP_METRICS_TIMEOUT / OTEL_EXPORTER_OTLP_TIMEOUT | management.otlp.metrics.export.read-timeout |
| OTEL_EXPORTER_OTLP_METRICS_HEADERS / OTEL_EXPORTER_OTLP_HEADERS | management.otlp.metrics.export.headers |
| OTEL_METRIC_EXPORT_INTERVAL | management.otlp.metrics.export.step |
| OTEL_METRICS_EXPORTER | management.otlp.metrics.export.enabled(仅 otlp 开启导出) |
| OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE / OTEL_EXPORTER_OTLP_CERTIFICATE | management.otlp.metrics.export.ssl.bundle |
| OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY / OTEL_EXPORTER_OTLP_CLIENT_KEY | management.otlp.metrics.export.ssl.bundle |
| OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE / OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE | management.otlp.metrics.export.ssl.bundle |
链路导出器映射:
| 环境变量 | Spring Boot 配置项 |
|---|---|
| OTEL_EXPORTER_OTLP_TRACES_ENDPOINT / OTEL_EXPORTER_OTLP_ENDPOINT | management.opentelemetry.tracing.export.otlp.endpoint |
| OTEL_EXPORTER_OTLP_TRACES_COMPRESSION / OTEL_EXPORTER_OTLP_COMPRESSION | management.opentelemetry.tracing.export.otlp.compression |
| OTEL_EXPORTER_OTLP_TRACES_TIMEOUT / OTEL_EXPORTER_OTLP_TIMEOUT | management.opentelemetry.tracing.export.otlp.timeout |
| OTEL_EXPORTER_OTLP_TRACES_PROTOCOL / OTEL_EXPORTER_OTLP_PROTOCOL | management.opentelemetry.tracing.export.otlp.transport |
| OTEL_EXPORTER_OTLP_TRACES_HEADERS / OTEL_EXPORTER_OTLP_HEADERS | management.opentelemetry.tracing.export.otlp.headers |
| OTEL_BSP_SCHEDULE_DELAY | management.opentelemetry.tracing.export.schedule-delay |
| OTEL_BSP_EXPORT_TIMEOUT | management.opentelemetry.tracing.export.timeout |
| OTEL_BSP_MAX_QUEUE_SIZE | management.opentelemetry.tracing.export.max-queue-size |
| OTEL_BSP_MAX_EXPORT_BATCH_SIZE | management.opentelemetry.tracing.export.max-batch-size |
| OTEL_TRACES_EXPORTER | management.tracing.export.otlp.enabled(仅 otlp 开启导出) |
| OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT / OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT | management.opentelemetry.tracing.limits.max-attribute-value-length |
| OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT / OTEL_ATTRIBUTE_COUNT_LIMIT | management.opentelemetry.tracing.limits.max-attributes |
| OTEL_SPAN_EVENT_COUNT_LIMIT | management.opentelemetry.tracing.limits.max-events |
| OTEL_SPAN_LINK_COUNT_LIMIT | management.opentelemetry.tracing.limits.max-links |
| OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT | management.opentelemetry.tracing.limits.max-attributes-per-event |
| OTEL_LINK_ATTRIBUTE_COUNT_LIMIT | management.opentelemetry.tracing.limits.max-attributes-per-link |
| OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE / OTEL_EXPORTER_OTLP_CERTIFICATE | management.opentelemetry.tracing.export.otlp.ssl.bundle |
| OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY / OTEL_EXPORTER_OTLP_CLIENT_KEY | management.opentelemetry.tracing.export.otlp.ssl.bundle |
| OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE / OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE | management.opentelemetry.tracing.export.otlp.ssl.bundle |
日志导出器映射:
| 环境变量 | Spring Boot 配置项 |
|---|---|
| OTEL_EXPORTER_OTLP_LOGS_ENDPOINT / OTEL_EXPORTER_OTLP_ENDPOINT | management.opentelemetry.logging.export.otlp.endpoint |
| OTEL_EXPORTER_OTLP_LOGS_COMPRESSION / OTEL_EXPORTER_OTLP_COMPRESSION | management.opentelemetry.logging.export.otlp.compression |
| OTEL_EXPORTER_OTLP_LOGS_TIMEOUT / OTEL_EXPORTER_OTLP_TIMEOUT | management.opentelemetry.logging.export.otlp.timeout |
| OTEL_EXPORTER_OTLP_LOGS_PROTOCOL / OTEL_EXPORTER_OTLP_PROTOCOL | management.opentelemetry.logging.export.otlp.transport |
| OTEL_EXPORTER_OTLP_LOGS_HEADERS / OTEL_EXPORTER_OTLP_HEADERS | management.opentelemetry.logging.export.otlp.headers |
| OTEL_BLRP_SCHEDULE_DELAY | management.opentelemetry.logging.export.schedule-delay |
| OTEL_BLRP_EXPORT_TIMEOUT | management.opentelemetry.logging.export.timeout |
| OTEL_BLRP_MAX_QUEUE_SIZE | management.opentelemetry.logging.export.max-queue-size |
| OTEL_BLRP_MAX_EXPORT_BATCH_SIZE | management.opentelemetry.logging.export.max-batch-size |
| OTEL_LOGS_EXPORTER | management.logging.export.otlp.enabled(仅 otlp 开启导出) |
| OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT / OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT | management.opentelemetry.logging.limits.max-attribute-value-length |
| OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT / OTEL_ATTRIBUTE_COUNT_LIMIT | management.opentelemetry.logging.limits.max-attributes |
| OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE / OTEL_EXPORTER_OTLP_CERTIFICATE | management.opentelemetry.logging.export.otlp.ssl.bundle |
| OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY / OTEL_EXPORTER_OTLP_CLIENT_KEY | management.opentelemetry.logging.export.otlp.ssl.bundle |
| OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE / OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE | management.opentelemetry.logging.export.otlp.ssl.bundle |
Resource 资源相关环境变量
OTEL_RESOURCE_ATTRIBUTESOTEL_SERVICE_NAME
OTEL_RESOURCE_ATTRIBUTES 使用逗号分隔键值对,示例:key1=value1,key2=value2,key3=spring%20boot
所有值按字符串处理,非标准字符必须做 URL 百分号编码。
OpenTelemetry SDK 文档中其余环境变量,Spring Boot 自动配置不兼容。
如果你希望完整启用原生 OTel SDK 所有环境变量能力,需要自行构造 OpenTelemetry Bean。
⚠️ 风险:自定义
Bean会关闭Spring Boot OpenTelemetry自动配置,可能破坏内置可观测能力。
实现方式:引入 io.opentelemetry:opentelemetry-sdk-extension-autoconfigure
java
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
class AutoConfiguredOpenTelemetrySdkConfiguration {
@Bean
OpenTelemetry autoConfiguredOpenTelemetrySdk() {
return AutoConfiguredOpenTelemetrySdk.initialize().getOpenTelemetrySdk();
}
}
6.4 日志(Logging)
OpenTelemetryLoggingAutoConfiguration 负责初始化 OTel SdkLoggerProvider。OTLP 日志导出由 OtlpLoggingAutoConfiguration 提供,支持 HTTP/gRPC。
如需深度自定义 OTLP 日志导出器,可以注册 OtlpHttpLogRecordExporterBuilderCustomizer / OtlpGrpcLogRecordExporterBuilderCustomizer Bean,自定义逻辑优先级高于自动配置。
框架虽然提供 SdkLoggerProvider Bean,但默认不会自动把应用日志桥接到 OTel Logger ,需要引入第三方日志桥接组件,详见「OpenTelemetry 日志接入」章节。
6.5 指标(Metrics)
Spring 技术栈统一使用 Micrometer 采集指标,不通过 OpenTelemetry ``SdkMeterProvider 采集和导出指标,框架不会创建 SdkMeterProvider Bean。
Micrometer 指标可以借助 OtlpMeterRegistry 通过 OTLP 上报到任意兼容 OTel 的后端,参考「OTLP 指标上报」章节。
Micrometer OTLP Registry 不依赖自动配置的 Resource Bean,但 OTEL_RESOURCE_ATTRIBUTES、OTEL_SERVICE_NAME、management.opentelemetry.resource-attributes 配置依然生效。
如果业务或依赖库直接使用 OTel MeterProvider,这类指标不会自动导出。
官方强烈建议统一使用 Micrometer 采集指标。如果依赖强制使用 OTel MeterProvider,可以手动构建 SdkMeterProvider Bean,并注入到对应组件:
java
import java.time.Duration;
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import io.opentelemetry.sdk.metrics.export.MetricReader;
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
import io.opentelemetry.sdk.resources.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
class OpenTelemetryMetricsConfiguration {
@Bean
OtlpHttpMetricExporter metricExporter() {
String endpoint = "http://localhost:4318/v1/metrics";
return OtlpHttpMetricExporter.builder().setEndpoint(endpoint).build();
}
@Bean
PeriodicMetricReader metricReader(MetricExporter exporter) {
Duration interval = Duration.ofMinutes(1);
return PeriodicMetricReader.builder(exporter).setInterval(interval).build();
}
@Bean
SdkMeterProvider meterProvider(Resource resource, MetricReader metricReader) {
return SdkMeterProvider.builder().registerMetricReader(metricReader).setResource(resource).build();
}
}
该配置开启基于 HTTP 的 OTLP 原生指标导出。
6.6 链路追踪(Tracing)
当项目启用 Micrometer Tracing 时,OpenTelemetryTracingAutoConfiguration 初始化 OTel ``SdkTracerProvider;OtlpTracingAutoConfiguration 开启 OTLP 链路导出,支持 HTTP/gRPC。
官方建议:优先使用 Micrometer Observation / Micrometer Tracing API ,尽量避免直接使用原生
OpenTelemetry API。