オーケストレーション履歴のエクスポート機能を使用すると、アプリは、Durable Task Scheduler からターミナル オーケストレーション インスタンス (完了、失敗、または終了状態) の実行履歴を抽出し、Azure Blob Storageに書き込みます。 この機能は、スケジューラの外部でのオーケストレーション データの監査、コンプライアンス、分析、および長期アーカイブに使用します。
注
オーケストレーション履歴のエクスポート機能は現在プレビュー段階であり、Durable Task .NET SDK で使用できます。
Microsoft.DurableTask.ExportHistory パッケージが必要です。
ヒント
完全で実行可能な参照サンプルは、ExportHistoryWebApp で入手できます。 このガイドに従う場合は、参照として使用することをお勧めします。
オーケストレーション履歴のエクスポートのしくみ
エクスポート履歴では、永続的なエンティティとオーケストレーションを内部的に使用して、次のプロセスでエクスポート ジョブを確実に管理します。
-
ExportHistoryClientを使用してエクスポート ジョブを作成し、時間枠とエクスポート モードを指定します。 - SDK は、ジョブの状態と進行状況を追跡する永続的エンティティ (
ExportJob) を作成します。 - 内部オーケストレーションは、指定された時間枠と状態フィルターに一致するターミナル オーケストレーション インスタンスを一覧表示します。
- 一致するインスタンスごとに、アクティビティは Durable Task Scheduler から完全な実行履歴をフェッチします。
- 履歴はシリアル化され (既定では gzip 圧縮を使用した JSONL)、Azure Blob Storageに書き込まれます。
- ジョブはその進行状況をチェックポイントとして保存するため、中断された場合でも再開できます。
バッチおよび連続ジョブのエクスポートモード
エクスポート履歴では、次の 2 つのモードがサポートされます。
| モード | 行動 |
|---|---|
| バッチ | 固定時間内に終了状態に達したインスタンスをエクスポートし (completedTimeFrom から completedTimeTo)、ジョブを完了としてマークします。 |
| 連続 | 終了時刻なしで、 completedTimeFrom 以降のターミナル インスタンスを継続的に終了します。 ジョブは、削除するまでアクティブなままです。 |
前提条件
- .NET 8 SDK 以降
- Durable Task Scheduler タスク ハブ (またはローカル エミュレーター)
- ローカル開発用のAzure Storage アカウント (または Azurite)
- 次の NuGet パッケージ:
Microsoft.DurableTask.ExportHistoryMicrosoft.DurableTask.Client.AzureManagedMicrosoft.DurableTask.Worker.AzureManaged
オーケストレーション履歴のエクスポートを有効にする
エクスポート履歴パッケージをインストールします。
dotnet add package Microsoft.DurableTask.ExportHistoryDurable Task Scheduler 用の Azure Managed クライアント パッケージと worker パッケージをインストールします。
dotnet add package Microsoft.DurableTask.Client.AzureManaged dotnet add package Microsoft.DurableTask.Worker.AzureManagedワーカーとクライアントの両方にエクスポート履歴を登録します。
using Microsoft.DurableTask.Client; using Microsoft.DurableTask.Client.AzureManaged; using Microsoft.DurableTask.ExportHistory; using Microsoft.DurableTask.Worker; using Microsoft.DurableTask.Worker.AzureManaged; string connectionString = builder.Configuration.GetValue<string>("DURABLE_TASK_CONNECTION_STRING") ?? throw new InvalidOperationException("Missing DURABLE_TASK_CONNECTION_STRING"); string storageConnectionString = builder.Configuration.GetValue<string>("EXPORT_HISTORY_STORAGE_CONNECTION_STRING") ?? throw new InvalidOperationException("Missing EXPORT_HISTORY_STORAGE_CONNECTION_STRING"); string containerName = builder.Configuration.GetValue<string>("EXPORT_HISTORY_CONTAINER_NAME") ?? throw new InvalidOperationException("Missing EXPORT_HISTORY_CONTAINER_NAME"); // Register the worker with export history support. // This registers internal entities, orchestrations, and activities that manage export jobs. builder.Services.AddDurableTaskWorker(worker => { worker.UseDurableTaskScheduler(connectionString); worker.UseExportHistory(); }); // Register the client with export history support. // This configures the Azure Blob Storage destination and registers the ExportHistoryClient. builder.Services.AddDurableTaskClient(client => { client.UseDurableTaskScheduler(connectionString); client.UseExportHistory(options => { options.ConnectionString = storageConnectionString; options.ContainerName = containerName; // Optional: set a virtual folder path prefix for blob names (for example, "exports/daily"). // When set, blobs are written to "{prefix}/{hash}.{ext}" instead of "{hash}.{ext}". options.Prefix = builder.Configuration.GetValue<string>("EXPORT_HISTORY_PREFIX"); }); });
エクスポート ジョブの作成と管理
エクスポート履歴を有効にした後、 ExportHistoryClient を使用してジョブを作成および管理します。
バッチ エクスポート ジョブを作成する
次の例では、バッチ エクスポート ジョブは、固定時間内に終了状態に達したすべてのオーケストレーション インスタンスをエクスポートします。
ExportHistoryClient exportClient = app.Services.GetRequiredService<ExportHistoryClient>();
ExportJobCreationOptions options = new(
mode: ExportMode.Batch,
completedTimeFrom: DateTimeOffset.UtcNow.AddHours(-24),
completedTimeTo: DateTimeOffset.UtcNow,
destination: new ExportDestination("my-export-container")
{
// Virtual folder path prefix applied to all blob names for this job
Prefix = "exports/daily",
});
ExportHistoryJobClient jobClient = await exportClient.CreateJobAsync(options);
ExportJobDescription description = await jobClient.DescribeAsync();
連続エクスポート ジョブを作成する
次の例では、連続エクスポート ジョブは、開始時刻からターミナル インスタンスを無期限に終了します。
ExportJobCreationOptions options = new(
mode: ExportMode.Continuous,
completedTimeFrom: DateTimeOffset.UtcNow,
completedTimeTo: null,
destination: null);
ExportHistoryJobClient jobClient = await exportClient.CreateJobAsync(options);
destinationが null の場合、ジョブは ExportHistoryStorageOptions で構成された既定のコンテナーとプレフィックスを使用します。
エクスポート ジョブの詳細を取得する
ジョブの状態、進行状況カウンター、エラーなど、ジョブの完全な説明を取得するには、次のコードを使用します。
ExportJobDescription? job = await exportClient.GetJobAsync("my-job-id");
注
GetJobAsync は、指定したジョブ ID が存在しない場合に ExportJobNotFoundException をスローします。 削除された可能性のあるジョブのクエリを実行するときに、この例外を処理します。
ExportJobDescriptionには次のものが含まれます。
| 財産 | 説明 |
|---|---|
JobId |
一意のジョブ識別子。 |
Status |
現在の状態: Pending、 Active、 Failed、または Completed。 |
CreatedAt |
ジョブが生成された時。 |
LastModifiedAt |
ジョブが最後に更新された日時。 |
ScannedInstances |
これまでにスキャンされたインスタンスの合計数。 |
ExportedInstances |
これまでにエクスポートされたインスタンスの合計数。 |
LastError |
最後のエラー メッセージ (存在する場合)。 |
ジョブを一覧表示する
次の例のようなコードを使用して、アクティブなジョブの一覧をエクスポートします。
ExportJobQuery query = new()
{
Status = ExportJobStatus.Active,
CreatedFrom = DateTimeOffset.UtcNow.AddDays(-7),
PageSize = 50,
};
AsyncPageable<ExportJobDescription> jobs = exportClient.ListJobsAsync(query);
await foreach (ExportJobDescription job in jobs)
{
Console.WriteLine($"{job.JobId}: {job.Status} ({job.ExportedInstances} exported)");
}
ExportJobQueryでは、次のフィルター プロパティがサポートされています。
| 財産 | 説明 |
|---|---|
Status |
ジョブの状態 ( Pending、 Active、 Failed、または Completed) でフィルター処理します。 |
JobIdPrefix |
ID がこのプレフィックスで始まるジョブをフィルター処理します。 |
CreatedFrom |
この時刻以降に作成されたジョブのみを返します。 |
CreatedTo |
この時刻以前に作成されたジョブのみを返します。 |
PageSize |
1 ページあたりの結果の最大数。 |
ContinuationToken |
結果の次のページを取得するためのトークン。 |
ジョブを削除する
ジョブを削除するには、次のコードを使用します。
ExportHistoryJobClient jobClient = exportClient.GetJobClient("my-job-id");
await jobClient.DeleteAsync();
注
ジョブが存在しない場合、DeleteAsync は ExportJobNotFoundException をスローします。 ジョブを削除しても既にエクスポートされている BLOB はAzure Blob Storageから削除されません。
ジョブ作成オプションをエクスポートする
ExportJobCreationOptions クラスは、エクスポート ジョブの動作を制御し、次のパラメーターを含みます。
| パラメーター | 必須 | 説明 | デフォルト |
|---|---|---|---|
mode |
はい |
Batch 固定ウィンドウの場合は ゚、進行中のエクスポートの場合は Continuous 。 |
— |
completedTimeFrom |
はい (バッチ) | インスタンスが終了状態に達したタイミングに基づく時間枠の開始 (開始時点を含む)。 連続モードの場合、既定値は UtcNow (指定されていない場合) です。 |
— |
completedTimeTo |
はい (バッチ) | 時間枠の終了 (終了時点を含む)。 連続モードでは省略する必要があります。 今後は使用できません。 | — |
destination |
いいえ | このジョブの既定の BLOB コンテナーとプレフィックスをオーバーライドします。 | の既定値を使用します。 ExportHistoryStorageOptions |
jobId |
いいえ | カスタム ジョブ識別子。 | 自動生成された GUID |
format |
いいえ | エクスポート形式: JSONL (gzip 圧縮) または JSON (非圧縮)。 | gzip を使用した JSONL |
runtimeStatus |
いいえ | ターミナルの状態 ( Completed、 Failed、 Terminated) でフィルター処理します。 |
すべてのターミナルの状態 |
maxInstancesPerBatch |
いいえ | バッチごとに処理するインスタンスの数 (1 ~ 1000)。 | 100 |
エクスポートされたデータがAzure Blob Storageに格納される場所
エクスポートされた履歴は、次のパラメーターを使用してAzure Blob Storageに書き込まれます。
-
コンテナー:
EXPORT_HISTORY_CONTAINER_NAMEからの既定値、またはジョブごとのdestinationオーバーライド。 -
BLOB 名:
(completedTimestamp, instanceId)の SHA-256 ハッシュから派生します。 -
ファイル形式:
- 既定値:
.jsonl.gz(JSON Lines,gzip-compressed — 1 行に 1 つの履歴イベント) - 省略可能:
.json(履歴イベントの非圧縮 JSON 配列)
- 既定値:
-
プレフィックスを持つ BLOB パス: プレフィックスが構成されている場合 (たとえば、
exports/daily)、BLOB パスはexports/daily/{hash}.{ext}になります。 プレフィックスがない場合、BLOB は{hash}.{ext}としてコンテナー ルートに直接書き込まれます。
各 BLOB には、追跡可能な instanceId メタデータ タグが含まれています。
エクスポート履歴構成の環境変数
これらの環境変数は、Durable Task .NET SDK エクスポート履歴サンプルと共に使用します。
| Variable | 説明 | サンプルの既定値 |
|---|---|---|
DURABLE_TASK_CONNECTION_STRING |
Durable Task Scheduler 接続文字列 | Endpoint=http://localhost:8080;TaskHub=default;Authentication=None |
EXPORT_HISTORY_STORAGE_CONNECTION_STRING |
Azure Storage の接続文字列(エクスポートされた履歴 BLOB 用) | UseDevelopmentStorage=true |
EXPORT_HISTORY_CONTAINER_NAME |
エクスポートされた履歴の BLOB コンテナー | export-history |
EXPORT_HISTORY_PREFIX |
BLOB 名に対するオプションの仮想フォルダー パスのプレフィックス | 設定解除する |
ASPNETCORE_URLS |
サンプルの HTTP ホスト用のリッスン URL | フレームワークの既定値 |
エクスポート履歴のAzureアクセス許可
ローカル エミュレーターの代わりに Azure リソースを使用する場合、アプリ ID は Durable Task Scheduler と Blob Storage にアクセスする必要があります。
- アプリのタスク ハブに
Durable Task Data Contributorを付与します。 - エクスポートされた履歴 BLOB を格納するストレージ アカウントに
Storage Blob Data Contributorを付与します。
エクスポート ジョブに関する重要な考慮事項
同時消去操作:
エクスポート ジョブの実行中にオーケストレーション インスタンスを消去すると、エクスポートが影響を受ける可能性があります。 エクスポートが読み取る前に消去されたインスタンスは、エクスポートされたデータから欠落します。 同じ時間枠をカバーするアクティブなエクスポート ジョブと同時に消去操作を実行しないようにします。BLOB のクリーンアップ:
エクスポート ジョブを削除しても、エクスポートされた BLOB はAzure Blob Storageから削除されません。 エクスポートされたデータを削除する必要がある場合は、ストレージ アカウントから BLOB を個別に削除します。
エクスポートが機能することを確認する
エクスポート ジョブを作成した後、両方のシグナルをチェックして動作することを確認します。
- ジョブの状態は、
PendingからActiveに移行し、最終的にはCompletedに移行します (バッチ モードの場合)。 - BLOB エントリは、構成済みのエクスポート コンテナーに表示されます。
ジョブの状態をプログラムを使ってポーリングできます。
ExportJobDescription? job;
do
{
await Task.Delay(TimeSpan.FromSeconds(5));
job = await exportClient.GetJobAsync(jobId);
Console.WriteLine($"Status: {job?.Status}, Exported: {job?.ExportedInstances}");
}
while (job?.Status is ExportJobStatus.Pending or ExportJobStatus.Active);
ローカル開発の場合は、次のAzure CLI コマンドを実行してコンテナーを検査します。
az storage blob list \
--connection-string "UseDevelopmentStorage=true" \
--container-name export-history \
--output table
ヒント
ExportHistoryWebApp サンプルには、VS Code に対する既製の REST クライアント要求を含む ExportHistoryWebApp.http ファイルが含まれています。 それを開き、[ 要求の送信 ] をクリックして、作成、取得、一覧表示、削除操作をすばやくテストします。