コンテンツにスキップ

OpenTelemetry Rust SDK

このドキュメントでは SDK インストルメンテーションを採用しています。アプリケーションコード内で SDK を初期化し、Span を作成して Exporter を構成し、DataKit 経由でトレースを Guance に送信します。これはゼロコードインジェクションではありません。依存関係をインストールしたり環境変数を設定したりしても、すべてのフレームワーク呼び出しが自動的に収集されるわけではありません。このドキュメントでは Trace のみを有効にし、Kubernetes には対応しません。

Rust + OpenTelemetry SDK -> OTLP/HTTP -> DataKit -> Guance

前提条件

  • Rust の stable ツールチェーンと Cargo をインストールしてください。以下では OpenTelemetry 0.31.0 を固定して使用します。現在の安定ツールチェーンを使用し、Cargo.lock をアプリケーションのバージョン管理に含めることを推奨します。
  • サンプルは同期 main、ブロッキング HTTP クライアント、バックグラウンドのバッチエクスポートスレッドを使用しているため、Tokio は不要です。
  • DataKit がインストール済みで、対象ワークスペースのインストールコマンドを使用してデータ送信先とトークンを設定していることを前提とします。アプリケーションは DataKit の HTTP ポート 9529 にアクセスできる必要があります。

一、OpenTelemetry コレクターを有効にする

DataKit ホストで設定ディレクトリに移動します。設定ファイルが存在しない場合のみサンプルをコピーし、既存ファイルがある場合は直接調整してください:

cd /usr/local/datakit/conf.d/opentelemetry
sudo cp -n opentelemetry.conf.sample opentelemetry.conf

opentelemetry.conf に以下の設定が含まれていることを確認してください。カスタムタグは customer_tags で保持されます:

[[inputs.opentelemetry]]
  customer_tags = ["team", "app.operation"]

  [inputs.opentelemetry.http]
    http_status_ok = 200
    trace_api = "/otel/v1/traces"
    metric_api = "/otel/v1/metrics"
    logs_api = "/otel/v1/logs"

同一ホストからの接続には 127.0.0.1:9529 を使用します。別ホストから接続する場合は、DataKit のメイン設定 datakit.conf[http_api].listen でアプリケーションがアクセスできるリッスンアドレスを設定し、ネットワークアクセス範囲を制限してください。HTTP リッスンアドレスはコレクターの設定ファイルでは設定しません。

DataKit を再起動して確認します:

sudo datakit service restart
curl http://127.0.0.1:9529/v1/ping

/v1/ping は HTTP サービスへの到達可能性のみを確認するもので、トレースが取り込まれたことを示すものではありません。詳細は OpenTelemetry コレクター を参照してください。DataKit がワークスペースの認証を担当するため、サンプルアプリケーションでワークスペーストークンを直接設定する必要はありません。

二、アプリケーションへの OpenTelemetry 導入

依存関係のインストール

空のディレクトリにサンプルプロジェクトを作成し、Cargo.toml を以下の内容に設定します。既存のプロジェクトの場合は依存関係をマージし、元の設定を上書きしないでください:

cargo new otel-rust-demo
cd otel-rust-demo
[package]
name = "otel-rust-demo"
version = "0.1.0"
edition = "2021"

[dependencies]
opentelemetry = { version = "=0.31.0", default-features = false, features = ["trace"] }
opentelemetry_sdk = { version = "=0.31.0", default-features = false, features = ["trace"] }
opentelemetry-otlp = { version = "=0.31.0", default-features = false, features = ["trace", "http-proto", "reqwest-blocking-client"] }

SDK を初期化して Span を作成する

以下を src/main.rs として保存します。SDK は起動時に一度だけ初期化され、checkout の下に子 Span db.lookup を作成し、終了前にバッチエクスポートを待機します:

use opentelemetry::{
    global,
    trace::{TraceContextExt, Tracer},
    KeyValue,
};
use opentelemetry_otlp::{Protocol, SpanExporter, WithExportConfig};
use opentelemetry_sdk::{
    propagation::TraceContextPropagator,
    trace::{Sampler, SdkTracerProvider},
    Resource,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let exporter = SpanExporter::builder()
        .with_http()
        .with_protocol(Protocol::HttpBinary)
        .build()?;

    let provider = SdkTracerProvider::builder()
        .with_batch_exporter(exporter)
        .with_resource(Resource::builder().build())
        .with_sampler(Sampler::ParentBased(Box::new(
            Sampler::TraceIdRatioBased(1.0),
        )))
        .build();

    global::set_text_map_propagator(TraceContextPropagator::new());
    global::set_tracer_provider(provider.clone());
    let tracer = global::tracer("otel-rust-demo");

    tracer.in_span("checkout", |_cx| {
        tracer.in_span("db.lookup", |cx| {
            cx.span().set_attribute(KeyValue::new("app.operation", "lookup"));
        });
    });

    provider.shutdown()?;
    Ok(())
}

