0 XP
Módulo 10 · Observabilidade e SRE

Prometheus e PromQL: consultas e alertas que valem plantão

Avançado 50 min+25 XPPrometheusPromQLAlertmanager

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.001

Regras 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.md

Por 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. 1. Qual alerta é mais acionável?

  2. 2. Como consultar um counter corretamente?

  3. 3. Para que serve o 'for: 10m' num alerta?

Minhas anotações

Salvo automaticamente neste navegador.

AnteriorPróxima