Alerting — Prometheus + Alertmanager¶
Documentação de referência para configuração e critérios de alertas core do ambiente.
Arquitetura¶
graph LR
P[Prometheus] -->|avalia regras e envia alertas| A[Alertmanager - Mimir]
A -->|notifica| D[Discord / E-mail]
G[Grafana] -->|cria contact points e policies| A
G -->|consulta| P
O Prometheus avalia todas as regras (arquivos versionados neste repositório) e entrega os alertas ao Alertmanager, que agrupa, inibe e notifica. Os canais de notificação são criados e mantidos na UI do Grafana (Alerting → Contact points / Notification policies), que grava direto na API de configuração do Alertmanager.
Por que o Alertmanager é o do Mimir¶
O Alertmanager interno do Grafana só processa alertas gerenciados pelo próprio Grafana. Usá-lo sozinho exigiria migrar para o Grafana as regras e a avaliação hoje mantidas no Prometheus. O Alertmanager vanilla recebe esses alertas, mas sua configuração fica somente leitura na UI. O Mimir preserva as regras nativas do Prometheus e oferece a API gravável necessária para administrar notificações no Grafana.
| Alternativa | Resultado |
|---|---|
| Alertmanager embutido do Grafana | Só recebe alertas gerenciados pelo Grafana; exigiria migrar as regras e a avaliação. |
Alertmanager vanilla (prom/alertmanager) |
Recebe alertas normalmente, mas não tem API de escrita de configuração. A tela de Contact Points do Grafana fica somente leitura; canais só por arquivo. |
| Alertmanager do Mimir (adotado) | Recebe o formato padrão do Prometheus e expõe API de configuração gravável. A UI do Grafana cria contact points e notification policies normalmente. |
A tela de Contact Points do Grafana é a mesma nos três casos — o que muda é para onde ela grava. Só o Mimir aceita a escrita vinda de um Alertmanager externo.
O Grafana mantém seu Alertmanager interno como padrão do seletor e não oferece uma opção documentada para trocar esse padrão global. Na UI, selecione "Mimir (oficial)". A entrada "Grafana" continua visível, mas não é usada por este projeto.
Com isso é possível ter, tudo pela interface: vários canais do Discord com alertas distintos, múltiplos destinatários de e-mail por severidade, e um contact point com mais de uma integração.
O que é versionado e o que é da UI¶
| Item | Onde vive |
|---|---|
| Regras de alerta e SLO | prometheus/alerts/ e slo_rules.yml (git) |
| Estrutura inicial: agrupamento e inibições | config/alertmanager.yml (git) |
| Contact points, notification policies, templates | UI do Grafana (gravados no Alertmanager) |
| Webhooks e credenciais dos canais | UI do Grafana — nunca no repositório |
O alertmanager.yml só vale enquanto não houver configuração salva pela UI.
Depois da primeira gravação, a configuração da UI passa a ser a fonte de verdade.
Princípios: 1. Prometheus é o único motor de avaliação — nenhuma regra de alerta é criada na UI 2. O Alertmanager é o único responsável por notificação 3. SLOs e Error Budget vivem exclusivamente no Prometheus (recording rules versionadas) 4. Alertas devem ser determinísticos, acionáveis e com owner definido 5. Todo alerta referencia um runbook real em docs/runbooks/ 6. Nenhuma credencial de canal entra no repositório
Severidades¶
| Severidade | Impacto | Ação | Tempo de Resposta |
|---|---|---|---|
| P0 | Crítico — serviço indisponível | Imediata | Minutos |
| P1 | Grave — serviço degradado | Rápida | Horas |
| P2 | Risco — tendência de problema | Planejada | Horário comercial |
P0 — Incidente Crítico¶
Impacto imediato, total ou quase total.
Critérios (qualquer um): - Serviço indisponível para usuários - Perda de dados em andamento - Falha de infraestrutura crítica sem redundância - Violação grave de SLO em andamento
Exemplos: - Postgres fora do ar - API core não responde - 100% de erro HTTP - Host único crítico down - Filesystem readonly em produção
P1 — Incidente Grave¶
Serviço degradado com impacto significativo.
Critérios (qualquer um): - Erro ou latência acima do SLO por tempo sustentado - Capacidade comprometida sem queda total - Fast burn de Error Budget - Falha parcial em cluster ou réplica
Exemplos: - HTTP 5xx > 5% por 5 minutos - Latência P95 acima do SLO - Redis respondendo, mas com timeout frequente - CPU saturada causando throttling real - SLO fast burn (janela curta)
P2 — Risco Iminente¶
Sem impacto imediato, mas alto risco de incidente.
Critérios (qualquer um): - Tendência clara de esgotamento de recurso - Slow burn de Error Budget - Degradação progressiva - Falha tolerada temporariamente
Exemplos: - Disco > 85% com crescimento contínuo - Memória com leak gradual - Aumento constante de latência - SLO slow burn (janela longa) - Replicação de banco atrasada
Critérios por Domínio¶
Infra / Host¶
| Situação | Severidade |
|---|---|
| Host crítico down | P0 |
| Host não crítico down | P1 |
| CPU alta sem impacto | ❌ Não alertar |
| CPU saturada com throttling | P1 |
| Memória esgotando | P1 |
| Disco > 90% | P1 |
| Disco > 85% + tendência | P2 |
| Filesystem readonly | P0 |
| OOM Killer ativo | P1 |
Containers¶
| Situação | Severidade |
|---|---|
| Container crítico em crash loop | P0 |
| Container não crítico reiniciando | P2 |
| OOMKilled | P1 |
| CPU throttling severo | P1 |
| Restart esporádico | ❌ Não alertar |
Bancos de Dados¶
| Situação | Severidade |
|---|---|
| Banco fora do ar | P0 |
| Conexões esgotadas | P1 |
| Replicação parada | P1 (não aplicável hoje — topologia single-node) |
| Replicação atrasada | P2 (não aplicável hoje — topologia single-node) |
| Latência alta sustentada | P1 |
| Falha em backup | P2 |
Aplicação HTTP¶
| Situação | Severidade |
|---|---|
| 100% 5xx | P0 |
| 5xx > 5% sustentado | P1 |
| 5xx intermitente | P2 |
| Latência P95 acima do SLO | P1 |
| Latência P99 acima do SLO | P2 |
| Tráfego zerado inesperado | P0 |
SLO / Error Budget¶
| Situação | Severidade |
|---|---|
| Fast burn | P1 |
| Slow burn | P2 |
| Orçamento < 50% | P2 |
| Orçamento < 10% | P1 |
| Orçamento esgotado | P0 |
Padrão de Labels¶
Todo alerta DEVE ter:
labels:
severity: p0 | p1 | p2
layer: core
owner: sre | infra | backend
service: <nome-do-serviço>
environment: prod | stg
annotations:
summary: <frase curta em português: o que aconteceu e onde>
description: <detalhe técnico: métrica, limiar e janela>
impact: <consequência para usuários/negócio, em linguagem simples>
possible_causes: <hipóteses mais prováveis para acelerar o diagnóstico>
runbook: <URL real em https://docs-ops.pagesaude.com.br/runbooks/>
As annotations atendem os dois públicos: impact em linguagem de negócio,
description/possible_causes para o time técnico. Filtros de séries usam o label
canônico environment (ADR-0002) — nunca env.
Regras de Upgrade/Downgrade¶
Upgrade Automático¶
- P2 → P1: Se persistir > X minutos ou cruzar SLO
- P1 → P0: Se serviço ficar indisponível ou erro > 50%
Downgrade Automático¶
- Resolvido sem ação
- Impacto cessado
- Métrica normalizada
Critérios de Aceite¶
Um alerta só pode existir se: - Severidade definida por este documento - Existe ação clara - Existe owner - Impacto mensurável
Se dois engenheiros discordam da severidade, o alerta está mal definido. Ajuste o critério, não a severidade.
Estrutura de Arquivos¶
services/observability/stack/config/prometheus/
├── prometheus.yaml # Configuração principal (entrega ao Alertmanager)
├── slo_rules.yml # Recording rules de SLO
└── alerts/
├── core/
│ ├── host.rules.yml # Host: down, disco, memória, swap, CPU
│ ├── container.rules.yml # Containers (métricas cAdvisor)
│ └── telemetry.rules.yml # Coleta (Alloy agent)
├── databases/
│ ├── postgres.rules.yml
│ └── redis.rules.yml
├── application/
│ ├── http.rules.yml
│ └── latency.rules.yml
└── slo/
├── availability.rules.yml
└── latency.rules.yml
Anti-padrões (Proibidos)¶
- ❌ Regras de alerta criadas na UI do Grafana
- ❌ Alertas sem owner
- ❌ Alertas sem runbook
- ❌ Alertas baseados apenas em "uso alto"
- ❌ Duplicar alerta Prometheus + Grafana
- ❌ Alertas "informativos"