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

# Observabilidade do Fetcher

> Endpoints de saúde e prontidão do Fetcher, sondas paralelas de dependências, comportamento de drenagem em SIGTERM, relato do circuit breaker, métricas Prometheus e tracing OpenTelemetry.

O Fetcher responde a três perguntas operacionais por HTTP: o processo está vivo, ele consegue atender tráfego agora e qual dependência está em falha. Esta página cobre cada superfície e o que ela reporta.

## Endpoints

***

| Endpoint             | Responde                                                     | Manager | Worker |
| -------------------- | ------------------------------------------------------------ | ------- | ------ |
| `/health`            | O processo está vivo e iniciou de forma limpa?               | Sim     | Sim    |
| `/readyz`            | Esta instância consegue atender tráfego agora?               | Sim     | Sim    |
| `/readyz/tenant/:id` | Ela consegue atender um tenant? Apenas em modo multi-tenant. | Sim     | Sim    |
| `/metrics`           | Exposição Prometheus.                                        | Sim     | Sim    |
| `/version`           | Versão do build.                                             | Sim     | —      |

O Manager serve todos eles em `SERVER_ADDRESS`. O Worker não tem servidor de API, então ele roda um microsservidor de saúde em `HEALTH_PORT`, cujo padrão é `4007`.

Todos eles montam antes da autenticação. As sondas do Kubernetes e do balanceador de carga não precisam de token.

## `/health` e a autossondagem de inicialização

***

O `/health` não é um 200 estático. No boot, o Fetcher roda cada sonda de dependência uma vez, em paralelo, e então grava uma flag de processo com o resultado. Até essa autossondagem passar, o `/health` retorna 503.

<Note>
  **O kubelet reinicia um pod cujas dependências falharam no boot.** Ele não manda tráfego para o pod. A flag começa falsa, então um processo que quebra no meio da sondagem nunca reporta saúde por acidente. Aponte a sua sonda de liveness para o `/health`.
</Note>

Cada dependência também emite o resultado da própria autossondagem como métrica. Uma falha repetida no boot, portanto, aparece em um painel, e não só nos logs.

## `/readyz` e as sondas de dependências

***

O `/readyz` roda toda sonda registrada a cada requisição, em paralelo, uma goroutine por dependência. O handler não guarda cache nem estado de fundo. Uma resposta em cache abre uma janela em que o Kubernetes continua roteando para um pod degradado.

Um agregado saudável retorna 200. Qualquer outra coisa retorna 503. O corpo da resposta reporta cada dependência pelo nome, com o status dela, a latência dela e a postura de TLS dela.

### O que cada serviço sonda

| Dependência          | Manager         | Worker          |
| -------------------- | --------------- | --------------- |
| `mongodb`            | Sim             | Sim             |
| `rabbitmq`           | Sim             | Sim             |
| `redis`              | Sim             | —               |
| `multi_tenant_redis` | Só multi-tenant | Só multi-tenant |
| `tenant_manager`     | Só multi-tenant | Só multi-tenant |
| `s3`                 | —               | Sim             |

Em modo multi-tenant, as entradas de MongoDB e RabbitMQ compartilhados reportam `n/a` com o motivo `multi-tenant: see /readyz/tenant/:id`, e as sondas por tenant passam para esse endpoint.

### Tempos limite por dependência

Cada sonda roda sob um prazo fixo. Os valores não são configuráveis, então todo serviço Lerian tem o mesmo envelope de latência de prontidão, e um único limiar de painel funciona para toda a frota.

| Classe de dependência                                                   | Prazo |
| ----------------------------------------------------------------------- | ----- |
| Bancos de dados (`mongodb`, `postgres`, `mysql`, `oracle`, `sqlserver`) | 2s    |
| Cache (`redis`, `valkey`)                                               | 1s    |
| Fila (`rabbitmq`)                                                       | 2s    |
| Armazenamento (`s3`, `seaweedfs`)                                       | 2s    |
| Upstreams HTTP (`tenant_manager`, `upstream_*`)                         | 1s    |

Uma sonda que ignora o prazo dela não trava a resposta. O handler substitui o resultado dela por `down`.

## Estado do circuit breaker

***

A resolução de tenant roda atrás de um circuit breaker. A variável `MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD` define quantas falhas consecutivas o abrem, e o padrão dela é 5. A variável `MULTI_TENANT_CIRCUIT_BREAKER_TIMEOUT_SEC` define quanto tempo ele fica aberto, e o padrão dela é 30 segundos.

