可觀測性

可觀測性是指能夠從外部觀察執行中系統的內部狀態。它由三個支柱組成:日誌、指標和追蹤。

對於指標和追蹤,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.