ビルドと実行

アプリケーションを起動する同じターミナルで以下のパラメータを設定します。別ホストから接続する場合は 127.0.0.1 を実際の DataKit アドレスに置き換えてください:

export OTEL_SERVICE_NAME="order-service"
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment.name=prod,service.version=1.0.0,team=backend"
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT="http://127.0.0.1:9529/otel/v1/traces"

cargo run

初回実行時は依存関係のダウンロードとコンパイルが行われます。それ以降は cargo build --release を実行して本番用バイナリをビルドできます。長時間稼働するサービスでは Provider を保持し、リクエストの受信を停止して処理中の Span を終了させた後に shutdown() を呼び出してください。

三、データ送信パラメータ

パラメータまたは設定 説明
OTEL_SERVICE_NAME service.name。サンプルでは order-service を使用していますが、安定したサービス名に設定してください。
OTEL_RESOURCE_ATTRIBUTES カンマ区切りのリソース属性。サンプルでは環境、バージョン、team を設定しています。カスタムフィールドは DataKit の customer_tags に追加してください。
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT Trace 専用の完全なアドレス: http://127.0.0.1:9529/otel/v1/traces。汎用のベースアドレスよりも優先されます。
OTEL_EXPORTER_OTLP_ENDPOINT 任意のベースアドレス: http://127.0.0.1:9529/otel。Trace 専用アドレスが設定されていない場合、Exporter が /v1/traces を追加します。
OTEL_EXPORTER_OTLP_HEADERS 任意の OTLP リクエストヘッダー。形式は key=value,key2=value2 です。受信側またはプロキシが認証を要求する場合にのみ設定します。

この例では、コード内で .with_http()Protocol::HttpBinary を使用して HTTP/Protobuf を選択しています。OTEL_EXPORTER_OTLP_PROTOCOL を変更しても、このサンプルが自動的に gRPC に切り替わることはありません。gRPC に変更するには、grpc-tonic を有効にし、.with_tonic() に切り替えて、適切な Tokio ランタイムを提供する必要があります。

サンプリングはコード内で ParentBased + ルートトレースの比率 1.0 として構成されており、親 Span のサンプリング決定に従います。本番環境では、サンプルの比率を 0.1 に変更すると、ルートトレースの約 10% がサンプリングされます。この例ではサンプラーを明示的に設定しているため、OTEL_TRACES_SAMPLEROTEL_TRACES_SAMPLER_ARG には依存しません。

この例では Trace エクスポートパイプラインを明示的に作成しているため、OTEL_TRACES_EXPORTER がその選択や終了を行うことはありません。Metric や Log の Provider は作成されていないため、OTEL_METRICS_EXPORTEROTEL_LOGS_EXPORTER を設定しても対応するシグナルは有効になりません。ログについては、DataKit の ログファイル収集 を別途使用できます。

コンテキスト伝播とアプリケーションへの組み込み

この例では W3C TraceContext プロパゲーターを登録していますが、ネットワークリクエストを自動的にインターセプトすることはありません。HTTP/RPC に組み込む場合は、サーバー側で Extractor を使用して上流のコンテキストを抽出し、新しい Span の親として設定し、クライアント側で Injector を使用して traceparenttracestate を注入します。同期サンプルの in_span.await をまたいで直接使用しないでください。非同期タスクでは FutureExt::with_context などを使用してコンテキストを伝播してください。tracing を使用するアプリケーションでは、互換性のあるバージョンの tracing-opentelemetry Layer も設定する必要があります。

検証とトラブルシューティング

  1. サンプルを実行した後、Guance のアプリケーションパフォーマンスモニタリング(APM)で order-service を指定してトレースを検索し、checkout とその子 Span db.lookup が存在することを確認します。
  2. データがない場合は、コレクターが有効になっているか、アプリケーションの環境変数が有効か、HTTP パスに /otel/v1/traces が含まれているか、DataKit とアプリケーションのエクスポートエラーを確認してください。
  3. Span が終了し、Provider が終了前にフラッシュを完了していることを確認してください。強制終了したり、ルートトレースの比率を 0 に設定すると、期待したデータが表示されない可能性があります。ネットワークが到達可能であることは、エクスポートが成功したことを意味しません。

参考ドキュメント

フィードバック

このページは役に立ちましたか?