> ## 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.

# Implementando observabilidade no Flowker

> Habilite e interprete os traces, métricas e logs estruturados do OpenTelemetry do Flowker no Tempo, Prometheus e Loki por meio de um collector OTLP padrão.

O Flowker emite traces, métricas e logs estruturados usando o padrão **OpenTelemetry**.

## Visão geral

***

A telemetria do Flowker usa três sinais:

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

O Flowker exporta todos os sinais via **OTLP (OpenTelemetry Protocol)** para um collector de sua escolha.

## Configuração

***

Variáveis de ambiente controlam a telemetria.

```bash theme={null}
# Enable telemetry (required to activate OTLP export)
ENABLE_TELEMETRY=true

# OTLP collector endpoint (required when ENABLE_TELEMETRY=true)
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317

# Service identity
OTEL_RESOURCE_SERVICE_NAME=flowker
OTEL_RESOURCE_SERVICE_VERSION=1.0.0
OTEL_RESOURCE_DEPLOYMENT_ENVIRONMENT=production
OTEL_LIBRARY_NAME=flowker

# Log verbosity: debug | info | warn | error
LOG_LEVEL=info
```

<Note>
  Se você definir `ENABLE_TELEMETRY=true` sem `OTEL_EXPORTER_OTLP_ENDPOINT`, o Flowker não vai iniciar.
</Note>

## Tracing distribuído

***

Toda requisição HTTP e operação interna cria um **span do OpenTelemetry**. Os spans se propagam por toda a cadeia de execução. Uma única execução de workflow produz um trace conectado, do handler HTTP até as etapas individuais do executor.

### Convenção de nomenclatura de spans

Os spans seguem o padrão `<layer>.<resource>.<operation>`:

**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ó de executor processado                              |
| `command.execution.execute_with_provider_config` | Span para um nó resolvido com uma configuração de provedor específica |
| `command.execution.recover`                      | Span para recuperação de execução incompleta na inicialização         |

**Spans de comando de workflow**

| Nome do span                     | Descrição                               |
| -------------------------------- | --------------------------------------- |
| `command.workflow.create`        | Cria um novo workflow                   |
| `command.workflow.update`        | Atualiza um workflow existente          |
| `command.workflow.activate`      | Ativa um workflow                       |
| `command.workflow.deactivate`    | Desativa um workflow                    |
| `command.workflow.move_to_draft` | Move um workflow de volta para rascunho |
| `command.workflow.clone`         | Clona um workflow                       |
| `command.workflow.delete`        | Exclui um workflow                      |

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

| Nome do span                     | Descrição                           |
| -------------------------------- | ----------------------------------- |
| `command.executor_config.update` | Atualiza a configuração de executor |
| `command.executor_config.delete` | Exclui a configuração de executor   |

**Spans de configuração de provedor**

| Nome do span                      | Descrição                             |
| --------------------------------- | ------------------------------------- |
| `command.provider_config.create`  | Cria a configuração de provedor       |
| `command.provider_config.update`  | Atualiza a configuração de provedor   |
| `command.provider_config.enable`  | Habilita a configuração de provedor   |
| `command.provider_config.disable` | Desabilita a configuração de provedor |
| `command.provider_config.delete`  | Exclui a configuração de provedor     |

**Spans de consulta**

| Nome do span                  | Descrição                                |
| ----------------------------- | ---------------------------------------- |
| `query.execution.get`         | Obtém a execução pelo ID                 |
| `query.execution.list`        | Lista execuções                          |
| `query.execution.get_results` | Obtém os resultados da execução          |
| `query.workflow.get`          | Obtém o workflow pelo ID                 |
| `query.workflow.list`         | Lista workflows                          |
| `query.executor_config.get`   | Obtém a configuração de executor pelo ID |
| `query.executor_config.list`  | Lista configurações de executor          |
| `query.provider_config.get`   | Obtém a configuração de provedor pelo ID |
| `query.provider_config.list`  | Lista configurações de provedor          |

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

## Métricas

***

O Flowker expõe métricas HTTP e do sistema automaticamente via o SDK do OpenTelemetry. Você apenas precisa habilitar a telemetria.

### Métricas HTTP (via otelfiber)

Coletadas por rota pelo middleware `otelfiber`:

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

Cada métrica carrega labels: `http.request.method`, `http.route`, `http.response.status_code`.

### Métricas do sistema

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

### Buckets de histograma

Histogramas de latência usam os limites de bucket padrão do SDK do OpenTelemetry. Os valores de `http.server.duration` estão em milissegundos, então os limites são:

```
0, 5, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 2500, 5000, 7500, 10000
```

<Note>
  O Flowker não expõe diretamente um endpoint de scrape do Prometheus (`/metrics`). O Flowker exporta métricas via OTLP para seu collector, que então encaminha ao Prometheus. Configure seu collector OTLP para incluir um exporter `prometheusremotewrite`.
</Note>

## Logging estruturado

***

O Flowker usa **logging JSON estruturado** via Zap. Toda entrada de log carrega campos contextuais. Você pode indexar e consultar esses campos 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 de operação normal (execução iniciada, recuperada, etc.) |
| `warn`  | Problemas recuperáveis ou condições inesperadas, mas não fatais |
| `error` | Falhas de operação que exigem atenção                           |

Defina 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"
}
```

Nó de executor mal configurado:

```json theme={null}
{
  "level": "error",
  "node.id": "node-payment",
  "execution.id": "exec_xyz789",
  "message": "Executor node missing providerConfigId"
}
```

## Probes de saúde

***

O Flowker expõe probes de liveness e readiness compatíveis com Kubernetes para monitoramento operacional. Liveness sinaliza se o processo ainda está em execução. Readiness sinaliza se as dependências (principalmente o banco de dados) estão acessíveis. Configure ambas no nível do cluster como parte dos seus manifestos de deploy. A orquestração pode então reiniciar pods não saudáveis e remover instâncias degradadas dos balanceadores de carga.

## Dashboards do Grafana

***

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

### Painéis recomendados

**Throughput de requisições**

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

**Latência P95**

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

**Taxa de erro**

* Consulta: `sum(rate(http_server_duration_count{service_name="flowker", http_response_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)**

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

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