Encontrando a falha por trás de um dashboard verde
Uma migração de runtime deixou alertas sem corresponder a nada, silenciosamente. Controles positivos expuseram a correção incompleta.
Mudar apenas o tipo de recurso foi insuficiente; os filtros também precisavam corresponder a formatos de log específicos do runtime.
Contribuição em resumo
- Minha responsabilidade
- Inventário de alertas, correções de filtro cientes do runtime e validação por controle positivo.
- Escopo
- 22 alert policies e duas log-based metrics afetadas por uma migração de runtime.
- Colaboração & limites
- Reparei o caminho de monitoramento e verifiquei o logging da aplicação onde a mudança de filtro sozinha era insuficiente.
- Resultado
- Políticas e métricas reparadas contra mensagens de log conhecidas; mudar apenas o tipo de recurso ainda retornava zero correspondências.
O problema
Depois que as funções migraram para uma nova geração de runtime, os dashboards da aplicação ainda pareciam saudáveis. Mas o tipo de recurso e os rótulos dos logs tinham mudado, enquanto as alert policies e as log-based metrics ainda filtravam o formato anterior.
Uma auditoria identificou 22 políticas e duas métricas no escopo. Vinte e uma políticas estavam habilitadas, mas os filtros antigos já não conseguiam corresponder aos eventos pretendidos. A ausência de alertas tornara-se indistinguível da ausência de incidentes.
Minha contribuição
Rastreei o efeito da migração sobre os rótulos de recurso e os formatos de payload, auditei as políticas e as métricas relacionadas, apliquei as mudanças específicas do runtime e validei os novos filtros contra mensagens de log que se sabia existirem. Também verifiquei o caminho de logging da aplicação, onde mudar apenas o filtro não restauraria a visibilidade.
Por que a correção óbvia estava incompleta
Substituir o tipo de recurso parecia suficiente. Não era: algumas funções em Go emitiam JSON estruturado, enquanto funções em Python emitiam texto puro. Uma política que usava um campo de texto puro podia permanecer cega mesmo depois de seu filtro de recurso ser corrigido.
Outras políticas usavam uma expressão de busca que já correspondia a qualquer um dos formatos de payload. Tratar todos os filtros como iguais teria introduzido mudanças desnecessárias. Verifiquei cada formato em vez de aplicar uma substituição universal.
Resultados e medição
O registro de conclusão confirma 22 políticas e duas métricas corrigidas e verificadas. Uma varredura em todo o projeto não encontrou nenhuma política ou métrica remanescente usando o filtro de recurso obsoleto.
A comparação de cinco correspondências é um teste de controle positivo para uma mensagem conhecida específica. Ela demonstra por que a correção apenas do recurso era insuficiente; não é uma afirmação de que toda falha futura possível foi coberta. Alguns sinais foram deliberadamente deixados desabilitados onde eram redundantes, em vez de habilitar tudo indiscriminadamente.
Estender a cobertura ao fluxo de negócio
Em um acompanhamento à parte, descobri que dois escopos de verificação de alto volume estavam ausentes de um monitor que observava um escopo muito menor. O snapshot de produção registrado mostrava aproximadamente 128,000 documentos por dia nesses escopos antes não observados. Adicionei as verificações que faltavam e separei um escopo dormente, em vez de tratar um único total como prova de cobertura completa.
Esse volume diário descreve a observação usada para encontrar a lacuna. Não é uma contagem de verificações que falharam nem de incidentes evitados.
Distinguir ausência de eventos de estado ausente
Uma investigação posterior de batch-worker separou contadores de eventos vazios válidos de medidores de estado defeituosos. Um circuit breaker saudável ainda precisa publicar seu estado atual mesmo que nunca faça uma transição. O reparo também deu a cada réplica uma identidade de recurso do OpenTelemetry apropriada, em vez de mesclar seus dados em uma única série ambígua.
A validação em produção registrou zero erros de ordenação em uma janela de 3h28m, em comparação com erros que se repetiam a cada minuto antes da mudança. A mesma consulta retornou os erros anteriores como controle positivo. Painéis de eventos ainda podiam, legitimamente, não ter dados quando nenhum batch havia sido executado; o reparo não fabricou eventos para fazer um dashboard parecer populado.
O que eu aprendi
Um filtro que retorna zero linhas não é um resultado de validação enquanto não houver um evento conhecido que ele deveria corresponder. A aceitação de uma migração precisa de uma verificação de observabilidade que exercite payloads reais, não apenas um health endpoint bem-sucedido.
Decisões e próximos passos
Uma visão retrospectiva da abordagem e seus limites. A próxima melhoria é uma proposta, não um resultado entregue.
Alternativa e justificativa
Substituir apenas o tipo de recurso é mais simples, mas logs estruturados em Go e logs de texto puro em Python exigem correspondência de payload diferente.
Trade-off
Um dashboard silencioso não consegue distinguir uma aplicação saudável de um caminho de logging ou de alertas quebrado.
O que eu melhoraria em seguida
Próxima melhoria: automatizar verificações periódicas de controle positivo e incluir a compatibilidade de alertas nos critérios de aceitação de migração.