Micrometer 系列【59】统一观测:Spring Boot 集成指南

文章目录

  • [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)仅会出现在链路追踪中。

类型为 ObservationPredicateGlobalObservationConventionObservationFilterObservationHandlerBean 会自动注册到 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-1stack=prod

4. 禁用观测采集

如果你需要阻止部分观测上报,可以使用 management.observations.enable.* 配置:

yaml 复制代码
management.observations.enable.denied.prefix=false
management.observations.enable.another.denied.prefix=false

以上配置会禁止名称以 denied.prefixanother.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 原生提供,详情参考 MicrometerMicrometer ObservationMicrometer Tracing 文档。

⚠️ 注意:如果给已经内置埋点的类/方法添加注解(例如 Spring Data RepositorySpring MVC Controller),会产生重复观测

解决方案二选一:

  1. 通过配置或 ObservationPredicate 关闭自动埋点,只使用自定义注解;
  2. 删除自定义注解,使用框架内置观测。

6. OpenTelemetry 支持

6.1 自动配置

应用接入 OpenTelemetry 存在多种方式:可以使用 OpenTelemetry Java Agent,或是社区维护的 OpenTelemetry Spring Boot Starter;指标与链路遵循 OTel 规范语义约定。

本文档描述 Spring 官方支持的 OpenTelemetry 集成方案:基于 Micrometer + OTLP Exporter;指标与链路语义规范遵循 Spring 系列项目文档定义。

Spring Boot Actuator 模块内置基础 OpenTelemetry 支持:

  • 框架自动提供 OpenTelemetry Bean
  • 如果上下文中存在 SdkTracerProviderContextPropagatorsSdkLoggerProviderSdkMeterProvider,会自动注册。
  • 自动创建 Resource Bean ,自动配置的 Resource 属性可通过 management.opentelemetry.resource-attributes 指定。配置中的属性会和环境变量 OTEL_RESOURCE_ATTRIBUTESOTEL_SERVICE_NAME 合并,配置文件优先级高于环境变量

如果你自行定义了 Resource Bean,则上述自动合并逻辑不再生效。

Spring Boot 不会自动导出 OpenTelemetry 原生指标与日志 ;只有搭配 Micrometer Tracing 使用时,链路追踪导出才会自动配置。

6.2 关闭 OpenTelemetry

配置 management.opentelemetry.enabled=false 关闭 OpenTelemetry 支持。

行为类似环境变量 OTEL_SDK_DISABLED(逻辑取反):SDK 关闭后,指标、链路、日志使用空实现;上下文传播器不受影响,正常工作

重要提醒:Spring Boot 本身不使用 OpenTelemetry 原生指标能力,因此即使关闭 OpenTelemetryMicrometer 指标依然可能正常采集。

6.3 环境变量映射

Spring Boot 支持一部分 OpenTelemetry SDK 环境变量,启动时自动映射为 Spring Boot 配置项。

当同时存在「信号专属变量」(例如 OTEL_EXPORTER_OTLP_TRACES_ENDPOINT)和通用变量(OTEL_EXPORTER_OTLP_ENDPOINT)时,信号专属变量优先 。通用变量作为兜底时,框架自动追加路径后缀:v1/tracesv1/metricsv1/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_ATTRIBUTES
  • OTEL_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 SdkLoggerProviderOTLP 日志导出由 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_ATTRIBUTESOTEL_SERVICE_NAMEmanagement.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();
	}

}

该配置开启基于 HTTPOTLP 原生指标导出。

6.6 链路追踪(Tracing)

当项目启用 Micrometer Tracing 时,OpenTelemetryTracingAutoConfiguration 初始化 OTel ``SdkTracerProviderOtlpTracingAutoConfiguration 开启 OTLP 链路导出,支持 HTTP/gRPC

官方建议:优先使用 Micrometer Observation / Micrometer Tracing API ,尽量避免直接使用原生 OpenTelemetry API


相关推荐
阿里云云原生15 小时前
智能体构建与进化——Agent 开源开发者沙龙·广州站精彩回顾 & PPT 下载
云原生·agent
阿里云云原生16 小时前
阿里云联合 Datadog,补齐 Go 可观测性最后短板
云原生·go
qq_4523962316 小时前
第十二篇:《Istio 生产环境最佳实践与排错指南》
云原生·php·istio
山荷枝19 小时前
04-框架--SpringBoot
java·spring boot·后端
Henry-SAP20 小时前
SAP MRP类型如何影响计划订单生成
人工智能·云原生·sap·erp
用户3126874877201 天前
你的配置真的绑定上了吗?Spring Boot @ConfigurationProperties 全链路拆解
spring boot
2601_963870221 天前
【计算机毕业设计】基于Spring Boot+Vue的高考志愿填报系统的设计与实现
spring boot·课程设计·高考
andongni2031 天前
SpringBoot 入门实验报告
java·spring boot·后端
云烟成雨TD1 天前
Micrometer 系列【52】统一观测:Observation | 观测载体
云原生·链路追踪·micrometer