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-stoppedGrafana LGTMオールインワンコンテナを起動するには、次のコマンドを実行します。
docker compose up -dDocker 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:4317Grafana UIへのアクセス
実行されると、Grafana UIはhttp://localhost:3000/で利用可能になります。
- Grafana UIをhttp://localhost:3000/で開きます。
- 以下のデフォルトの認証情報でログインします。
- ユーザー:
admin - パスワード:
admin
- ユーザー:
- 左側のナビゲーションメニューで、ドリルダウン → トレースに移動します。
トレースビューでは、次のことができます。 - レート、エラー、または期間のメトリクスを選択します。
- サービス名やスパン名などでスパンフィルターを適用して、データを絞り込みます。
- トレースを表示し、詳細を検査し、スパンのタイムラインを操作します。
