> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Guia de Observabilidade

> Habilite traces, métricas e logs estruturados do OpenTelemetry no Flowker e conecte-os a Tempo, Prometheus e Loki para observabilidade completa.

O Flowker emite traces, métricas e logs estruturados usando o padrão **OpenTelemetry**. Este guia explica o que está disponível, como habilitar e como interpretar os dados no seu stack de observabilidade.

## Visão geral

***

A telemetria do Flowker é construída sobre três sinais:

| Sinal    | Backend    | O que cobre                                                      |
| -------- | ---------- | ---------------------------------------------------------------- |
| Traces   | Tempo      | Spans distribuídos por execuções de workflows e steps            |
| Métricas | Prometheus | Taxas de requisições HTTP, latência e uso de recursos do sistema |
| Logs     | Loki       | Logs JSON estruturados para cada operação                        |

Todos os sinais são exportados via **OTLP (OpenTelemetry Protocol)** para um collector de sua escolha.

## Configuração

***

A telemetria é controlada por variáveis de ambiente.

```bash theme={null}
# Habilitar telemetria (obrigatório para ativar a exportação OTLP)
ENABLE_TELEMETRY=true

# Endpoint do collector OTLP (obrigatório quando ENABLE_TELEMETRY=true)
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317

# Identidade do serviço
OTEL_RESOURCE_SERVICE_NAME=flowker
OTEL_RESOURCE_SERVICE_VERSION=1.0.0
OTEL_RESOURCE_DEPLOYMENT_ENVIRONMENT=production
OTEL_LIBRARY_NAME=flowker

# Verbosidade dos logs: debug | info | warn | error
LOG_LEVEL=info
```

<Note>
  Se `ENABLE_TELEMETRY=true` estiver configurado sem `OTEL_EXPORTER_OTLP_ENDPOINT`, o Flowker falhará ao iniciar.
</Note>

## Rastreamento distribuído

***

Cada requisição HTTP e operação interna cria um **span do OpenTelemetry**. Os spans são propagados por toda a cadeia de execução, de modo que uma única execução de workflow produz um trace conectado desde o HTTP handler até os steps individuais do executor.

### Convenção de nomes de spans

Os spans seguem o padrão `<camada>.<recurso>.<operação>`:

**Spans de execução**

| Nome do span                                     | Descrição                                                             |
| ------------------------------------------------ | --------------------------------------------------------------------- |
| `command.execution.execute`                      | Span raiz para uma execução de workflow                               |
| `command.execution.execute_executor_node`        | Span para cada nó executor processado                                 |
| `command.execution.execute_with_provider_config` | Span para um nó resolvido com uma configuração de provider específica |
| `command.execution.recover`                      | Span para recuperação de execuções incompletas na inicialização       |

**Spans de comandos de workflow**

| Nome do span                  | Descrição                       |
| ----------------------------- | ------------------------------- |
| `command.workflow.create`     | Criar um novo workflow          |
| `command.workflow.update`     | Atualizar um workflow existente |
| `command.workflow.activate`   | Ativar um workflow              |
| `command.workflow.deactivate` | Desativar um workflow           |
| `command.workflow.clone`      | Clonar um workflow              |
| `command.workflow.delete`     | Excluir um workflow             |

**Spans de configuração de executor**

| Nome do span                                | Descrição                            |
| ------------------------------------------- | ------------------------------------ |
| `command.executor_config.create`            | Criar configuração de executor       |
| `command.executor_config.update`            | Atualizar configuração de executor   |
| `command.executor_config.activate`          | Ativar configuração de executor      |
| `command.executor_config.enable`            | Habilitar configuração de executor   |
| `command.executor_config.disable`           | Desabilitar configuração de executor |
| `command.executor_config.mark_configured`   | Marcar executor como configurado     |
| `command.executor_config.mark_tested`       | Marcar executor como testado         |
| `command.executor_config.test_connectivity` | Testar conectividade do executor     |
| `command.executor_config.delete`            | Excluir configuração de executor     |

**Spans de configuração de provider**

| Nome do span                                | Descrição                            |
| ------------------------------------------- | ------------------------------------ |
| `command.provider_config.create`            | Criar configuração de provider       |
| `command.provider_config.update`            | Atualizar configuração de provider   |
| `command.provider_config.enable`            | Habilitar configuração de provider   |
| `command.provider_config.disable`           | Desabilitar configuração de provider |
| `command.provider_config.test_connectivity` | Testar conectividade do provider     |
| `command.provider_config.delete`            | Excluir configuração de provider     |

**Spans de consultas**

| Nome do span                           | Descrição                                                 |
| -------------------------------------- | --------------------------------------------------------- |
| `query.execution.get`                  | Obter execução por ID                                     |
| `query.execution.list`                 | Listar execuções                                          |
| `query.execution.get_results`          | Obter resultados de execução                              |
| `query.workflow.get`                   | Obter workflow por ID                                     |
| `query.workflow.get_by_name`           | Obter workflow por nome                                   |
| `query.workflow.list`                  | Listar workflows                                          |
| `query.executor_config.get`            | Obter configuração de executor por ID                     |
| `query.executor_config.get_by_name`    | Obter configuração de executor por nome                   |
| `query.executor_config.list`           | Listar configurações de executor                          |
| `query.executor_config.exists`         | Verificar existência de configuração de executor          |
| `query.executor_config.exists_by_name` | Verificar existência de configuração de executor por nome |
| `query.provider_config.get`            | Obter configuração de provider por ID                     |
| `query.provider_config.list`           | Listar configurações de provider                          |

