Prometheus e PromQL: consultas e alertas que valem plantão
Objetivos desta aula
- Escrever PromQL de taxa e percentil
- Criar regras de alerta por sintoma
- Configurar roteamento no Alertmanager
Prometheus coleta métricas por scrape e armazena séries temporais. Em PromQL, a função rate calcula taxa por segundo de contadores, histogram_quantile estima percentis a partir de buckets e agregações por label permitem ver o comportamento por rota ou por serviço.
Alerta bom é alerta que exige ação humana e descreve o impacto no usuário: 'taxa de erro 5xx acima de 2% por 5 minutos' vale acordar alguém; 'CPU em 85%' normalmente não, porque pode ser saudável. Use for para evitar alarme por pico transitório e severidade coerente com urgência.
No Alertmanager, agrupe alertas relacionados, defina inibição (não alertar sobre sintoma quando a causa já disparou) e rotas por severidade. Fadiga de alerta é falha de engenharia: se o time ignora notificação, o sistema de alerta está quebrado.
1. Como o Prometheus funciona
Ele puxa (scrape) métricas de endpoints /metrics em intervalos, guarda em um banco de séries temporais e avalia regras de alerta. No Kubernetes, o kube-prometheus-stack descobre alvos via ServiceMonitor.
2. Tipos de métrica
- Counter: só sobe (requisições totais) — use sempre com
rate() - Gauge: sobe e desce (memória em uso)
- Histogram: distribui valores em buckets para calcular percentis
3. PromQL essencial
rate(x[5m]) dá a taxa por segundo; sum by (route) agrega; histogram_quantile(0.95, …) calcula o p95. Média de latência esconde problemas — alerte em percentis.
4. Alertas que valem plantão
Alerte em sintomas que o usuário sente (erro, lentidão), não em causas (CPU alta). Todo alerta precisa de: for para evitar ruído, severidade, e link para runbook. Se ninguém precisa agir, não é alerta, é dashboard.
5. Alertmanager
Agrupa, deduplica, silencia e roteia: crítico vai para o plantão (PagerDuty/Opsgenie), aviso vai para o chat.
Na prática
PromQL essencial para o CloudShop
promql
# Requisicoes por segundo por rota
sum(rate(http_request_duration_seconds_count[5m])) by (route)
# Taxa de erro (proporcao de 5xx)
sum(rate(http_request_duration_seconds_count{status=~"5.."}[5m]))
/ sum(rate(http_request_duration_seconds_count[5m]))
# Latencia p95 por rota
histogram_quantile(0.95,
sum(rate(http_request_duration_seconds_bucket[5m])) by (le, route))
# Saturacao de memoria do pod contra o limite
sum(container_memory_working_set_bytes{pod=~"cloudshop-api.*"}) by (pod)
/ sum(kube_pod_container_resource_limits{resource="memory",pod=~"cloudshop-api.*"}) by (pod)
# Consumo do error budget de 30 dias (SLO 99.9%)
1 - (sum(rate(http_request_duration_seconds_count{status!~"5.."}[30d]))
/ sum(rate(http_request_duration_seconds_count[30d]))) / 0.001Regras de alerta por sintoma
yaml
groups:
- name: cloudshop-api
rules:
- alert: TaxaDeErroAlta
expr: |
sum(rate(http_request_duration_seconds_count{status=~"5.."}[5m]))
/ sum(rate(http_request_duration_seconds_count[5m])) > 0.02
for: 5m
labels: { severity: critical }
annotations:
summary: "Mais de 2% das requisicoes falhando"
description: "Usuarios estao recebendo erro. Runbook: docs/runbooks/api-5xx.md"
- alert: LatenciaP95Degradada
expr: |
histogram_quantile(0.95,
sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) > 1
for: 10m
labels: { severity: warning }
annotations:
summary: "p95 acima de 1s por 10 minutos"
- alert: ErrorBudgetQueimandoRapido
expr: |
(sum(rate(http_request_duration_seconds_count{status=~"5.."}[1h]))
/ sum(rate(http_request_duration_seconds_count[1h]))) > 14.4 * 0.001
for: 5m
labels: { severity: critical }
annotations:
summary: "Consumo acelerado do error budget (burn rate 14.4x)"Nota de segurança: Anotações de alerta vão para canais de chat: não inclua dado de cliente nem trecho de log sensível.
Consultas PromQL do dia a dia
promql
# requisições por segundo por rota
sum by (route) (rate(http_requests_total{service="api"}[5m]))
# taxa de erro 5xx
sum(rate(http_requests_total{service="api",status=~"5.."}[5m]))
/ sum(rate(http_requests_total{service="api"}[5m]))
# latência p95
histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket{service="api"}[5m])))Regra de alerta com runbook
yaml
groups:
- name: cloudshop-api
rules:
- alert: ApiHighErrorRate
expr: |
sum(rate(http_requests_total{service="api",status=~"5.."}[5m]))
/ sum(rate(http_requests_total{service="api"}[5m])) > 0.05
for: 10m # evita alertar por picos de segundos
labels: { severity: critical }
annotations:
summary: "API com mais de 5% de erros"
runbook_url: https://github.com/cloudshop/runbooks/blob/main/api-errors.mdPor que isso importa
Alerta acionável e runbook vinculado é o que torna plantão sustentável.
Erro comum
Alertar em CPU e disco e não alertar em taxa de erro percebida pelo usuário.
Dica de produção
Todo alerta crítico deve ter link para runbook com passos de diagnóstico e mitigação.
Pergunta de entrevista
Como você definiria alertas para um serviço novo sem histórico?
Glossário
- rate
- Função PromQL que calcula taxa por segundo de um contador.
- burn rate
- Velocidade de consumo do error budget em relação ao permitido.
- Scrape
- Coleta periódica das métricas expostas por um alvo.
- Counter
- Métrica que só aumenta; lida com rate().
- Percentil p95
- Valor abaixo do qual estão 95% das medições.
Conexão com o CloudShop
Criar as regras de alerta do CloudShop com runbook vinculado.
Quiz da aula
1. Qual alerta é mais acionável?
2. Como consultar um counter corretamente?
3. Para que serve o 'for: 10m' num alerta?
Minhas anotações
Salvo automaticamente neste navegador.