Grafana OnCall: plantão e escalonamento de alertas

Grafana OnCall é a solução open-source de on-call do Grafana Labs, alternativa ao PagerDuty e OpsGenie. Gerencia rotações de plantão, regras de escalonamento (se ninguém responde em 5 minutos, avisar o próximo), silêncios agendados para manutenções e integra diretamente com Prometheus Alertmanager.

Instalar Grafana OnCall self-hosted

Deploy do OnCall com Docker Compose:

yaml
# docker-compose.yml — Grafana + OnCall:
services:
  grafana:
    image: grafana/grafana-oss:latest
    environment:
      GF_SECURITY_ADMIN_PASSWORD: "SUA_SENHA"
      GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: "grafana-oncall-app"
      GF_INSTALL_PLUGINS: "grafana-oncall-app"
    volumes:
      - grafana-data:/var/lib/grafana
    ports:
      - "127.0.0.1:3000:3000"

  oncall-engine:
    image: grafana/oncall:latest
    restart: always
    environment:
      DATABASE_TYPE: sqlite3
      BROKER_TYPE: redis
      BASE_URL: http://oncall-engine:8080
      SECRET_KEY: "SUA_SECRET_KEY_LONGA_AQUI"
      REDIS_URI: redis://redis:6379/0
      DJANGO_SETTINGS_MODULE: settings.hobby
    depends_on:
      - redis

  oncall-celery:
    image: grafana/oncall:latest
    restart: always
    command: "celery -A engine worker -l info"
    environment:
      DATABASE_TYPE: sqlite3
      BROKER_TYPE: redis
      REDIS_URI: redis://redis:6379/0
      SECRET_KEY: "SUA_SECRET_KEY_LONGA_AQUI"
    depends_on:
      - redis

  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data

volumes:
  grafana-data:
  redis-data:

Configurar integração com Alertmanager

Conectar o Prometheus Alertmanager ao OnCall:

yaml
# 1. No Grafana OnCall UI:
#    Integrations → New Integration → Alertmanager
#    Copiar a URL de integração gerada:
#    https://oncall.seudominio.com.br/api/v1/integrations/INTEGRATION_ID/...

# 2. alertmanager.yml — adicionar receiver OnCall:
receivers:
  - name: 'grafana-oncall'
    webhook_configs:
      - url: 'https://oncall.seudominio.com.br/integrations/v1/alertmanager/TOKEN/'
        send_resolved: true

route:
  receiver: 'grafana-oncall'
  group_by: ['alertname', 'severity']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    # Críticos → OnCall (acorda a equipe)
    - match:
        severity: critical
      receiver: 'grafana-oncall'
      continue: false
    # Warnings → Slack apenas
    - match:
        severity: warning
      receiver: 'slack-warning'

# 3. Verificar integração:
# OnCall UI → Integrations → Status deve mostrar "Connected"
# Enviar alerta de teste para verificar recebimento

Criar escalation chains

Configurar regras de escalonamento para garantir que alguém responda:

bash
# Configuração via Grafana OnCall UI:

# Escalation Chain "API Crítica":
# 1. Notificar via Telegram (imediato)
# 2. Se não reconhecido em 5 min → notificar via ligação
# 3. Se não reconhecido em 15 min → notificar equipe completa no Slack
# 4. Se não reconhecido em 30 min → escalar para gerência

# API do OnCall para configurar programaticamente:
# POST /api/v1/escalation_chains/
curl -X POST   -H "Authorization: Token SEU_TOKEN_API"   -H "Content-Type: application/json"   https://oncall.seudominio.com.br/api/v1/escalation_chains/   -d '{
    "name": "api-critica-chain",
    "team_id": "SEU_TEAM_ID"
  }'

# Adicionar passos à chain:
curl -X POST   -H "Authorization: Token SEU_TOKEN_API"   -H "Content-Type: application/json"   https://oncall.seudominio.com.br/api/v1/escalation_policies/   -d '{
    "escalation_chain_id": "CHAIN_ID",
    "type": "notify_on_call_from_schedule",
    "position": 0,
    "notify_on_call_from_schedule": "SCHEDULE_ID"
  }'

# Tipos de step disponíveis:
# - notify_person: notificar pessoa específica
# - notify_on_call_from_schedule: notificar quem está de plantão
# - wait: aguardar N minutos antes do próximo step
# - notify_whole_channel: notificar canal Slack/Telegram
# - trigger_webhook: chamar URL customizada

Rotações de plantão e cronograma

Criar rotação semanal automatizada de on-call:

bash
# Schedules no OnCall — rotação de plantão:

# Via UI: OnCall → Schedules → Create Schedule

# Rotação semanal (cada pessoa fica 1 semana):
# Type: Rolling users
# Rotation end: nunca (recorrente)
# Users: [Leandro, Maria, João]
# Frequency: weekly
# Shift start: segunda-feira 09:00 (horário de Brasília)

# Rotação com cobertura diferente por horário:
# Plantão diurno (seg-sex 09h-18h): Equipe A
# Plantão noturno (seg-sex 18h-09h): Equipe B
# Plantão fim de semana: rotação mensal

