Encontrar la falla detrás de un dashboard en verde
Una migración de runtime dejó, en silencio, alertas que no coincidían con nada. Los controles positivos revelaron la corrección incompleta.
Cambiar solo el tipo de recurso no bastaba; los filtros también debían coincidir con los formatos de log específicos del runtime.
Contribución de un vistazo
- Mi responsabilidad
- Inventario de alertas, reparación de filtros según el runtime y validación con controles positivos.
- Alcance
- 22 alert policies y dos log-based metrics afectadas por una migración de runtime.
- Colaboración y límites
- Reparé la ruta de monitoreo y revisé el logging de la aplicación donde cambiar solo el filtro no bastaba.
- Resultado
- Políticas y métricas reparadas contra mensajes de log conocidos; cambiar solo el tipo de recurso seguía devolviendo cero coincidencias.
El problema
Después de que las funciones pasaran a una nueva generación de runtime, los dashboards de la aplicación seguían viéndose sanos. Pero el tipo de recurso y las etiquetas de los logs habían cambiado, mientras que las alert policies y las log-based metrics seguían filtrando el formato anterior.
Una auditoría identificó 22 políticas y dos métricas en alcance. Veintiuna políticas estaban habilitadas, pero los filtros antiguos ya no podían coincidir con los eventos que debían detectar. La ausencia de alertas se había vuelto indistinguible de la ausencia de incidentes.
Mi contribución
Rastreé el efecto de la migración sobre las etiquetas de recurso y los formatos de payload, audité las políticas y métricas relacionadas, apliqué los cambios específicos del runtime y validé los nuevos filtros contra mensajes de log que se sabía que existían. También revisé la ruta de logging de la aplicación, donde cambiar solo el filtro no restauraría la visibilidad.
Por qué la corrección obvia era incompleta
Reemplazar el tipo de recurso parecía suficiente. No lo era: algunas funciones en Go emitían JSON estructurado, mientras que las funciones en Python emitían texto plano. Una política que usaba un campo de texto plano podía seguir ciega incluso después de corregir su filtro de recurso.
Otras políticas usaban una expresión de búsqueda que ya coincidía con cualquiera de los dos formatos de payload. Tratar todos los filtros por igual habría introducido cambios innecesarios. Verifiqué cada forma en lugar de aplicar un reemplazo universal.
Resultados y medición
El registro de cierre confirma 22 políticas y dos métricas corregidas y verificadas. Un barrido en todo el proyecto no encontró ninguna política o métrica que siguiera usando el filtro de recurso obsoleto.
La comparación de cinco coincidencias es una prueba de control positivo para un mensaje conocido específico. Demuestra por qué la corrección limitada al recurso era insuficiente; no afirma que se haya cubierto toda posible falla futura. Algunas señales se dejaron deshabilitadas a propósito donde eran redundantes, en lugar de habilitar todo de forma indiscriminada.
Extender la cobertura al flujo de negocio
En un seguimiento aparte, descubrí que dos ámbitos de verificación de alto volumen estaban ausentes de un monitor que observaba un ámbito mucho más pequeño. La instantánea de producción registrada mostró aproximadamente 128,000 documentos por día en esos ámbitos que antes no se observaban. Agregué las verificaciones faltantes y separé un ámbito inactivo en lugar de tratar un único total como prueba de cobertura completa.
Ese volumen diario describe la observación usada para encontrar la brecha. No es un conteo de verificaciones fallidas ni de incidentes evitados.
Distinguir la ausencia de eventos de un estado faltante
Una investigación posterior de un batch worker separó los contadores de eventos vacíos válidos de los indicadores de estado defectuosos. Un circuit breaker sano debe seguir publicando su estado actual aunque nunca cambie de estado. La reparación también dio a cada réplica una identidad de recurso de OpenTelemetry apropiada, en lugar de combinar sus datos en una sola serie ambigua.
La validación en producción registró cero errores de ordenamiento en una ventana de 3h28m, frente a errores que se repetían cada minuto antes del cambio. La misma consulta devolvió los errores previos como control positivo. Los paneles de eventos aún podían, legítimamente, no tener datos cuando no se había ejecutado ningún batch; la reparación no fabricó eventos para que un dashboard pareciera poblado.
Lo que aprendí
Un filtro que devuelve cero filas no es un resultado de validación hasta que existe un evento conocido con el que debería coincidir. La aceptación de una migración necesita una verificación de observabilidad que ejercite payloads reales, no solo un health endpoint exitoso.
Decisiones y próximos pasos
Una mirada retrospectiva al enfoque y sus límites. La próxima mejora es una propuesta, no un resultado entregado.
Alternativa y justificación
Reemplazar solo el tipo de recurso es más simple, pero los logs estructurados de Go y los de texto plano de Python requieren una coincidencia de payload distinta.
Contrapartida
Un dashboard en silencio no puede distinguir una aplicación sana de una ruta de logging o de alertas rota.
Lo que mejoraría a continuación
Próxima mejora: automatizar verificaciones periódicas de control positivo e incluir la compatibilidad de alertas en los criterios de aceptación de las migraciones.