> For the complete documentation index, see [llms.txt](https://docs.skail.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.skail.dev/construir/testar-depurar-e-observar/como-observar-execucoes-monitor-otlp-logs.md).

# Como observar execuções: Monitor, OTLP, logs

Três fontes para saber o que as suas execuções estão fazendo: o Monitor do portal, os spans exportados por OpenTelemetry e os logs da sua aplicação. Como usar cada uma e como correlacioná-las pelo TaskId.

## Monitor: por execução

O Monitor lista as execuções do environment com TaskId, function, workload e versão, estado (em execução, aguardando evento, aguardando prazo, concluída, falha) e a linha do tempo: um item por passo, com argumentos, resultados, duração e retentativas de cada command; para esperas, o nome do evento e o instance id esperados; para falhas, a exceção.

Use para responder "onde está o pedido 4711": procure pelo TaskId (o id que você passou no trigger) e leia a linha do tempo. Use para diagnosticar uma espera que não termina: o nome e o id esperados estão ali; compare com o que o fire está enviando. Use para retomar uma execução falha depois de corrigir a causa. Ver [Monitor](/construir/portal/monitor.md).

## OpenTelemetry: por span

O runtime exporta traces automaticamente: cada function e cada command abre um span filho do `traceparent` recebido no trigger, com nome, duração, resultado e erro. Se o seu sistema que dispara já propaga `traceparent` (ASP.NET Core faz isso por padrão com OpenTelemetry), o trace começa no seu controller, passa pelo trigger, pela function e pelos commands, e volta pelo fire do webhook: uma transação de negócio inteira em um único trace, atravessando dias de espera.

Nada a configurar: o destino é o skail, que alimenta o Monitor com esses spans.

## Logs: pelo TaskId

Dentro de functions e commands, use `ILogger<T>` normalmente. Inclua sempre o `TaskId` para agrupar:

```csharp
[SkailFunction]
public async SkailTask EmitirFatura(Guid faturaId)
{
    using var escopo = _log.BeginScope(new Dictionary<string, object>
    {
        ["TaskId"] = SkailContext.Current.TaskId,
        ["FaturaId"] = faturaId
    });

    _log.LogInformation("Iniciando emissão");
    var valor = await CarregarValor(faturaId);
    _log.LogInformation("Valor carregado: {Valor}", valor);
    await CobrarCartao(faturaId, valor);
}
```

Dois cuidados. O corpo da function é reexecutado no replay, então um log na function pode aparecer mais de uma vez para a mesma execução (uma vez por retomada); é esperado, e o `TaskId` no escopo deixa isso legível. Log dentro de command aparece uma vez por execução do command. E logs vão para o skail, correlacionados ao span da execução.

## Correlacionar as três

O TaskId é a chave. Ele é o id da URL do trigger, o identificador da execução no Monitor, um atributo dos spans, e o campo do escopo de log. Adote a regra de usar um id de negócio como TaskId (o id da fatura) e a correlação passa a ser trivial: o suporte recebe "fatura 8f2c...", procura esse id no Monitor, nos traces e nos logs, e vê a mesma história em três ângulos.

## O que vale observar em produção

Execuções em falha (esgotaram as tentativas): precisam de ação. Execuções aguardando evento há mais tempo que o esperado: o fire não está chegando, ou nome e id divergem. Commands com retentativas altas: uma integração está degradando antes de falhar. Tempo entre trigger e início: a aplicação está fora ou com instâncias de menos. O que fazer com cada um está em [Monitoramento e alertas](/operar/monitoramento-e-alertas.md).

## Próximos passos

[Monitor](/construir/portal/monitor.md) para a referência da tela. [Como depurar com Time Travel Debug](/construir/testar-depurar-e-observar/como-depurar-com-time-travel-debug.md) para quando olhar não basta. [Troubleshooting](/operar/troubleshooting.md) para os sintomas mais comuns.
