← Todos os casos
Operar

Alerta que não chega a ninguém não existe: monitoramento de serviços críticos

38/38alertas de teste entregues depois de religar o roteamento

Monitorado no papel

Os produtos tinham Prometheus, Grafana e regras de alerta. Em qualquer checklist, estariam marcados como monitorados. O que me fez desconfiar foi uma API pública que ficou dez minutos fora do ar e quem percebeu foi um monitor externo, e não o nosso.

Resolvi seguir o caminho completo de um alerta, da métrica até uma pessoa recebendo a mensagem. Em vários clusters, a rota raiz do Alertmanager apontava para um receptor nulo: o alerta era avaliado e descartado. Num deles, 36 alertas ativos iam para o vazio. Um roteador de mensagens descartava em silêncio tudo de um produto porque o prefixo do nome tinha um ponto, e um canal ficou 113 dias vazio sem ninguém notar. Além disso, as regras eram quase todas de saturação, como CPU, disco e conexões. Um banco, uma fila ou um cache podia cair sem abrir incidente nenhum.

Medir o que o cliente usa

Comecei pelo que o cliente sente. Implantei o Blackbox Exporter para sondar a API pública a cada 30 segundos, com alerta crítico depois de dois minutos fora e rota direta para o NOC. Os manifestos ficaram versionados e o token do webhook em Secret, fora do Git.

Num produto em que o serviço crítico é a conexão das instâncias com o canal de mensagens, não existia métrica pronta. Criei o sinal a partir dos logs: um pipeline no Grafana Alloy que coleta só os eventos de conexão e desconexão, descartando cerca de 99% do volume na origem, e uma regra que detecta desconexão em massa.

Regras de queda, com cuidado

Escrevi regras de indisponibilidade para PostgreSQL, Redis, Dragonfly, RabbitMQ, Elasticsearch, MongoDB e Kafka nos diferentes produtos, configuradas para que a métrica sumir também conte como queda. Antes de ligar qualquer uma, medi a cobertura de 24 horas de cada sinal e as oscilações dos cinco dias anteriores, para que as regras novas não virassem ruído.

Numa delas, a conta não fechava. O alerta de broker do Kafka esperava três brokers fora, mas o cluster tinha cinco e um tópico interno com fator de replicação 1. Um único broker fora já era incidente. Corrigi o limiar e versionei as regras no Git do produto.

Provar que chega

Reescrevi o roteamento do Alertmanager com destinos separados para o NOC, o canal do produto e o chat do time, com os alertas críticos indo para o NOC e o ruído conhecido contido de propósito. Antes de aplicar, testei a matriz de roteamento com o amtool em 12 casos e, depois, conferi o log do operator.

No caminho, corrigi detalhes que matavam a entrega sem erro nenhum: o prefixo com ponto, um agrupamento que deixava o nome do alerta vazio para o roteador e uma rota que exigia um label com um espaço no final.

A prova final foi com alertas sintéticos: 38 disparos em quatro produtos, 38 entregues no chat e no canal do produto e a contagem batendo um a um no NOC. Na auditoria seguinte, ainda encontrei uma regressão: um webhook que eu tinha validado dias antes tinha deixado de existir no gateway do NOC. Ficou documentado e corrigido.

Por fim, eliminei um falso positivo recorrente (uma regra que, sem dados, mantinha o último estado e ficava travada em disparo depois que o problema já tinha passado) e padronizei o nome de todas as regras com o prefixo do produto em quatro clusters, por script, preservando os labels de roteamento.

O que mudou

A queda de qualquer banco, fila ou cache principal passou a abrir incidente, o que antes não acontecia em vários produtos. Os alertas que eram descartados passaram a chegar a três destinos, com a entrega comprovada por teste. A API pública ganhou o próprio monitoramento de disponibilidade.

O que eu levo disso

Um alerta só existe quando alguém o recebe. Criar a regra é a parte fácil; o monitoramento é o caminho inteiro até uma pessoa, testado. Por isso nenhuma mudança de roteamento minha foi validada com "a configuração parece certa".

E regra de saturação não substitui regra de queda. Um banco a 50% de CPU está bem. Um banco que sumiu também não está saturado.