KtorサーバーでのOpenTelemetryによる分散トレース
必要な依存関係: io.opentelemetry.instrumentation:opentelemetry-ktor-3.0
コード例: opentelemetry
KtorはOpenTelemetryと統合されています。OpenTelemetryは、トレース、メトリクス、ログなどのテレメトリーデータを収集するためのオープンソースの可観測性フレームワークです。アプリケーションを計測し、データをGrafanaやJaegerなどの監視および可観測性ツールにエクスポートするための標準的な方法を提供します。
KtorServerTelemetry
プラグインは、Ktorサーバーアプリケーションにおける受信HTTPリクエストの分散トレースを可能にします。このプラグインは、ルート、HTTPメソッド、ステータスコード情報を含むspansを自動的に作成し、受信リクエストヘッダーから既存のトレースコンテキストを抽出し、スパン名、属性、スパンの種類をカスタマイズできるようにします。
クライアント側では、OpenTelemetryはKtorClientTelemetryプラグインを提供しており、これは外部サービスへの送信HTTP呼び出しのトレースを収集します。
依存関係の追加
KtorServerTelemetry
を使用するには、ビルドスクリプトにopentelemetry-ktor-3.0
アーティファクトを含める必要があります。
OpenTelemetryの構成
KtorアプリケーションにKtorServerTelemetry
プラグインをインストールする前に、OpenTelemetry
インスタンスを構成および初期化する必要があります。このインスタンスは、トレースやメトリクスを含むテレメトリーデータの管理を担当します。
自動構成
OpenTelemetryを構成する一般的な方法は、AutoConfiguredOpenTelemetrySdk
を使用することです。これにより、システムプロパティと環境変数に基づいてエクスポーターとリソースが自動的に構成され、セットアップが簡素化されます。
自動検出された構成は、例えばservice.name
リソース属性を追加するなどして、引き続きカスタマイズできます。
package com.example
import io.opentelemetry.api.OpenTelemetry
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk
import io.opentelemetry.semconv.ServiceAttributes
fun getOpenTelemetry(serviceName: String): OpenTelemetry {
return AutoConfiguredOpenTelemetrySdk.builder().addResourceCustomizer { oldResource, _ ->
oldResource.toBuilder()
.putAll(oldResource.attributes)
.put(ServiceAttributes.SERVICE_NAME, serviceName)
.build()
}.build().openTelemetrySdk
}
プログラムによる構成
環境ベースの構成に依存する代わりに、コードでエクスポーター、プロセッサー、およびプロパゲーターを定義するには、OpenTelemetrySdk
を使用できます。
次の例は、OTLPエクスポーター、スパンプロセッサー、およびトレースコンテキストプロパゲーターを使用してOpenTelemetryをプログラムで構成する方法を示しています。
import io.opentelemetry.api.OpenTelemetry
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator
import io.opentelemetry.context.propagation.ContextPropagators
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter
import io.opentelemetry.sdk.OpenTelemetrySdk
import io.opentelemetry.sdk.trace.SdkTracerProvider
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor
fun configureOpenTelemetry(): OpenTelemetry {
val spanExporter = OtlpGrpcSpanExporter.builder()
.setEndpoint("http://localhost:4317")
.build()
val tracerProvider = SdkTracerProvider.builder()
.addSpanProcessor(BatchSpanProcessor.builder(spanExporter).build())
.build()
return OpenTelemetrySdk.builder()
.setTracerProvider(tracerProvider)
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
.buildAndRegisterGlobal()
}
このアプローチは、テレメトリーのセットアップを完全に制御する必要がある場合、またはデプロイ環境が自動構成に依存できない場合に使用します。
詳細については、OpenTelemetry SDKコンポーネントのドキュメントを参照してください。
KtorServerTelemetryのインストール
アプリケーションにKtorServerTelemetry
プラグインをインストールするには、指定されたモジュールのinstall
関数に渡し、構成済みのOpenTelemetry
インスタンスを設定します。
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.application.*
import io.opentelemetry.instrumentation.*
fun main() {
embeddedServer(Netty, port = 8080) {
val openTelemetry = getOpenTelemetry(serviceName = "opentelemetry-ktor-sample-server")
install(KtorServerTelemetry){
setOpenTelemetry(openTelemetry)
}
// ...
}.start(wait = true)
}
import io.ktor.server.application.*
import io.opentelemetry.instrumentation.*
// ...
fun Application.module() {
val openTelemetry = getOpenTelemetry(serviceName = "opentelemetry-ktor-sample-server")
install(KtorServerTelemetry){
setOpenTelemetry(openTelemetry)
}
// ...
}
KtorServerTelemetry
は、他のロギングまたはテレメトリー関連のプラグインよりも前にインストールされていることを確認してください。
トレースの構成
KtorサーバーがOpenTelemetryスパンを記録およびエクスポートする方法をカスタマイズできます。以下のオプションを使用すると、どのリクエストがトレースされるか、スパンがどのように命名されるか、含まれる属性、およびスパンの種類の決定方法を調整できます。
これらの概念の詳細については、OpenTelemetryトレースドキュメントを参照してください。
追加のHTTPメソッドをトレースする
デフォルトでは、このプラグインは標準のHTTPメソッド(GET
、POST
、PUT
など)をトレースします。追加またはカスタムのメソッドをトレースするには、knownMethods
プロパティを構成します。
install(KtorServerTelemetry) {
// ...
knownMethods(HttpMethod.DefaultMethods + CUSTOM_METHOD)
}
ヘッダーをキャプチャする
特定のリクエストヘッダーをスパン属性として含めるには、capturedRequestHeaders
プロパティを使用します。
install(KtorServerTelemetry) {
// ...
capturedRequestHeaders(HttpHeaders.UserAgent)
}
スパンの種類の選択
リクエストの特性に基づいてスパンの種類(SERVER
、CLIENT
、PRODUCER
、CONSUMER
など)をオーバーライドするには、spanKindExtractor
プロパティを使用します。
install(KtorServerTelemetry) {
// ...
spanKindExtractor {
if (httpMethod == HttpMethod.Post) {
SpanKind.PRODUCER
} else {
SpanKind.CLIENT
}
}
}
カスタム属性の追加
スパンの開始時または終了時にカスタム属性をアタッチするには、attributesExtractor
プロパティを使用します。
install(KtorServerTelemetry) {
// ...
attributesExtractor {
onStart {
attributes.put("start-time", System.currentTimeMillis())
}
onEnd {
attributes.put("end-time", Instant.now().toEpochMilli())
}
}
}
その他のプロパティ
アプリケーション全体のトレース動作を細かく調整するために、プロパゲーター、属性制限、計測の有効化/無効化など、追加のOpenTelemetryプロパティも構成できます。詳細については、OpenTelemetry Java構成ガイドを参照してください。
Grafana LGTMでテレメトリーデータを検証する
テレメトリーデータを視覚化および検証するために、トレース、メトリクス、ログをGrafanaなどの分散トレースバックエンドにエクスポートできます。grafana/otel-lgtm
オールインワンイメージには、Grafana、Tempo(トレース)、Loki(ログ)、およびMimir(メトリクス)がバンドルされています。
Docker Composeの使用
以下の内容でdocker-compose.ymlファイルを作成します。
services:
grafana-lgtm:
image: grafana/otel-lgtm:latest
ports:
- "4317:4317" # OTLP gRPC receiver (traces, metrics, logs)
- "4318:4318" # OTLP HTTP receiver
- "3000:3000" # Grafana UI
environment:
- GF_SECURITY_ADMIN_USER=admin
- GF_SECURITY_ADMIN_PASSWORD=admin
restart: unless-stopped
Grafana LGTMオールインワンコンテナを起動するには、次のコマンドを実行します。
docker compose up -d
Docker CLIの使用
あるいは、Dockerコマンドラインを使用してGrafanaを直接実行することもできます。
docker run -d --name grafana_lgtm \
-p 4317:4317 \ # OTLP gRPC receiver (traces, metrics, logs)
-p 4318:4318 \ # OTLP HTTP receiver
-p 3000:3000 \ # Grafana UI
-e GF_SECURITY_ADMIN_USER=admin \
-e GF_SECURITY_ADMIN_PASSWORD=admin \
grafana/otel-lgtm:latest
アプリケーションエクスポート構成
KtorアプリケーションからOTLPエンドポイントにテレメトリーを送信するには、OpenTelemetry SDKがgRPCプロトコルを使用するように構成します。これらの値は、SDKをビルドする前に環境変数で設定できます。
export OTEL_TRACES_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
または、JVMフラグを使用します。
-Dotel.traces.exporter=otlp -Dotel.exporter.otlp.protocol=grpc -Dotel.exporter.otlp.endpoint=http://localhost:4317
Grafana UIへのアクセス
実行されると、Grafana UIはhttp://localhost:3000/で利用可能になります。
- Grafana UIをhttp://localhost:3000/で開きます。
- 以下のデフォルトの認証情報でログインします。
- ユーザー:
admin
- パスワード:
admin
- ユーザー:
- 左側のナビゲーションメニューで、ドリルダウン → トレースに移動します。
トレースビューでは、次のことができます。
- レート、エラー、または期間のメトリクスを選択します。
- サービス名やスパン名などでスパンフィルターを適用して、データを絞り込みます。
- トレースを表示し、詳細を検査し、スパンのタイムラインを操作します。