このバージョンはまだ開発中であり、まだ安定しているとは見なされていません。最新の安定バージョンについては、Spring Boot 4.1.1 を使用してください!

トレース

Spring Boot Actuator は、一般的なトレーサーライブラリのファサードである Micrometer Tracing (英語) の依存関係管理と自動構成を提供します。

Micrometer Tracing の機能の詳細については、リファレンスドキュメント (英語) を参照してください。

サポートされているトレーサー

Spring Boot には、次のトレーサーの自動構成が同梱されています。

入門

トレースを始めるには、サンプルアプリケーションが必要です。今回の目的には、初めての Spring Boot アプリケーションの開発セクションで紹介されているシンプルな "Hello World!" Web アプリケーションで十分です。Brave トレーサーを使用し、トレースバックエンドには Zipkin を使用します。

要約すると、メインのアプリケーションコードは次のようになります。

  • Java

  • Kotlin

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class MyApplication {

	private static final Log logger = LogFactory.getLog(MyApplication.class);

	@RequestMapping("/")
	String home() {
		logger.info("home() has been called");
		return "Hello World!";
	}

	public static void main(String[] args) {
		SpringApplication.run(MyApplication.class, args);
	}

}
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@SpringBootApplication
class MyApplication {

	private val logger: Log = LogFactory.getLog(MyApplication::class.java)

	@RequestMapping("/")
	fun home(): String {
		logger.info("home() has been called")
		return "Hello, World!"
	}

}

fun main(args: Array<String>) {
	runApplication<MyApplication>(*args)
}
home() メソッドには logger ステートメントが追加されていますが、これは後で重要になります。

ここで、org.springframework.boot:spring-boot-starter-zipkin 依存関係を追加する必要があります。

次に、次のアプリケーションプロパティを追加します。

  • プロパティ

  • YAML

management.tracing.sampling.probability=1
management:
  tracing:
    sampling:
      probability: 1.0

デフォルトでは、Spring Boot はリクエストの 10% のみをサンプリングして、トレースバックエンドがオーバーロードになるのを防ぎます。このプロパティは、すべてのリクエストがトレースバックエンドに送信されるように、100% に切り替えます。

トレースを収集して視覚化するには、実行中のトレースバックエンドが必要です。ここではトレースバックエンドとして Zipkin を使用します。Zipkin クイックスタートガイド (英語) は、Zipkin をローカルで開始する方法を説明します。

Zipkin が実行されたら、アプリケーションを開始できます。

Web ブラウザーを localhost:8080 で開くと、次の出力が表示されるはずです。

Hello World!

バックグラウンドでは、HTTP リクエストの観測が作成され、それが Brave にブリッジされ、Zipkin に新しいトレースが報告されます。

次に、localhost:9411 で Zipkin UI を開き、クエリの実行 ボタンを押して、収集されたすべてのトレースを一覧表示します。トレースが 1 つ表示されるはずです。「表示」ボタンを押すと、そのトレースの詳細が表示されます。

相関 ID のログ記録

相関 ID は、ログファイル内の行をスパン / トレースにリンクさせるのに役立ちます。Micrometer Tracing を使用している場合、Spring Boot ではデフォルトでログに相関 ID が含まれます。

デフォルトの相関 ID は、traceId と spanId の MDC (英語) 値から構築されます。例: Micrometer Tracing が 803B448A0489F84084905D3093480352 の MDC traceId と 3425F23BB2432450 の MDC spanId を追加した場合、ログ出力には相関 ID [803B448A0489F84084905D3093480352-3425F23BB2432450] が含まれます。

相関 ID に別の形式を使用したい場合は、logging.pattern.correlation プロパティを使用して相関 ID を定義できます。例: 以下は、以前に Spring Cloud Sleuth で使用されていた形式で Logback の相関 ID を提供します。

  • プロパティ

  • YAML

logging.pattern.correlation=[${spring.application.name:},%X{traceId:-},%X{spanId:-}] 
logging.include-application-name=false
logging:
  pattern:
    correlation: "[${spring.application.name:},%X{traceId:-},%X{spanId:-}] "
  include-application-name: false
上の例では、ログメッセージ内でアプリケーション名が重複するのを避けるために、logging.include-application-name が false に設定されています (logging.pattern.correlation にはすでにアプリケーション名が含まれています)。logging.pattern.correlation には、デフォルトで直後に来るロガー名と区別されるように、末尾にスペースが含まれていることにもメンションする価値があります。
相関 ID はコンテキストの伝播に依存します。詳細については、このドキュメントを参照してください。

トレースの伝播

ネットワーク上でトレースを自動的に伝播するには、自動構成された RestClient.Builder または WebClient.Builder を使用してクライアントを構築します。

自動構成ビルダーを使用せずに RestClient (Javadoc) または WebClient (Javadoc) を作成すると、自動トレース伝播は機能しません。

トレーサーの実装

Micrometer Tracer は複数のトレーサー実装をサポートしているため、Spring Boot との依存関係は複数可能です。OpenTelemetry と OTLP、Brave と Zipkin の組み合わせは一般的であり、専用のスターターが用意されています。

OpenTelemetry と OTLP

OpenTelemetry を使用したトレースと OTLP を使用したレポートには、次の依存関係が必要です。

  • org.springframework.boot:spring-boot-starter-opentelemetry

management.opentelemetry.tracing.export.otlp.* 構成プロパティを使用して、OTLP を使用したレポートを構成します。

