ベストプラクティス

OpenTelemetry .NET でトレースを使用する際のベストプラクティスを学びます

以下のベストプラクティスに従って、OpenTelemetry .NET のトレースを最大限に活用しましょう。

パッケージバージョン

使用している .NET ランタイムのバージョンに関わらず、System.Diagnostics.DiagnosticSource パッケージの最新の安定バージョンに含まれる System.Diagnostics.Activity API を使用してください。

  • OpenTelemetry .NET SDK の最新安定バージョンを使用している場合、System.Diagnostics.DiagnosticSource パッケージのバージョンについて心配する必要はありません。 パッケージの依存関係を通じてすでに管理されています。
  • .NET ランタイムチームは System.Diagnostics.DiagnosticSource のメジャーバージョンアップ時にも後方互換性について高い基準を維持しているため、互換性の懸念はありません。

トレース API

ActivitySource

System.Diagnostics.ActivitySource を頻繁に作成することは避けてください。 ActivitySource は比較的コストが高く、アプリケーション全体で再利用することを想定しています。 ほとんどのアプリケーションでは、static readonly フィールドとしてモデル化するか、依存性注入を通じてシングルトンとして扱えます。

ActivitySource.Name には、ドット区切りの アッパーキャメルケース を使用してください。 多くの場合、完全修飾クラス名を使用するのがよい選択です。 たとえば次のように行います。

static readonly ActivitySource MyActivitySource = new("MyCompany.MyProduct.MyLibrary");

Activity

パフォーマンスを向上させるため、タグの設定の前に Activity.IsAllDataRequested を確認してください。

using (var activity = MyActivitySource.StartActivity("SayHello"))
{
    if (activity != null && activity.IsAllDataRequested == true)
    {
        activity.SetTag("http.url", "http://www.mywebsite.com");
    }
}

属性の設定には Activity.SetTag を使用してください。

アクティビティを適切に終了または停止してください。 これは using ステートメントを使って暗黙的に行うことができ、この方法が推奨されます。 明示的に Activity.Dispose または Activity.Stop を呼び出すこともできます。

ループ内で Activity.AddEvent を呼び出すことは避けてください。 アクティビティは数百や数千のイベントを扱うようには設計されていません。 より適切なモデルは相関ログActivity.Links を使用することです。 たとえば次のコードのように行います。

private static async Task Test()
{
    Activity activity = Activity.Current;

    while (true)
    {
        activity.AddEvent(new ActivityEvent("Processing background task."));
        await Task.Delay(1000);
    }
}

TracerProvider の管理

TracerProvider インスタンスを頻繁に作成することは避けてください。 TracerProvider は比較的コストが高く、アプリケーション全体で再利用することを想定しています。 ほとんどのアプリケーションでは、プロセスごとに1つの TracerProvider インスタンスで十分です。

TracerProvider インスタンスを自分で作成する場合は、そのライフサイクルを管理してください。

一般的なルールとして以下が挙げられます。

  • 依存性注入(DI)を使用するアプリケーション(たとえば ASP.NET Core.NET Worker)を構築している場合、ほとんどのケースでは TracerProvider インスタンスを作成し、DI にそのライフサイクルを管理させるべきです。 詳しくは Getting Started with OpenTelemetry .NET Traces in 5 Minutes - ASP.NET Core Application チュートリアルを参照してください。
  • DI を使用しないアプリケーションを構築している場合は、TracerProvider インスタンスを作成し、ライフサイクルを明示的に管理してください。 詳しくは Getting Started with OpenTelemetry .NET Traces in 5 Minutes - Console Application チュートリアルを参照してください。
  • アプリケーション終了前に TracerProvider インスタンスを破棄し忘れると、適切なフラッシュが行われないためアクティビティがドロップされる可能性があります。
  • TracerProvider インスタンスを早すぎるタイミングで破棄すると、それ以降のアクティビティは収集されません。

相関

OpenTelemetry では、トレースは自動的にログと相関され、エグザンプラーを通じてメトリクスと相関させることもできます。

手動でのアクティビティの作成

入門ガイドで示したように、Activity を手動で作成するのは非常に簡単です。 そのため、アクティビティを過剰に作成してしまいがちです(たとえば、各メソッド呼び出しに対して作成するなど)。 コストが高いだけでなく、アクティビティが多すぎるとトレースの可視化も難しくなります。 Activity を手動で作成するかわりに、ASP.NET CoreHttpClient などの計装ライブラリを活用できるか確認してください。 これらのライブラリは Activity を作成してタグ(属性)を設定するだけでなく、プロセス境界を越えたコンテキストの伝搬や復元も処理します。

計装ライブラリが生成した Activity に必要な情報が不足している場合は、新しいアクティビティを作成するのではなく、既存の Activity にその情報を追加することが一般的に推奨されます。

静的なタグをリソースとしてモデル化する

MachineNameEnvironment など、プロセスのライフタイム全体を通じて静的なタグは、各 Activity に追加するのではなく、Resource としてモデル化すべきです。

トレースが欠落する一般的な問題

以下は、トレースが欠落する一般的な問題です。

  • Activity の作成に使用される ActivitySourceTracerProvider に追加されていない。 AddSource メソッドを使用して、指定した ActivitySource からのアクティビティを有効にしてください。
  • TracerProvider が早すぎるタイミングで破棄されている。 トレースを収集するためには、TracerProvider インスタンスがアクティブな状態に保たれている必要があります。 一般的なアプリケーションでは、1つの TracerProvider がアプリケーション起動時に構築され、アプリケーション終了時に破棄されます。 ASP.NET Core アプリケーションの場合は、OpenTelemetry.Extensions.Hosting パッケージの AddOpenTelemetry メソッドと WithTraces メソッドを使用して TracerProvider を正しくセットアップしてください。