Ktor Server における OpenTelemetry を使用した分散トレーシング
必要な依存関係: io.opentelemetry.instrumentation:opentelemetry-ktor-3.0
コード例: opentelemetry
Ktor は OpenTelemetry と統合されています。OpenTelemetry は、トレース、メトリクス、ログなどのテレメトリデータを収集するためのオープンソースのオブザーバビリティフレームワークです。アプリケーションを計装し、Grafana や Jaeger などのモニタリングおよびオブザーバビリティツールにデータをエクスポートするための標準的な方法を提供します。
KtorServerTelemetry プラグインは、Ktor サーバーアプリケーションにおける受信 HTTP リクエストの分散トレーシングを有効にします。ルート、HTTP メソッド、ステータスコード情報を含むスパンを自動的に作成し、受信リクエストヘッダーから既存のトレースコンテキストを抽出します。また、スパン名、属性、スパンの種類のカスタマイズも可能です。
クライアント側では、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)
}ヘッダーのキャプチャ
特定の HTTP リクエストヘッダーをスパン属性として含めるには、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 受信機 (トレース、メトリクス、ログ)
- "4318:4318" # OTLP HTTP 受信機
- "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 受信機 (トレース、メトリクス、ログ)
-p 4318:4318 \ # OTLP HTTP 受信機
-p 3000:3000 \ # Grafana UI
-e GF_SECURITY_ADMIN_USER=admin \
-e GF_SECURITY_ADMIN_PASSWORD=admin \
grafana/otel-lgtm:latestアプリケーションのエクスポート設定
Ktor アプリケーションから OTLP エンドポイントにテレメトリを送信するには、gRPC プロトコルを使用するように OpenTelemetry SDK を設定します。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
- ユーザー:
- 左側のナビゲーションメニューで、Drilldown → Traces に移動します。
Traces ビューでは、以下のことができます: - Rate(レート)、Errors(エラー)、または Duration(期間)のメトリクスを選択する。
- スパンフィルター(サービス名やスパン名など)を適用してデータを絞り込む。
- トレースを表示し、詳細を調査し、スパンのタイムラインを操作する。