OTLP スパンエクスポーターに高度なカスタマイズを適用する必要がある場合は、OtlpHttpSpanExporterBuilderCustomizer (Javadoc) または OtlpGrpcSpanExporterBuilderCustomizer (Javadoc) Bean の登録を検討してください。これらは、OtlpHttpSpanExporter または OtlpGrpcSpanExporter の作成前に呼び出されます。カスタマイザーは、自動構成によって適用されるものよりも優先されます。

OpenZipkin Brave と Zipkin

OpenZipkin Brave を使用したトレースと Zipkin へのレポートには、次の依存関係が必要です。

  • org.springframework.boot:spring-boot-starter-zipkin

management.tracing.export.zipkin.* 構成プロパティを使用して、Zipkin へのレポートを構成します。

サンプリング

デフォルトでは、Spring Boot はトレースバックエンドの負荷を軽減するため、リクエストの 10% のみをサンプリングします。これは management.tracing.sampling.probability プロパティで設定できます。

OpenTelemetry を使用する場合、management.opentelemetry.tracing.sampler プロパティを介して使用するサンプラーを設定することもできます。サポートされているサンプラーは以下のとおりです。

サンプラー 説明

always-on

あらゆる痕跡を採取します。

always-off

あらゆる痕跡を消し去る。

trace-id-ratio

management.tracing.sampling.probability に基づいてトレースの一部をサンプリングします。

parent-based-always-on

親スパンがサンプリングされている場合は、子スパンをサンプリングします。親スパンが存在しない場合は、すべてのトレースをサンプリングします。

parent-based-always-off

親スパンがサンプリングされている場合は、子スパンをサンプリングします。親スパンが存在しない場合は、すべてのトレースを破棄します。

parent-based-trace-id-ratio (default)

親スパンがサンプリングされている場合は、子スパンをサンプリングします。親がない場合は、management.tracing.sampling.probability に基づいてトレースの一部をサンプリングします。

スパン制限

OpenTelemetry を使用する場合、management.opentelemetry.tracing.limits.* の設定プロパティを介してスパン制限を設定できます。これにより、スパンあたりの属性、イベント、リンクの最大数、文字列属性値の最大長を制御できます。

例: スパンあたりの属性数を 64 に制限し、属性値の最大長を 256 文字に制限します。

  • プロパティ

  • YAML

management.opentelemetry.tracing.limits.max-attributes=64
management.opentelemetry.tracing.limits.max-attribute-value-length=256
management:
  opentelemetry:
    tracing:
      limits:
        max-attributes: 64
        max-attribute-value-length: 256

完全な制御が必要な場合は、カスタム SpanLimits (英語) Bean を登録できます。

Micrometer Observation との統合

TracingAwareMeterObservationHandler (英語) ObservationRegistry (英語) に自動的に登録され、完了した観測ごとにスパンが作成されます。

カスタムスパンの作成

観測を開始することで、独自のスパンを作成できます。そのためには、コンポーネントに ObservationRegistry (英語) を挿入します。

  • Java

  • Kotlin

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

import org.springframework.stereotype.Component;

@Component
class CustomObservation {

	private final ObservationRegistry observationRegistry;

	CustomObservation(ObservationRegistry observationRegistry) {
		this.observationRegistry = observationRegistry;
	}

	void someOperation() {
		Observation observation = Observation.createNotStarted("some-operation", this.observationRegistry);
		observation.lowCardinalityKeyValue("some-tag", "some-value");
		observation.observe(() -> {
			// Business logic ...
		});
	}

}
import io.micrometer.observation.Observation
import io.micrometer.observation.ObservationRegistry
import org.springframework.stereotype.Component

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

	fun someOperation() {
		Observation.createNotStarted("some-operation", observationRegistry)
			.lowCardinalityKeyValue("some-tag", "some-value")
			.observe {
				// Business logic ...
			}
	}

}

これにより、タグ "some-tag=some-value" を持つ "some-operation" という名前の観測が作成されます。

メトリクスを作成せずにスパンを作成する場合は、Micrometer の下位レベルの Tracer API (英語) を使用する必要があります。

バゲッジ

Tracer (英語) API を使用してバゲッジを作成できます。

  • Java

  • Kotlin

import io.micrometer.tracing.BaggageInScope;
import io.micrometer.tracing.Tracer;

import org.springframework.stereotype.Component;

@Component
class CreatingBaggage {

	private final Tracer tracer;

	CreatingBaggage(Tracer tracer) {
		this.tracer = tracer;
	}

	void doSomething() {
		try (BaggageInScope scope = this.tracer.createBaggageInScope("baggage1", "value1")) {
			// Business logic
		}
	}

}
import io.micrometer.tracing.Tracer
import org.springframework.stereotype.Component

@Component
class CreatingBaggage(private val tracer: Tracer) {

	fun doSomething() {
		tracer.createBaggageInScope("baggage1", "value1").use {
			// Business logic
		}
	}

}

この例では、値 value1 を持つ baggage1 という名前のバゲッジを作成します。W3C 伝播を使用している場合、バゲッジはネットワーク上で自動的に伝播されます。B3 伝播を使用している場合、バゲッジは自動的には伝播されません。ネットワーク上でバゲージを手動で伝播するには、management.tracing.baggage.remote-fields 構成プロパティを使用します (これは W3C にも機能します)。上の例では、このプロパティを baggage1 に設定すると、HTTP ヘッダー baggage1: value1 が生成されます。

バゲージを MDC に伝播する場合は、management.tracing.baggage.correlation.fields 構成プロパティを使用します。上の例では、このプロパティを baggage1 に設定すると、baggage1 という名前の MDC エントリが作成されます。

テスト

@SpringBootTest (Javadoc) を使用する場合、データをレポートしているトレースコンポーネントは自動的に構成されません。詳細については、トレースの使用を参照してください。