分散トレースを使用すると、オーケストレーションの実行をエンド ツー エンドで可視化できます。
Durable Task Scheduler で OpenTelemetry を有効にすると、各オーケストレーション、アクティビティ、サブオーケストレーションによって、ワークフロー全体のタイミング、順序、エラーを示すリンクされたスパンが生成されます。 これらのトレースは、
Durable Functions スタンドアロンの Durable Task SDK はどちらもバックエンドとして Durable Task Scheduler を使用する場合に OpenTelemetry 分散トレースをサポートします。
どのように機能するのか
Durable Task SDK は、OpenTelemetry スパンを使用し、オーケストレーションとアクティビティを自動的にインストルメント化します。 SDK は、各オーケストレーションのために親スパンを作成し、各アクティビティ呼び出し、サブオーケストレーション、タイマーごとに子スパンを作成します。 トレース コンテキストはこれらすべての操作に自動的に伝達されるため、ワークフロー全体に対して 1 つの相関トレースが取得されます。
結果のトレース ツリーは次のようになります。
create_orchestration (client)
└─ orchestration (server)
├─ activity:Step1
├─ activity:Step2
└─ activity:Step3
オーケストレーターまたはアクティビティ コードにカスタム インストルメンテーションを追加する必要はありません。
Microsoft.DurableTask アクティビティ ソースを OpenTelemetry 構成に登録すると、SDK によって残りの処理が行われます。
前提条件
- Durable Functions 拡張機能 バージョン 2.13.0 以降を含むAzure Functions プロジェクト。
- 関数アプリのストレージ バックエンドとして構成された Durable Task Scheduler。
- トレースを表示するための OpenTelemetry 互換バックエンド (Application Insights、Jaeger、または別の OTLP コレクター)。
- .NET 8 SDK 以降。
-
Microsoft.DurableTask.Worker.AzureManagedとMicrosoft.DurableTask.Client.AzureManagedNuGet パッケージ。 - NuGet パッケージの
OpenTelemetry、OpenTelemetry.Extensions.Hosting、およびOpenTelemetry.Exporter.OpenTelemetryProtocol。
- 運用用 の Application Insights やローカル開発用 の Jaeger など、トレースを表示するための OpenTelemetry 互換バックエンド。
分散トレースを有効にする
Durable Functionsで分散トレースを有効にするには、host.json を更新し、OpenTelemetry と互換性のあるテレメトリ バックエンドを構成します。
host.json を更新する
host.jsontracingdurableTask の下に セクションを追加します。
{
"version": "2.0",
"extensions": {
"durableTask": {
"tracing": {
"DistributedTracingEnabled": true,
"Version": "V2"
}
}
}
}
Application Insights の構成
関数アプリで APPLICATIONINSIGHTS_CONNECTION_STRING 環境変数を設定します。
ローカル開発の場合は、 local.settings.jsonに追加します。
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"APPLICATIONINSIGHTS_CONNECTION_STRING": "<your-connection-string>"
}
}
Azureホストされているアプリの場合は、Azure ポータルの Configuration の下にアプリケーション設定として追加します。
注
以前に APPINSIGHTS_INSTRUMENTATIONKEYを使用していた場合は、最新の機能の APPLICATIONINSIGHTS_CONNECTION_STRING に切り替えます。
テレメトリ のノイズを削減する
Application Insights がトレース データをサンプリングしないようにするには、host.jsonのサンプリング 規則からRequestを除外します。
{
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
}
}
Microsoft.DurableTask アクティビティ ソースを OpenTelemetry 構成に登録します。 Durable Task SDK では、このソースを登録すると、オーケストレーションとアクティビティのスパンが自動的に作成されます。
ワーカーの Program.csで、Durable Task アクティビティ ソースを使用して OpenTelemetry トレースを追加します。
using Microsoft.DurableTask;
using Microsoft.DurableTask.Worker;
using Microsoft.DurableTask.Worker.AzureManaged;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
var builder = Host.CreateApplicationBuilder(args);
// Configure OpenTelemetry tracing
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource.AddService("durable-worker"))
.WithTracing(tracing =>
{
tracing
.AddSource("Microsoft.DurableTask")
.AddOtlpExporter(opts =>
{
opts.Endpoint = new Uri(
Environment.GetEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT")
?? "http://localhost:4317");
});
});
// Build connection string from environment variables
string endpoint = Environment.GetEnvironmentVariable("ENDPOINT") ?? "http://localhost:8080";
string taskHub = Environment.GetEnvironmentVariable("TASKHUB") ?? "default";
string connectionString = endpoint.Contains("localhost")
? $"Endpoint={endpoint};TaskHub={taskHub};Authentication=None"
: $"Endpoint={endpoint};TaskHub={taskHub};Authentication=DefaultAzure";
// Configure Durable Task worker
builder.Services.AddDurableTaskWorker()
.AddTasks(tasks =>
{
tasks.AddOrchestratorFunc<string, string>(
"OrderProcessingOrchestration", async (ctx, input) =>
{
var validated = await ctx.CallActivityAsync<string>("ValidateOrder", input);
var payment = await ctx.CallActivityAsync<string>("ProcessPayment", validated);
var shipment = await ctx.CallActivityAsync<string>("ShipOrder", payment);
var result = await ctx.CallActivityAsync<string>("SendNotification", shipment);
return result;
});
tasks.AddActivityFunc<string, string>("ValidateOrder", (ctx, input) =>
Task.FromResult($"Validated({input})"));
tasks.AddActivityFunc<string, string>("ProcessPayment", (ctx, input) =>
Task.FromResult($"Paid({input})"));
tasks.AddActivityFunc<string, string>("ShipOrder", (ctx, input) =>
Task.FromResult($"Shipped({input})"));
tasks.AddActivityFunc<string, string>("SendNotification", (ctx, input) =>
Task.FromResult($"Notified({input})"));
})
.UseDurableTaskScheduler(connectionString);
var host = builder.Build();
await host.RunAsync();
重要な行は .AddSource("Microsoft.DurableTask")であり、Durable Task SDK が出力するスパンをキャプチャするように OpenTelemetry に指示します。
OTLP エンドポイントを構成する
上記のコード スニペットは、 OTEL_EXPORTER_OTLP_ENDPOINT 環境変数を参照して、トレース データの宛先を設定します。 バックエンドに基づいてこの変数を設定します。
| Backend | エンドポイント値 | プロトコル |
|---|---|---|
| Jaeger (ローカル) | http://localhost:4317 |
gRPC |
| Jaeger (ローカル、HTTP) | http://localhost:4318 |
HTTP/protobuf |
| OpenTelemetry コレクター | http://<collector-host>:4317 |
gRPC |
| Azure Monitor (OTLP 経由) | 代わりに Azure Monitor エクスポーターを使用する | N/A |
Jaeger を使用したローカル開発では、Jaeger が OTLP gRPC を有効 (ポート 4317) で実行している場合、既定の http://localhost:4317 が機能します。 JavaScript SDK は既定で HTTP/protobuf を使用するため、4318 パスを持つポート /v1/tracesを対象とします。
Jaeger UI を使用してトレースをローカルで表示する
ローカル開発の場合は、Jaeger で Durable Task Scheduler エミュレーターを使用してトレースを表示します。 両方のサービスを開始するには、 docker-compose.yml を使用します。
services:
dts-emulator:
image: mcr.microsoft.com/dts/dts-emulator:latest
ports:
- "8080:8080" # gRPC
- "8082:8082" # Dashboard
jaeger:
image: jaegertracing/jaeger:latest
ports:
- "16686:16686" # Jaeger UI
- "4317:4317" # OTLP gRPC
- "4318:4318" # OTLP HTTP
インフラストラクチャを開始します。
docker compose up -d
アプリケーションを実行したら、 http://localhost:16686 で Jaeger UI を開き、サービス名 ( durable-worker など) を検索してトレースを表示します。
Durable Functionsを使用したローカル開発の場合、分散トレース データは既定で Application Insights に送信されます。 デプロイせずにトレースをローカルで表示するには、関数アプリの Program.csに Application Insights と共に OTLP エクスポーターを追加します。
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing
.AddSource("Microsoft.DurableTask")
.AddOtlpExporter(opts =>
{
opts.Endpoint = new Uri("http://localhost:4317");
});
});
次に、 docker run -d -p 16686:16686 -p 4317:4317 jaegertracing/jaeger:latest を使用して Jaeger をローカルで実行し、 http://localhost:16686で Jaeger UI を開きます。
Application Insights でトレースを表示する
運用環境のワークロードでは、 Application Insights が推奨されるテレメトリ バックエンドです。
DistributedTracingEnabled の中で true が Version に設定され、V2 が host.json に設定された後、開発中の Durable Functions アプリは、Application Insights に関連付けられたスパンを出力します。 Azure ポータルで完全なオーケストレーション トレースを表示するには:
- Azure ポータルで Application Insights リソースに移動します。
- トランザクション検索を開き、名前またはインスタンス ID でオーケストレーションを検索します。
- トレースを選択すると、すべての相関スパンを持つエンドツーエンドのトランザクションが表示されます。
トレースは、各アクティビティ呼び出し、サブオーケストレーション、タイマー待機ごとに、子スパンを持つ親スパンという形でオーケストレーションを表示します。 次のパターンでは、個別のトレース図形が生成されます。
| パターン | トレース図形 |
|---|---|
| 関数の連鎖 | オーケストレーター スパンの下で入れ子になっている複数のシーケンシャル アクティビティ スパン。 |
| ファンアウト/ファンイン | 並列アクティビティ スパンは、時間方向で重なり合っています。 |
| 人間との相互作用 | 外部イベントを長時間待機するオーケストレーター スパン。 |
| モニター | 反復アクティビティは、イテレーションの間にタイマー待ちを伴って繰り返し実行されます。 |
Azure Monitor OpenTelemetry エクスポーターを使用して Application Insights にトレースを送信するように OTLP エクスポーターを構成するか、OTLP を介して Application Insights に転送する OpenTelemetry コレクターにエクスポートします。
Azure.Monitor.OpenTelemetry.Exporter NuGet パッケージをインストールし、OTLP エクスポーターを次のように置き換えます。
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource.AddService("durable-worker"))
.WithTracing(tracing =>
{
tracing
.AddSource("Microsoft.DurableTask")
.AddAzureMonitorTraceExporter(opts =>
{
opts.ConnectionString = Environment.GetEnvironmentVariable(
"APPLICATIONINSIGHTS_CONNECTION_STRING");
});
});
トレース データに表示される内容
Durable Task SDK によって生成されるトレース データには、次のものが含まれます。
| スパンの種類 | 説明 |
|---|---|
create_orchestration |
新しいオーケストレーションをスケジュール設定するときに出力されるクライアント側のスパン |
orchestration |
完全な実行ライフサイクルをカバーするサーバー側オーケストレーションスパン |
activity:<name> |
タイミングと結果を示す各アクティビティ呼び出しのスパン |
sub_orchestration:<name> |
各サブオーケストレーション呼び出しのスパン |
timer |
永続タイマーの待機に対応するスパン |
各スパンには、 durabletask.type、 durabletask.task.name、 durabletask.task.instance_id、 durabletask.task.task_idなどの属性が含まれます。 失敗したアクティビティとオーケストレーションは、スパンの状態やイベントの中で、エラーの詳細を保持しています。
Troubleshooting
| 問題点 | Resolution |
|---|---|
| 痕跡が表示されない |
Microsoft.DurableTask アクティビティ ソースが登録され、エクスポーター エンドポイントに到達可能であることを確認します。 |
| トレースが不完全です | Durable Task SDK (特に JavaScript/TypeScript) の 前に OpenTelemetry SDK が初期化されていることを確認します。 |
| Application Insights の中で不足しているスパン | トレース データが削除されないように、 サンプリング設定 を無効または調整します。 |
| トレースは一致しません | バックエンドとして Durable Task Scheduler を使用していることを確認します。 トレース コンテキストの伝達にはスケジューラが必要です。 |