<Tip>
  No Grafana Tempo, busque pelo nome do serviço (`flowker`) e filtre por nome do span para isolar operações específicas. Use `command.execution.execute` como ponto de entrada para ver um trace completo do workflow.
</Tip>

## Métricas

***

O Flowker expõe métricas HTTP e do sistema automaticamente via SDK do OpenTelemetry. Nenhuma configuração adicional é necessária além de habilitar a telemetria.

### Métricas HTTP (via otelfiber)

Coletadas por rota pelo middleware `otelfiber`:

| Métrica                       | Tipo          | Descrição                                 |
| ----------------------------- | ------------- | ----------------------------------------- |
| `http.server.duration`        | Histograma    | Duração da requisição em milissegundos    |
| `http.server.request.size`    | Histograma    | Tamanho do payload da requisição em bytes |
| `http.server.response.size`   | Histograma    | Tamanho do payload da resposta em bytes   |
| `http.server.active_requests` | UpDownCounter | Número de requisições em andamento        |

Cada métrica inclui os labels: `http.method`, `http.route`, `http.status_code`.

### Métricas do sistema

| Métrica            | Tipo  | Unidade    | Descrição                          |
| ------------------ | ----- | ---------- | ---------------------------------- |
| `system.cpu.usage` | Gauge | percentual | Uso de CPU do host do processo     |
| `system.mem.usage` | Gauge | percentual | Uso de memória do host do processo |

### Buckets de histograma

Histogramas de latência usam os seguintes limites de bucket (em segundos):

```
0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10
```

<Note>
  O Flowker não expõe um endpoint de scraping do Prometheus (`/metrics`) diretamente. As métricas são exportadas via OTLP para o seu collector, que as repassa ao Prometheus. Configure seu collector OTLP para incluir um exportador `prometheusremotewrite`.
</Note>

## Logging estruturado

***

O Flowker usa **logging JSON estruturado** via Zap. Cada entrada de log é enriquecida com campos contextuais que podem ser indexados e consultados no Loki.

### Referência de campos de log

| Campo           | Descrição                                 | Exemplo                     |
| --------------- | ----------------------------------------- | --------------------------- |
| `operation`     | Nome do span/operação                     | `command.execution.execute` |
| `workflow.id`   | Identificador do workflow                 | `wf_abc123`                 |
| `execution.id`  | Identificador da execução                 | `exec_xyz789`               |
| `node.id`       | Identificador do nó dentro de um workflow | `node-payment`              |
| `executor.id`   | Identificador do executor                 | `exec_cfg_001`              |
| `error.message` | Descrição do erro quando aplicável        | `database ping failed: ...` |

### Níveis de log

| Nível   | Quando usado                                                     |
| ------- | ---------------------------------------------------------------- |
| `debug` | Estado interno detalhado — apenas para desenvolvimento           |
| `info`  | Marcos normais de operação (execução iniciada, recuperada, etc.) |
| `warn`  | Problemas recuperáveis ou condições inesperadas mas não fatais   |
| `error` | Falhas de operação que requerem atenção                          |

Configure a variável de ambiente `LOG_LEVEL` para controlar a verbosidade.

### Exemplos de entradas de log

Execução de workflow iniciada:

```json theme={null}
{
  "level": "info",
  "operation": "command.execution.execute",
  "workflow.id": "wf_abc123",
  "message": "Starting workflow execution"
}
```

Recuperação de execução incompleta:

```json theme={null}
{
  "level": "info",
  "operation": "command.execution.recover",
  "count": 3,
  "message": "Recovering incomplete executions"
}
```

Execução com falha:

```json theme={null}
{
  "level": "error",
  "execution.id": "exec_xyz789",
  "workflow.id": "wf_abc123",
  "execution.status": "failed",
  "error.message": "executor node missing providerConfigId",
  "message": "Workflow execution failed"
}
```

## Probes de saúde

***

O Flowker expõe probes de liveness e readiness compatíveis com Kubernetes para monitoramento operacional. Liveness indica se o processo está em execução; readiness indica se as dependências (notadamente o banco de dados) estão acessíveis. Configure ambos no nível do cluster, como parte dos seus manifestos de deployment, para que a orquestração possa reiniciar pods não saudáveis e remover instâncias degradadas dos load balancers.

## Dashboards do Grafana

***

A telemetria do Flowker se integra diretamente com o stack de observabilidade da Lerian. Dashboards pré-configurados estão disponíveis através da instância do Grafana gerenciada pela Lerian.

### Painéis recomendados

**Throughput de requisições**

* Query: `sum(rate(http_server_duration_count{service_name="flowker"}[5m])) by (http_route)`
* Mostra requisições por segundo, por rota

**Latência P95**

* Query: `histogram_quantile(0.95, sum(rate(http_server_duration_bucket{service_name="flowker"}[5m])) by (le, http_route))`
* Mostra o percentil 95 do tempo de resposta por rota

**Taxa de erros**

* Query: `sum(rate(http_server_duration_count{service_name="flowker", http_status_code=~"5.."}[5m])) / sum(rate(http_server_duration_count{service_name="flowker"}[5m]))`
* Mostra a proporção de respostas 5xx

**Execuções ativas (via logs)**

* Loki query: `{service_name="flowker"} |= "Starting workflow execution" | count_over_time([1m])`

<Note>
  Para a configuração completa do stack de observabilidade, consulte [**Plataforma → Observabilidade**](/pt/platform/observability).
</Note>