Quando o breaker está aberto, a sonda por tenant reporta a dependência como `down`, com o erro `circuit breaker open` e o estado de breaker `open`. Isso distingue um breaker acionado de uma falha comum de conexão, que é a diferença entre esperar um reset e acionar o dono do banco de dados.

## Drenagem em SIGTERM

***

Em `SIGTERM` ou `SIGINT`, os dois serviços entram em drenagem antes de derrubar as conexões.

1. O `/readyz` passa direto para 503 por `READYZ_DRAIN_DELAY_SEC` segundos, cujo padrão é 12 e cujo mínimo é 1.
2. O Kubernetes remove o pod dos endpoints do Service enquanto ele ainda atende o trabalho em voo.
3. Só então as conexões fecham.

O serviço pula as sondas reais durante a drenagem. A resposta carrega uma dependência sintética chamada `draining` com status `down`, e emite métricas como qualquer outra.

<Note>
  **Os alertas continuam avaliando durante um deploy contínuo.** A dependência sintética `draining` mantém a série de métricas viva, então um painel mostra uma drenagem em vez de uma lacuna. Defina o período de graça de término acima da janela de drenagem.
</Note>

## Métricas

***

O `/metrics` serve a exposição Prometheus, incluindo os coletores de runtime e de processo do Go.

| Métrica                    | Tipo       | Labels          | Reporta                                                                         |
| -------------------------- | ---------- | --------------- | ------------------------------------------------------------------------------- |
| `readyz_check_duration_ms` | histograma | `dep`, `status` | Duração de cada sonda de prontidão, em milissegundos.                           |
| `readyz_check_status`      | contador   | `dep`, `status` | Contagem de resultados por dependência e status.                                |
| `selfprobe_result`         | gauge      | `dep`           | Último resultado da autossondagem de inicialização: `1` para up, `0` para down. |

Os buckets do histograma vão de 1 ms a 5.000 ms. Nomes de métricas, labels e buckets são um contrato de plataforma, e painéis de toda a frota dependem deles.

O histograma de duração registra o tempo de relógio que a sonda contribuiu para o handler, e não a latência que a sonda reportou para si mesma. É esse o número que explica um `/readyz` lento.

## Tracing

***

Defina `ENABLE_TELEMETRY=true` e aponte `OTEL_EXPORTER_OTLP_ENDPOINT` para o seu coletor. O Fetcher então exporta traces e métricas OpenTelemetry por OTLP.

Quatro atributos de recurso moldam o que você vê: `OTEL_RESOURCE_SERVICE_NAME` (`fetcher` no Manager, `fetcher-worker` no Worker), `OTEL_RESOURCE_SERVICE_VERSION`, `OTEL_RESOURCE_DEPLOYMENT_ENVIRONMENT` e `OTEL_LIBRARY_NAME`.

O Engine emite os próprios spans por uma porta de um método só. Um hospedeiro que não fornece um tracer recebe um no-op, e o comportamento não muda.

## O que alertar

***

1. **`/readyz` em 503 fora de uma janela de deploy.** Um nome de dependência no corpo da resposta diz qual é.
2. **Uma dead-letter queue crescendo.** Cada mensagem ali é um job que o Worker não conseguiu processar. Veja [Implantação](/pt/fetcher/fetcher-deployment).
3. **`selfprobe_result` em 0 para qualquer dependência.** Um pod reiniciou sobre uma dependência quebrada.
4. **Estado de breaker `open` no `tenant_manager`.** A resolução de tenant falha, e toda requisição com escopo de tenant depende dela.

## Próximos passos

***

<CardGroup cols={2}>
  <Card title="Implantação" icon="server" href="/pt/fetcher/fetcher-deployment">
    Dependências, filas, escala e checagens de inicialização.
  </Card>

  <Card title="Configuração" icon="gear" href="/pt/fetcher/fetcher-configuration">
    Cada variável de ambiente, por componente.
  </Card>

  <Card title="Segurança" icon="shield" href="/pt/fetcher/fetcher-security">
    Chaves, assinatura, criptografia em repouso e validação de host.
  </Card>

  <Card title="Jobs de extração" icon="list-check" href="/pt/fetcher/fetcher-extraction-jobs">
    Ciclo de vida do job, estados terminais e eventos.
  </Card>
</CardGroup>
