Exportar o histórico de orquestração com o Agendador de Tarefas Duráveis (versão prévia)

O recurso de exportação de histórico de orquestração permite que seu aplicativo extraia históricos de execução para instâncias de orquestração em estado terminal (concluído, falhou ou encerrado) de Durable Task Scheduler e os escreva no Armazenamento de Blobs do Azure. Use esse recurso para auditoria, conformidade, análise e arquivamento de longo prazo de dados de orquestração fora do agendador.

Observação

O recurso de exportação de histórico de orquestração está atualmente na versão prévia e disponível para o SDK .NET Durable Task. Ele requer o pacote Microsoft.DurableTask.ExportHistory.

Dica

Uma amostra de referência completa e executável está disponível em ExportHistoryWebApp. É recomendável usá-lo como referência à medida que você segue este guia.

Como funciona a exportação do histórico de orquestração

O histórico de exportação utiliza entidades duráveis e orquestrações internas para gerenciar tarefas de exportação de forma confiável, seguindo o processo descrito a seguir.

  1. Você cria um trabalho de exportação por meio do ExportHistoryClient, especificando uma janela de tempo e um modo de exportação.
  2. O SDK cria uma entidade durável (ExportJob) que acompanha o estado e o progresso do trabalho.
  3. Uma orquestração interna lista instâncias de orquestração terminal que correspondem ao período de tempo e aos filtros de status especificados.
  4. Para cada instância correspondente, uma atividade busca o histórico de execução completo do Agendador de Tarefas Duráveis.
  5. O histórico é serializado (JSONL com compactação gzip por padrão) e gravado em Armazenamento de Blobs do Azure.
  6. O trabalho registra seu progresso em pontos de verificação, para que possa ser retomado caso seja interrompido.

Modos de exportação para trabalhos em lotes e contínuos

O histórico de exportação dá suporte a dois modos:

Modo Comportamento
Batch Exporta instâncias que atingiram um estado terminal dentro de uma janela de tempo fixa (completedTimeFrom para completedTimeTo), em seguida, marca o trabalho como concluído.
Contínuo Instâncias do terminal Tails são executadas continuamente a partir de completedTimeFrom, sem horário de término. O trabalho permanece ativo até que você o exclua.

Pré-requisitos

  • SDK do .NET 8 ou posterior
  • Um hub de tarefas do Agendador de Tarefas Durável (ou o emulador local)
  • Uma conta Armazenamento do Azure (ou Azurite para desenvolvimento local)
  • Os seguintes pacotes NuGet:
    • Microsoft.DurableTask.ExportHistory
    • Microsoft.DurableTask.Client.AzureManaged
    • Microsoft.DurableTask.Worker.AzureManaged

Habilitar a exportação do histórico de orquestração

  1. Instale o pacote de histórico de exportação.

    dotnet add package Microsoft.DurableTask.ExportHistory
    
  2. Instale o cliente Azure gerenciado e os pacotes de trabalho para o Agendador de Tarefas Duráveis.

    dotnet add package Microsoft.DurableTask.Client.AzureManaged
    dotnet add package Microsoft.DurableTask.Worker.AzureManaged
    
  3. Registre o histórico de exportação tanto no trabalhador quanto no cliente.

    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");
        });
    });
    

Criar e gerenciar trabalhos de exportação

Depois de habilitar o histórico de exportação, use o ExportHistoryClient para criar e gerenciar trabalhos.

Criar uma tarefa de exportação em lote

No exemplo a seguir, um trabalho de exportação em lote exporta todas as instâncias de orquestração que atingiram um estado terminal dentro de uma janela de tempo fixa.

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();

Criar um trabalho de exportação contínua

No exemplo a seguir, uma tarefa de exportação contínua monitora instâncias de terminal indefinidamente a partir de um horário de início.

ExportJobCreationOptions options = new(
    mode: ExportMode.Continuous,
    completedTimeFrom: DateTimeOffset.UtcNow,
    completedTimeTo: null,
    destination: null);

ExportHistoryJobClient jobClient = await exportClient.CreateJobAsync(options);

Quando destination for nulo, o trabalho usará o contêiner padrão e o prefixo configurados em ExportHistoryStorageOptions.

Obter detalhes da tarefa de exportação

Use o código a seguir para recuperar a descrição completa de um trabalho, incluindo seu status, contadores de progresso e quaisquer erros.

ExportJobDescription? job = await exportClient.GetJobAsync("my-job-id");

Observação

GetJobAsync lança ExportJobNotFoundException se a ID do trabalho especificada não existir. Lide com essa exceção ao consultar trabalhos que podem ter sido excluídos.

A API ExportJobDescription inclui:

Propriedade Descrição
JobId O identificador de trabalho exclusivo.
Status Status atual: Pending, , Active, Failedou Completed.
CreatedAt Quando a tarefa foi criada.
LastModifiedAt Quando o trabalho foi atualizado pela última vez.
ScannedInstances Número total de instâncias escaneadas até agora.
ExportedInstances Número total de instâncias exportadas até agora.
LastError Última mensagem de erro, se houver.

Listar trabalhos

Exporte uma lista de trabalhos ativos usando código semelhante ao exemplo a seguir.

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)");
}

O ExportJobQuery suporta as seguintes propriedades de filtro:

Propriedade Descrição
Status Filtrar por status do trabalho: Pending, , Active, Failedou Completed.
JobIdPrefix Filtrar trabalhos cuja ID começa com esse prefixo.
CreatedFrom Devolver somente os trabalhos criados até ou após esse momento.
CreatedTo Devolver somente os trabalhos criados até ou antes desse momento.
PageSize Número máximo de resultados por página.
ContinuationToken Token para recuperar a próxima página de resultados.

