Monitoramento e Observabilidade¶
Este documento detalha a arquitetura, provisionamento e operação da stack de monitoramento e observabilidade da Page Saúde.
Visão Geral¶
A solução de observabilidade segue um modelo distribuído com coleta centralizada:
- Agentes (Grafana Alloy): Instalados em cada servidor, coletam métricas, logs e traces locais
- Gateway (Alloy Gateway): Ponto central de recepção de telemetria na stack de operações
- Backends: Armazenamento especializado por tipo de dado (Prometheus, Loki, Tempo, Pyroscope)
- Visualização: Grafana como interface unificada
Protocolo¶
Toda a comunicação de telemetria utiliza o padrão OpenTelemetry (OTLP), garantindo interoperabilidade e flexibilidade na instrumentação de aplicações.
Arquitetura¶
flowchart LR
subgraph SERVERS["Servidores de Aplicação/Banco"]
APP["Aplicações"]
AGENT["Alloy Agent<br/>:4317/:4318"]
APP -->|OTEL SDK| AGENT
end
subgraph OPS["Stack de Operações (VM Monitoring)"]
GW["Alloy Gateway<br/>:4317/:4318/:4380"]
PROM["Prometheus<br/>(Métricas)"]
LOKI["Loki<br/>(Logs)"]
TEMPO["Tempo<br/>(Traces)"]
PYRO["Pyroscope<br/>(Profiling)"]
GRAF["Grafana<br/>(Interface)"]
GW --> PROM
GW --> LOKI
GW --> TEMPO
GW --> PYRO
GRAF --> PROM
GRAF --> LOKI
GRAF --> TEMPO
GRAF --> PYRO
end
AGENT -->|OTLP| GW
Componentes¶
Grafana Alloy Agent¶
Coletor leve instalado em cada servidor. Responsável por:
- Métricas de Host: CPU, memória, disco, rede (via
node_exporterintegrado) - Métricas de Containers: cAdvisor embutido no Alloy (métricas
container_*) - Logs de Containers: Coleta via Docker socket (filtrado por label)
- Métricas de Serviços: PostgreSQL, Redis, Apache (quando habilitado)
- Logs de Serviços: Apache access/error logs (quando habilitado)
- Receiver OTLP: Recebe traces e métricas de aplicações instrumentadas
Localização: services/observability/agent/
Alloy Gateway¶
Ponto central de recepção na stack de operações. Funções:
- Receber telemetria dos agentes remotos
- Rotear dados para os backends apropriados
- Processar e enriquecer atributos
Endpoints expostos:
| Porta | Protocolo | Uso |
| :--- | :--- | :--- |
| 4317 | gRPC OTLP | Traces, Métricas, Logs |
| 4318 | HTTP OTLP | Traces, Métricas, Logs |
| 4380 | HTTP | Pyroscope (Profiling) |
Backends de Armazenamento¶
| Componente | Função | Retenção Padrão |
|---|---|---|
| Prometheus | Métricas (TSDB) | 7 dias / 5GB |
| Loki | Logs estruturados | 7 dias |
| Tempo | Traces distribuídos | 7 dias |
| Pyroscope | Profiling contínuo | 7 dias / 1GB min free |
Grafana¶
Interface unificada de visualização com datasources pré-configurados para todos os backends. Inclui:
- Dashboards provisionados automaticamente
- Alertas configuráveis
- Exploração de logs, traces e métricas correlacionados
O Grafana Image Renderer não é provisionado: a VM de operações tem orçamento de memória restrito. Retomar a avaliação quando houver pelo menos 16 GiB de memória e 4 CPUs disponíveis para o renderer, além da necessidade confirmada de imagens em alertas ou relatórios.
Provisionamento¶
Stack Centralizada¶
Provisionada automaticamente em hosts com with_monitoring_stack: true:
# ansible/inventory/ops.yml
ops_servers:
hosts:
ops-pagesaude-monitor-01:
with_monitoring_stack: true
Role Ansible: monitoring → tasks/stack.yml
Agente de Monitoramento¶
Provisionado automaticamente em todos os hosts. A configuração de coleta é controlada por flags:
| Flag | Descrição | Efeito |
|---|---|---|
with_postgres |
Provisiona PostgreSQL | Auto-habilita monitor_postgres |
with_redis |
Provisiona Redis | Auto-habilita monitor_redis |
monitor_apache |
Monitora Apache existente | Habilita métricas e logs Apache |
Exemplo de Inventário:
db_servers:
hosts:
prod-pagesaude-db-01:
with_postgres: true # Provisiona PG + habilita monitoramento
monitor_postgres: true # Ou apenas habilita monitoramento (PG externo)
postgres_host: "host.docker.internal"
postgres_port: 15432
Role Ansible: monitoring → tasks/agent.yml
Variáveis de Ambiente do Agente¶
Geradas automaticamente pelo Ansible em .env:
| Variável | Descrição |
|---|---|
ENVIRONMENT |
Ambiente de deploy (prod, stg, local) |
NODE_HOSTNAME |
Hostname do servidor |
OTELCOL_EXPORTER_OTLP_ENDPOINT |
Endpoint do Gateway (host:4317) |
PYROSCOPE_WRITE_ENDPOINT |
Endpoint do Pyroscope |
POSTGRES_DATABASE_URL |
Connection string PostgreSQL (se habilitado) |
REDIS_URL |
Connection string Redis (se habilitado) |
Integração com Aplicações¶
Coleta de Logs (Passiva)¶
Para coletar logs de containers automaticamente, adicione a label:
labels:
monitoring.logs.enabled: "true"
O Alloy Agent detectará o container e coletará stdout/stderr via Docker socket.
Instrumentação com OpenTelemetry SDK¶
Para enviar traces e métricas customizadas, configure o SDK OTel da sua linguagem:
environment:
OTEL_SERVICE_NAME: meu-servico
OTEL_EXPORTER_OTLP_ENDPOINT: http://alloy-agent:4318
OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf
OTEL_PROPAGATORS: baggage,tracecontext
OTEL_RESOURCE_ATTRIBUTES: >
deployment.environment.name=prod,
service.namespace=pagesaude,
service.name=meu-servico,
service.type=backend
Referência: Consulte o ADR-0002: Padrão de Telemetria para a lista completa de atributos obrigatórios.
Observabilidade de Frontend (Grafana Faro)¶
O frontend usa o Grafana Faro Web SDK para RUM, erros JS e traces. A coleta entra via faro.receiver e é roteada no Alloy da stack de operações.
- Receiver:
services/observability/stack/config/alloy-faro.alloy - Logs: exceções chegam no Loki com
source="faro",kind="exception"e labelsapp_name,app_environment - Traces: enviados para o Tempo via OTLP
- Correlação: erros são associados ao trace ativo automaticamente quando há span em andamento
Dashboard: o painel de frontend é provisionado em services/observability/stack/config/grafana/dashboards/Application/frontend.json, com filtros por environment e application.
Profiling Contínuo¶
Para habilitar profiling com Pyroscope (linguagens suportadas: Go, Java, Python, Ruby, Node.js, .NET):
environment:
PYROSCOPE_APPLICATION_NAME: meu-servico
PYROSCOPE_SERVER_ADDRESS: http://alloy-agent:4380
Estrutura de Arquivos¶
services/observability/
├── agent/ # Agente (instalado em cada servidor)
│ ├── compose.yaml
│ ├── config/ # Configurações sempre carregadas
│ │ ├── logs.alloy # Coleta de logs Docker
│ │ ├── metrics.alloy # Métricas de host/containers
│ │ ├── otelcol.alloy # Receiver OTLP
│ │ └── profiling.alloy # Integração Pyroscope
│ └── extra/ # Configurações opcionais (symlink quando habilitado)
│ ├── apache.alloy
│ ├── postgres.alloy
│ └── redis.alloy
│
└── stack/ # Stack centralizada (VM de Operações)
├── compose.yaml
└── config/
├── alloy-gateway.alloy # Configuração do Gateway
├── alloy-faro.alloy # Receiver Faro (frontend) + pipeline Loki
├── prometheus.yaml # Configuração Prometheus
├── loki.yaml # Configuração Loki
├── tempo.yaml # Configuração Tempo
└── grafana/ # Provisioning Grafana
├── provisioning/
│ ├── datasources/
│ └── dashboards/
└── dashboards/ # JSON dos dashboards
Alertas e Notificações¶
As regras de alerta são avaliadas pelo Prometheus (arquivos versionados em
services/observability/stack/config/prometheus/alerts/) e entregues ao Alertmanager,
que agrupa, inibe e notifica. Os canais são configurados na UI do Grafana.
- Severidades, critérios e padrão de labels/annotations: alerting.md
- Configuração dos canais (webhook do Discord, SMTP): operation.md
- Runbooks: runbooks/
Disponibilidade externa (Cloudflare)¶
O monitoramento interno continua sendo responsabilidade da stack acima. Para confirmar a disponibilidade vista de fora, usar Cloudflare Health Checks (Pro) contra endpoints HTTPS de saúde das aplicações. Mudanças de estado seguem pelo serviço de Notifications da Cloudflare até um webhook do Discord; não há container, receiver ou credencial adicional na stack.
flowchart LR
CF[Cloudflare Health Checks Pro] -->|HTTPS| APP[Endpoint público /health]
CF -->|mudança de estado| N[Cloudflare Notifications]
N -->|webhook| D[Discord]
O Health Check é complementar aos alertas do Prometheus: ele detecta falhas de DNS, CDN, TLS, roteamento ou origem a partir da internet. A configuração e a rotação do webhook são operacionais; veja operation.md.