可观测性

可观测性是指能够从外部观察运行中系统的内部状态。它由三个支柱组成:日志、指标和追踪。

对于指标和追踪,Spring Boot 使用 Micrometer Observation。要创建自己的观测(这将生成指标和追踪),可以注入一个 ObservationRegistry

  • Java

  • Kotlin

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 来进一步配置注册表。

JDBC 的可观测性可以通过一个独立的项目进行配置。Datasource Micrometer 项目提供了一个 Spring Boot starter,它在调用 JDBC 操作时自动创建观测。在参考文档中阅读更多信息。
R2DBC 的可观测性内置于 Spring Boot 中。要启用它,请将 io.r2dbc:r2dbc-proxy 依赖项添加到您的项目中。

上下文传播

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

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

  • Java

  • Kotlin

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 Observation 文档

通用标签

通用标签通常用于操作环境的维度下钻,例如主机、实例、区域、堆栈等。通用标签作为低基数标签应用于所有观测,并且可以配置,如以下示例所示

  • 属性

  • YAML

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

阻止观测

如果您想阻止报告某些观测,可以使用 management.observations.enable 属性

  • 属性

  • YAML

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 Security 报告观测,请将属性 management.observations.enable.spring.security 设置为 false

如果您需要对阻止观测进行更精细的控制,可以注册类型为 ObservationPredicate 的 Bean。只有当所有 ObservationPredicate Bean 都对该观测返回 true 时,才会报告观测。

  • Java

  • Kotlin

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”的观测。

Micrometer Observation 注解支持

要启用对可观测性注解(如 @Observed@Timed@Counted@MeterTag@NewSpan)的扫描,您需要将 management.observations.annotations.enabled 属性设置为 true。此功能由 Micrometer 直接支持。请参阅 MicrometerMicrometer ObservationMicrometer Tracing 参考文档。

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

OpenTelemetry 支持

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

Spring Boot 的 actuator 模块包含对 OpenTelemetry 的基本支持。

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

如果您定义了自己的 Resource Bean,则情况将不再如此。

Spring Boot 不提供 OpenTelemetry 指标或日志的自动导出。OpenTelemetry 追踪的导出仅在与 Micrometer Tracing 一起使用时才自动配置。

环境变量

Spring Boot 支持以下环境变量来配置 OpenTelemetry 资源

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

Micrometer 还支持以下环境变量来配置通过 OTLP 进行的指标导出

OpenTelemetry 文档中描述的其他环境变量不受支持。

如果您希望 OpenTelemetry SDK 指定的所有环境变量都生效,则必须提供自己的 OpenTelemetry Bean。

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

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

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。通过 OTLP 导出日志通过 OtlpLoggingAutoConfiguration 支持,该配置通过 HTTP 或 gRPC 启用 OTLP 日志导出。

然而,虽然存在 SdkLoggerProvider Bean,但 Spring Boot 默认不支持将日志桥接到此 Bean。这可以通过第三方日志桥接器完成,如 使用 OpenTelemetry 记录日志 部分所述。

指标

Spring 产品组合中的指标选择是 Micrometer,这意味着指标不会通过 OpenTelemetry 的 SdkMeterProvider 收集和导出。Spring Boot 不提供 SdkMeterProvider Bean。

但是,Micrometer 指标可以通过 OTLP 导出到任何支持 OpenTelemetry 的后端,使用 OtlpMeterRegistry,如 使用 OTLP 的指标 部分所述。

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

通过 OpenTelemetry API 和 SDK 的指标

如果您或您包含的依赖项使用 OpenTelemetry 的 MeterProvider,这些指标将不会导出。

我们强烈建议您使用 Micrometer 报告您的指标。如果您包含的依赖项使用 OpenTelemetry 的 MeterProvider,您可以在应用程序中包含此配置以配置 MeterProvider Bean,然后您必须将其连接到您的依赖项中

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 = "https://: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 指标。

追踪

如果使用 Micrometer 追踪,OpenTelemetryTracingAutoConfiguration 配置 OpenTelemetry 的 SdkTracerProvider。通过 OTLP 导出追踪由 OtlpTracingAutoConfiguration 启用,该配置支持通过 HTTP 或 gRPC 导出 OTLP 追踪。

我们强烈建议使用 Micrometer Observation 或 Tracing API,而不是直接使用 OpenTelemetry API。

© . This site is unofficial and not affiliated with VMware.