Excluir um trabalho

Use o código a seguir para excluir um trabalho.

ExportHistoryJobClient jobClient = exportClient.GetJobClient("my-job-id");
await jobClient.DeleteAsync();

Observação

DeleteAsync lançará ExportJobNotFoundException se o trabalho não existir. Excluir um trabalho não remove os blobs que já foram exportados do Armazenamento de Blobs do Azure.

Opções de criação de trabalho de exportação

A ExportJobCreationOptions classe controla o comportamento do trabalho de exportação e inclui os parâmetros a seguir.

Parâmetro Obrigatório Descrição Default
mode Sim Batch para uma janela fixa ou Continuous para exportação contínua.
completedTimeFrom Sim (Lote) Início do período (inclusive), com base no momento em que as instâncias atingiram um estado terminal. Para o modo Contínuo, o padrão é UtcNow caso não seja fornecido.
completedTimeTo Sim (Lote) Fim da janela de tempo (inclusive). Deve ser omitido para o modo Contínuo. Não pode ser no futuro.
destination No Substitua o contêiner de blobs e o prefixo padrão para esta tarefa. Usa o padrão de ExportHistoryStorageOptions
jobId No Identificador de trabalho personalizado. GUID gerado automaticamente
format No Formato de exportação: JSONL (compactado por gzip) ou JSON (descompactado). JSONL com gzip
runtimeStatus No Filtrar por status de terminal: Completed, , Failed. Terminated Todos os status do terminal
maxInstancesPerBatch No Número de instâncias a serem processadas por lote (1 a 1000). 100

Onde os dados exportados são armazenados no Armazenamento de Blobs do Azure

O histórico exportado é gravado em Armazenamento de Blobs do Azure com os parâmetros a seguir.

  • Contêiner: padrão de EXPORT_HISTORY_CONTAINER_NAME, ou a substituição por tarefa destination.
  • Nome do blob: derivado de um hash SHA-256 de (completedTimestamp, instanceId).
  • Formato do arquivo:
    • Padrão: .jsonl.gz (Linhas JSON, compactadas por gzip — um evento de histórico por linha)
    • Opcional: .json (matriz JSON descompactada de eventos históricos)
  • Caminho de blob com prefixo: quando um prefixo é configurado (por exemplo, exports/daily), o caminho do blob se torna exports/daily/{hash}.{ext}. Sem um prefixo, o blob é gravado diretamente na raiz do contêiner como {hash}.{ext}.

Cada blob inclui uma instanceId marca de metadados para rastreabilidade.

Variáveis de ambiente para a configuração do histórico de exportação

Utilize essas variáveis de ambiente com o exemplo de histórico de exportação do SDK .NET do Durable Task.

Variable Descrição Padrão de amostra
DURABLE_TASK_CONNECTION_STRING Cadeia de Conexão do Agendador de Tarefas Durável Endpoint=http://localhost:8080;TaskHub=default;Authentication=None
EXPORT_HISTORY_STORAGE_CONNECTION_STRING Cadeia de conexão do Armazenamento do Azure para blobs de histórico exportados UseDevelopmentStorage=true
EXPORT_HISTORY_CONTAINER_NAME Contêiner de blob para exportação de histórico export-history
EXPORT_HISTORY_PREFIX Prefixo de caminho de pasta virtual opcional para nomes de blobs remover definição
ASPNETCORE_URLS Escutar URLs para o host HTTP do exemplo padrão da estrutura

permissões de Azure para o histórico de exportação

Quando você usa recursos Azure em vez de emuladores locais, a identidade do aplicativo precisa de acesso ao Agendador de Tarefas Duráveis e Armazenamento de Blobs:

  1. Conceda Durable Task Data Contributor no hub de tarefas do aplicativo.
  2. Conceda permissões Storage Blob Data Contributor na conta de armazenamento que armazena os blobs de histórico exportados.

Considerações importantes para trabalhos de exportação

  • Operações de limpeza simultâneas:
    Se você remover instâncias de orquestração enquanto uma tarefa de exportação estiver em execução, a exportação poderá ser afetada. Instâncias que forem eliminadas antes da leitura durante a exportação estarão ausentes dos dados exportados. Evite executar operações de limpeza simultaneamente com trabalhos de exportação ativos que abrangem a mesma janela de tempo.

  • Limpeza de blob:
    Excluir um trabalho de exportação não remove os blobs exportados de Armazenamento de Blobs do Azure. Se você precisar remover os dados exportados, exclua os blobs da conta de armazenamento separadamente.

Verificar se a exportação funciona

Depois de criar um trabalho de exportação, verifique se ele funciona verificando os dois sinais:

  • O status do trabalho passa de Pending para Active e, eventualmente, para Completed (no modo Lote).
  • As entradas de blob aparecem no contêiner de exportação configurado.

Você pode sondar o status do trabalho programaticamente:

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);

Para desenvolvimento local, execute este comando CLI do Azure para inspecionar o contêiner:

az storage blob list \
  --connection-string "UseDevelopmentStorage=true" \
  --container-name export-history \
  --output table

Dica

O exemplo ExportHistoryWebApp inclui um arquivo ExportHistoryWebApp.http com solicitações prontas do cliente REST para VS Code. Abra-o e clique em Enviar Solicitação para testar rapidamente as operações de criação, obtenção, lista e exclusão.

Próximas Etapas