此版本仍在开发中,尚未被视为稳定版本。如需最新稳定版本,请使用 Spring Boot 4.0.4!spring-doc.cadn.net.cn

可观测性

可观测性是指从外部观察运行系统内部状态的能力。 它由三个支柱组成:日志、度量和跟踪。spring-doc.cadn.net.cn

对于指标和追踪,Spring Boot 使用 Micrometer Observation。 要创建你自己的观测数据(这将生成指标和追踪),你可以注入一个 ObservationRegistryspring-doc.cadn.net.cn

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(() -> {
				// Execute business logic here
			});
	}

}
import io.micrometer.observation.Observation
import io.micrometer.observation.ObservationRegistry;

import org.springframework.stereotype.Component

@Component
class MyCustomObservation(private val observationRegistry: ObservationRegistry) {

	fun doSomething() {
		Observation.createNotStarted("doSomething", observationRegistry)
			.lowCardinalityKeyValue("locale", "en-US")
			.highCardinalityKeyValue("userId", "42")
			.observe {
				// Execute business logic here
			}
	}

}
低基数标签将添加到指标和追踪中,而高基数标签仅会添加到追踪中。

类型为 ObservationPredicateGlobalObservationConventionObservationFilterObservationHandler 的 Bean 将自动注册到 ObservationRegistry 上。 您还可以注册任意数量的 ObservationRegistryCustomizer Bean,以进一步配置注册表。spring-doc.cadn.net.cn

可使用一个单独的项目来配置JDBC的可观测性。 数据源Micrometer项目提供了一个Spring BootStarters,可在调用JDBC操作时自动创建观测信息。 详细了解它 在参考文档中
Spring Boot 内置了对 R2DBC 的可观测性支持。 要启用它,请将 io.r2dbc:r2dbc-proxy 依赖项添加到您的项目中。

上下文传播

可观察性支持依赖于 上下文传播库 以在不同线程和响应式管道中传递当前观察。 默认情况下,ThreadLocal 值不会在响应式操作符中自动恢复。 此行为由 spring.reactor.context-propagation 属性控制,可以设置为 auto 以启用自动传播。spring-doc.cadn.net.cn

如果您使用的是 @Async 方法或使用 AsyncTaskExecutor,则必须在执行器上注册 ContextPropagatingTaskDecorator,否则在切换线程时会丢失可观测性上下文。 这可以通过以下配置完成:spring-doc.cadn.net.cn

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();
	}

}
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
	fun contextPropagatingTaskDecorator(): ContextPropagatingTaskDecorator {
		return ContextPropagatingTaskDecorator()
	}

}

有关观察的更多详情,请参阅 Micrometer 观察文档spring-doc.cadn.net.cn

常用标签

常用的标签通常用于对运行环境进行维度钻取,例如主机、实例、区域、堆栈等。 常用的标签作为低基数标签应用于所有观测,并且可以进行配置,如下例所示:spring-doc.cadn.net.cn

management.observations.key-values.region=us-east-1
management.observations.key-values.stack=prod
management:
  observations:
    key-values:
      region: "us-east-1"
      stack: "prod"

前面的示例将 regionstack 标签分别添加到值为 us-east-1prod 的所有观测中。spring-doc.cadn.net.cn

防止观测

如果您希望阻止报告某些观测数据,可以使用 management.observations.enable 属性:spring-doc.cadn.net.cn

management.observations.enable.denied.prefix=false
management.observations.enable.another.denied.prefix=false
management:
  observations:
    enable:
      denied:
        prefix: false
      another:
        denied:
          prefix: false

前面的示例将阻止所有名称以 denied.prefixanother.denied.prefix 开头的观察。spring-doc.cadn.net.cn

如果您希望阻止 Spring Security 报告观测数据,请将属性 management.observations.enable.spring.security 设置为 false

如果您需要对防止观测进行更精细的控制,可以注册类型为 ObservationPredicate 的 Bean。 仅当所有 ObservationPredicate Bean 对该观测返回 true 时,才会报告观测结果。spring-doc.cadn.net.cn

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) {
		return !name.contains("denied");
	}

}
import io.micrometer.observation.Observation.Context
import io.micrometer.observation.ObservationPredicate
import org.springframework.stereotype.Component

@Component
class MyObservationPredicate : ObservationPredicate {

	override fun test(name: String, context: Context): Boolean {
		return !name.contains("denied")
	}

}

前面的示例将阻止所有名称包含“denied”的观察。spring-doc.cadn.net.cn

Micrometer 观测注解支持

要启用对诸如 @Observed@Timed@Counted@MeterTag@NewSpan 等可观测性注解的扫描,请将 management.observations.annotations.enabled 属性设置为 true。 还需要依赖于 org.aspectj:aspectjweaver,它是 spring-boot-starter-aspectj 的一部分。 此功能由 Micrometer 直接支持。 请参阅 MicrometerMicrometer ObservationMicrometer Tracing 参考文档。spring-doc.cadn.net.cn

当你注解已经进行仪器检测的方法或类(例如,Spring Data 仓库Spring MVC 控制器)时,你会得到重复的观测结果。 在这种情况下,你可以使用 属性 或一个 ObservationPredicate 禁用自动仪器检测,并依赖你的注解,或者你可以删除你的注解。

