Pular para conteúdo

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_exporter integrado)
  • 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: monitoringtasks/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: monitoringtasks/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 labels app_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.

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.

Referências