# API para criar schedule:
curl -X POST   -H "Authorization: Token SEU_TOKEN_API"   https://oncall.seudominio.com.br/api/v1/schedules/   -d '{
    "name": "Plantão API",
    "type": "ical",
    "ical_url_primary": "https://calendar.google.com/calendar/ical/...",
    "slack": {"channel_id": "C12345", "user_group_id": "S12345"},
    "enable_web_overrides": true
  }'

# Override temporário (trocar plantão para um dia específico):
# UI: Schedules → clicar no dia → Criar override
# Útil para férias ou compromissos

# Verificar quem está de plantão agora:
curl -H "Authorization: Token SEU_TOKEN_API"   https://oncall.seudominio.com.br/api/v1/schedules/SCHEDULE_ID/next_shifts/

Configurar notificações por Telegram

Receber alertas de plantão no Telegram pessoal:

bash
# Configurar Telegram como canal de notificação pessoal:

# 1. Criar bot no Telegram:
#    → Abrir @BotFather no Telegram
#    → /newbot → nome: "Runstack OnCall" → username: runstack_oncall_bot
#    → Salvar o token: 7123456789:AAF...

# 2. No OnCall: Settings → Telegram Integration
#    Inserir o TELEGRAM_TOKEN do bot

# 3. Cada usuário conecta sua conta:
#    OnCall → Profile → Notification rules → Add Telegram
#    Abrir o bot no Telegram e enviar /start
#    → Bot confirma a conexão com o OnCall

# 4. Regras de notificação por usuário (OnCall → Profile):
# Para alertas críticos (severity=critical):
#   1. Telegram (imediato)
#   2. Aguardar 3 minutos
#   3. Ligação (se integrado com Twilio)
#
# Para alertas de warning:
#   1. Telegram apenas

# 5. Testar: OnCall → Integrations → Test Integration
#    Deve receber mensagem no Telegram em segundos

# Formato da mensagem Telegram:
# 🔴 ALERTA CRITICO
# 📌 ApiAltaTaxaErros
# 🌍 Serviço: nodejs-api | Ambiente: production
# 📋 Taxa de erros acima de 5%: 8.3%
# ⏰ Iniciado: 08/06/2026 02:34
# [🔗 Ver no Grafana] [✅ Reconhecer] [🔇 Silenciar 30min]

Não quer configurar manualmente?

Implante o VPS para Node.js em menos de 5 minutos com a Runstack. Infraestrutura da OPEN Datacenter, com servidores em São Paulo.

Perguntas frequentes

PagerDuty: produto maduro e battle-tested, integrações com centenas de ferramentas, SLA de 99.99%, suporte enterprise, compliance (SOC2, HIPAA). Caro: ~$20-30/usuário/mês. Grafana OnCall: open-source, self-hosted grátis, integração nativa com Grafana/Prometheus, menos features avançadas. Grafana Cloud OnCall tem plano gratuito para times pequenos. Para startups e equipes até 10 pessoas: OnCall. Para enterprise com compliance e 24/7 crítico: PagerDuty vale o investimento.

Depende da criticidade: para sistemas de pagamento ou saúde (critical): resposta em 5 minutos, resolução em 30 minutos. Para SaaS B2B (critical): resposta em 15 minutos, resolução em 1 hora. Para sistemas não críticos (warning): resposta no próximo dia útil. A escalation chain deve refletir essas expectativas: se em 5 minutos sem resposta → próximo passo. Configure o "resolve timeout" no Alertmanager alinhado com o SLO de MTTR (Mean Time to Resolve).

Calibre os thresholds: um alerta que dispara mais de 3 vezes por semana sem ser um problema real é um falso positivo, ajuste o threshold ou o for (duração mínima). Use inhibit_rules para inibir alertas derivados. Configure silêncio recorrente para manutenções planejadas. Revise alertas semanalmente: se um alerta acordou alguém mas não havia nada a fazer, o alerta está mal configurado. Alerta ruim é pior que nenhum alerta, treina a equipe a ignorar.

Para a UI e engine: sim, funciona self-hosted sem acesso externo. Para notificações: depende do canal. Telegram/Slack/email requerem acesso externo (APIs de terceiros). Para ambientes sem internet: use webhook para um sistema interno de notificação (Gotify, ntfy.sh self-hosted) ou integração com sistemas de mensageria internos (Mattermost, Rocket.Chat). O OnCall suporta webhooks customizados que podem apontar para qualquer endpoint interno.

Tecnicamente 1 pessoa pode receber todos os alertas. Para rotação saudável: mínimo 3-4 pessoas para cobrir férias e folgas sem esgotar ninguém. Com 2 pessoas: plantão alternado semana sim/não, sustentável por curto prazo. Para cobertura noturna e fins de semana em produtos críticos: equipe maior ou compensação específica para plantão fora do horário comercial. Comece com alertas apenas em horário comercial (usando silêncio recorrente) e expanda conforme o produto cresce.