OpenTelemetry 支持

在您的应用程序中支持 OpenTelemetry 有多种方式。 您可以使用由 OTel 社区支持的 OpenTelemetry Java AgentOpenTelemetry Spring Boot Starter, 其指标和追踪使用 OTel 库定义的语义约定。 本文档描述了 Spring 团队官方支持的 OpenTelemetry 集成方式,使用 Micrometer 和 OTLP 导出器; 其指标和追踪使用 Spring 项目文档(例如 Spring Framework)中描述的语义约定。

Spring Boot 的 actuator 模块包含对 OpenTelemetry 的基本支持。spring-doc.cadn.net.cn

它提供了一个类型为 OpenTelemetry 的 bean,如果应用上下文中存在类型为 SdkTracerProviderContextPropagatorsSdkLoggerProviderSdkMeterProvider 的 bean,它们将自动注册。 此外,它还提供一个 Resource bean。 可以通过 management.opentelemetry.resource-attributes 配置属性来配置自动配置的 Resource 的属性。 自动配置的属性将与来自 OTEL_RESOURCE_ATTRIBUTESOTEL_SERVICE_NAME 环境变量的属性合并,其中通过配置属性设置的属性优先于来自环境变量的属性。spring-doc.cadn.net.cn

如果您定义了自己的 Resource bean,情况将不再如此。spring-doc.cadn.net.cn

Spring Boot 不会自动导出 OpenTelemetry 指标或日志。 当与 Micrometer Tracing 一起使用时,才会自动配置 OpenTelemetry 跟踪的导出。

环境变量

Spring Boot 支持以下环境变量来配置 OpenTelemetry 资源:spring-doc.cadn.net.cn

OTEL_RESOURCE_ATTRIBUTES 环境变量由一系列键值对组成。 例如:key1=value1,key2=value2,key3=spring%20boot。 所有属性值均被视为字符串,且任何不在 baggage-octet 范围内的字符都必须进行百分号编码

Micrometer 还支持以下环境变量,用于通过 OTLP 配置指标导出:spring-doc.cadn.net.cn

其他环境变量如OpenTelemetry 文档中所述不受支持。spring-doc.cadn.net.cn

如果要使OpenTelemetry SDK指定的所有环境变量生效,您必须提供自己的 OpenTelemetry bean。spring-doc.cadn.net.cn

这样做会关闭 Spring Boot 的 OpenTelemetry 自动配置,可能会破坏内置的可观察性功能。

首先,添加对 io.opentelemetry:opentelemetry-sdk-extension-autoconfigure 的依赖以获取 OpenTelemetry 的零代码 SDK 自动配置模块,然后添加此配置:spring-doc.cadn.net.cn

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();
	}

}

日志

OpenTelemetryLoggingAutoConfiguration 配置了 OpenTelemetry 的 SdkLoggerProvider。 通过 OtlpLoggingAutoConfiguration 可以通过 OTLP 导出日志,该功能支持通过 HTTP 或 gRPC 导出 OTLP 日志。spring-doc.cadn.net.cn

然而,虽然存在一个 SdkLoggerProvider bean,Spring Boot 不会开箱即用地将日志桥接到这个 bean。 这可以通过第三方日志桥接器完成,如 使用 OpenTelemetry 记录日志 部分所述。spring-doc.cadn.net.cn

指标

Spring产品组合中选择的度量标准是Micrometer,这意味着通过OpenTelemetry的SdkMeterProvider不会收集和导出度量标准。 Spring Boot不提供SdkMeterProvider bean。spring-doc.cadn.net.cn

但是,可以通过OTLP将Micrometer指标导出到任何支持OpenTelemetry的后端,如OtlpMeterRegistry所述,详见使用OTLP的指标部分。spring-doc.cadn.net.cn

Micrometer 的 OTLP 注册表不使用 Resource Bean,但设置 OTEL_RESOURCE_ATTRIBUTESOTEL_SERVICE_NAMEmanagement.opentelemetry.resource-attributes 有效。

通过 OpenTelemetry API 和 SDK 的指标

如果你或你包含的依赖项使用了 OpenTelemetry 的 MeterProvider,这些指标将不会被导出。spring-doc.cadn.net.cn

我们强烈建议您使用 Micrometer 报告您的指标。 如果您包含的依赖项使用了 OpenTelemetry 的 MeterProvider,则可以将此配置包含在您的应用程序中,以配置一个 MeterProvider bean,然后必须将其连接到您的依赖项中:spring-doc.cadn.net.cn

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 方式启用指标导出。spring-doc.cadn.net.cn

跟踪

如果使用 Micrometer 跟踪,OpenTelemetryTracingAutoConfiguration 配置 OpenTelemetry 的 SdkTracerProvider。 通过 OTLP 导出跟踪由 OtlpTracingAutoConfiguration 启用,它支持通过 HTTP 或 gRPC 的 OTLP 导出跟踪。spring-doc.cadn.net.cn

我们强烈建议使用 Micrometer Observation 或 Tracing API,而不是直接使用 OpenTelemetry API。spring-doc.cadn.net.cn