Alertar por consumo de error budget
Ao final deste guia, o alerta do seu serviço dispara quando o usuário está sendo afetado numa velocidade que importa — e para de disparar por picos irrelevantes de madrugada.
1. Entenda por que o limiar fixo falha
Seção intitulada “1. Entenda por que o limiar fixo falha”taxa_de_erro > 5% por 5 minutos erra dos dois lados. De madrugada, com 20 requisições no
período, uma falha vira 5% e acorda alguém à toa. No pico, 2% de erro sustentado por três
horas passa despercebido — e consome mais orçamento que qualquer pico curto.
O burn rate resolve porque mede velocidade de consumo do orçamento de erro, e não um número solto.
2. Defina o SLI e o SLO
Seção intitulada “2. Defina o SLI e o SLO”O SLI precisa medir o que o usuário sente. Para uma API, a proporção de requisições bem-sucedidas:
sum(rate(http_requests_total{service="loja", status!~"5.."}[5m])) / sum(rate(http_requests_total{service="loja"}[5m]))Com SLO de 99,9% mensal, o orçamento de erro é 0,1% — cerca de 43 minutos de falha
total por mês. Esse 0,001 é o denominador de tudo que vem a seguir.
Exclua do SLI o que não é responsabilidade do serviço (erros 4xx de cliente, por exemplo) — mas documente a exclusão, porque ela é uma decisão discutível.
3. Pré-calcule as taxas com recording rules
Seção intitulada “3. Pré-calcule as taxas com recording rules”Alerta não pode depender de consulta cara: no incidente, o Prometheus está sob pressão.
groups: - name: slo-loja-gravacao interval: 30s rules: - record: slo:erro:ratio_rate5m expr: | sum(rate(http_requests_total{service="loja", status=~"5.."}[5m])) / sum(rate(http_requests_total{service="loja"}[5m])) - record: slo:erro:ratio_rate1h expr: | sum(rate(http_requests_total{service="loja", status=~"5.."}[1h])) / sum(rate(http_requests_total{service="loja"}[1h])) - record: slo:erro:ratio_rate30m expr: | sum(rate(http_requests_total{service="loja", status=~"5.."}[30m])) / sum(rate(http_requests_total{service="loja"}[30m])) - record: slo:erro:ratio_rate6h expr: | sum(rate(http_requests_total{service="loja", status=~"5.."}[6h])) / sum(rate(http_requests_total{service="loja"}[6h])) - record: slo:erro:ratio_rate3d expr: | sum(rate(http_requests_total{service="loja", status=~"5.."}[3d])) / sum(rate(http_requests_total{service="loja"}[3d]))4. Escolha as janelas e os multiplicadores
Seção intitulada “4. Escolha as janelas e os multiplicadores”Burn rate é quantas vezes mais rápido que o previsto você está gastando o orçamento. Taxa 1 consome o mês inteiro em um mês; taxa 14,4 consome 2% do orçamento em uma hora.
| Gravidade | Burn rate | Janelas | Consome | Destino |
|---|---|---|---|---|
| Rápida | 14,4× | 1h e 5m | 2% em 1h | página |
| Média | 6× | 6h e 30m | 5% em 6h | página (horário comercial) |
| Lenta | 1× | 3d e 6h | 10% em 3d | ticket |
O par de janelas é o truque que evita ruído: a janela longa confirma o problema, a curta garante que ele ainda está acontecendo — sem ela, o alerta continua tocando depois de resolvido.
5. Escreva as regras
Seção intitulada “5. Escreva as regras”groups: - name: slo-loja-alertas rules: - alert: LojaBurnRateRapida expr: | (slo:erro:ratio_rate1h > 14.4 * 0.001) and (slo:erro:ratio_rate5m > 14.4 * 0.001) for: 2m labels: { severity: page, service: loja } annotations: summary: "Loja consumindo orçamento de erro 14x acima do previsto" description: "Erro em 1h: {{ $value | humanizePercentage }}. SLO 99,9%." runbook: "https://portal.exemplo.com/guias/kubernetes/rollback-deploy/"
- alert: LojaBurnRateLenta expr: | (slo:erro:ratio_rate6h > 6 * 0.001) and (slo:erro:ratio_rate30m > 6 * 0.001) for: 15m labels: { severity: ticket, service: loja } annotations: summary: "Degradação persistente no serviço loja"Substitua 0.001 pelo orçamento do seu SLO (99,5% → 0.005; 99,95% → 0.0005).
Toda regra que pagina precisa de um runbook na anotação. Alerta sem runbook não está
pronto.
6. Valide contra incidentes passados
Seção intitulada “6. Valide contra incidentes passados”Esta é a etapa que dá confiança — e a mais pulada.
promtool check rules regras-slo.yamlpromtool test rules testes-slo.yaml # casos de teste com séries sintéticasDepois, olhe para trás: pegue dois ou três incidentes reais dos últimos meses e verifique na interface do Prometheus se a expressão teria disparado, e quando. Faça o mesmo com um período tranquilo, para confirmar que ela não dispararia.
# quanto do orçamento mensal já foi consumido — bom painel ao lado do alerta1 - ( sum(increase(http_requests_total{service="loja", status!~"5.."}[30d])) / sum(increase(http_requests_total{service="loja"}[30d]))) / 0.0017. Roteie por severidade
Seção intitulada “7. Roteie por severidade”route: group_by: [alertname, service] routes: - matchers: [severity="page"] receiver: plantao - matchers: [severity="ticket"] receiver: fila-do-timeSe der errado
Seção intitulada “Se der errado”| Sintoma | Causa provável |
|---|---|
| Nunca dispara | Multiplicador ou orçamento errado; teste com promtool |
| Dispara sem impacto | 4xx entrando no SLI, ou serviço com tráfego baixo demais |
| Continua tocando após resolver | Faltou a janela curta no and |
$value estranho na notificação |
A expressão devolve proporção, não porcentagem |
| Alerta some no incidente | Consulta cara sem recording rule |
Serviço com pouco tráfego é o caso difícil: com dezenas de requisições por hora, qualquer proporção é ruidosa. Ali, alerte por contagem absoluta de erros ou por disponibilidade medida com sonda sintética.
Checklist de pronto
Seção intitulada “Checklist de pronto”- SLI medindo sintoma do usuário, com exclusões documentadas.
- SLO acordado com produto e escrito.
- Recording rules para todas as janelas usadas.
- Duas janelas por alerta, rápida e lenta separadas por severidade.
- Runbook na anotação de toda regra que pagina.
- Regras testadas com
promtoole conferidas contra incidentes passados. - Painel de orçamento consumido publicado.