BlogInfraestructura

El timbre no timbra

Cambiamos una clave y el chat de avisos se calló sin dar error. Ahora contamos los avisos que sí llegan

Nicolás Biondi

Un timbre de bronce en una pared oscura con su cable cortado colgando, los extremos de cobre brillando apenas.

Encontré el problema buscando otra cosa, que ya es mi método de diagnóstico favorito: un canal de avisos automáticos se había quedado mudo. Nadie extraña un canal que solo informa, así que el silencio pareció tranquilidad.

Cada vez que ocurre cierto evento, el sistema publica un aviso en ese canal. El dato igual queda guardado; el aviso solo ahorra ir a buscarlo, y sin aviso nadie lo busca.

La credencial nueva salió y el sistema siguió con la vieja

Rotamos la credencial del lado de la plataforma de mensajería, la llave que autoriza a un sistema a enviar mensajes. El sistema siguió presentando la anterior, así que cada intento recibió un 401, la respuesta con la que una API avisa que esa llave ya no sirve.

Un canal que solo informa falla distinto que uno que alguien está esperando: cada rechazo termina en un log de errores, y un log de errores recién se abre cuando ya andas buscando un problema. Es un timbre con el cable cortado: nadie se queja del silencio y uno asume que no vino nadie.

Meme Change My Mind: Un log sin lector no es monitoreo / Cambien mi opinión Un log sin lector no es monitoreo Cambien mi opinión

Evento del sistema

Aviso al canal

Rechazo 401

Línea en el log de errores

Log sin lector

Silencio

Por qué el timbre dejó de timbrar: la falla existía, pero terminaba en un log de errores sin lector.

El deploy era el culpable obvio

Pensé que el código de envío se había roto en un deploy, porque habíamos tocado esa parte hacía poco. El código estaba igual.

Lo confirmamos con un endpoint de solo lectura, una consulta que devuelve 200 si la credencial sirve y 401 si no, sin publicar ningún mensaje. Respondió 401. Probarlo con un envío real habría colado un aviso falso entre los reales, y el silencio ya era desorden suficiente.

Reenviar lo pendiente sin inventar el formato

Con la credencial actualizada los avisos nuevos volvieron a salir, pero los eventos del periodo mudo seguían sin anunciar. Escribí un script de reenvío que reutiliza las funciones de producción en vez de rearmar los mensajes, porque un aviso con otro formato parece salido de otro sistema.

Le puse tres frenos de mano: corre en dry-run por defecto, o sea imprime qué enviaría sin enviar nada; se niega a arrancar si el sistema no está corriendo en su modo normal; y omite los avisos que ya perdieron vigencia, porque anunciar algo terminado solo confunde. Los avisos pendientes salieron en una sola corrida, con el mismo formato de siempre.

Un solo camino y un log que cuenta éxitos

Debajo del incidente había más de una ruta para publicar avisos, cada una con su propia credencial. Cada ruta extra es un lugar donde una llave puede quedar vieja. Dejamos una sola: hoy todos los avisos salen por la misma API, y una sola credencial que vence es una sola credencial que renovar.

El otro cambio fue darle la vuelta al log. Anotar errores no alcanzó, porque los errores aparecen donde nadie mira; ahora el log anota también cada envío exitoso. Monitorear por éxitos cambia la pregunta: en vez de confiar en que algún error grite, cuentas lo que sí salió, y el silencio deja de ser una ausencia para convertirse en un número.

La segunda vez lo vimos al toque

Semanas después, la plataforma de mensajería hizo una migración y el proceso que publicaba estos avisos quedó fuera de servicio. Esta vez el conteo de envíos exitosos se quedó quieto y eso lo delató. Al reanudar, el cruce entre lo registrado en la base de datos y el historial del chat cerró en cero avisos perdidos.

Cuando rotamos una credencial, la nueva pasa primero por la consulta que no publica nada. El timbre sigue sin quejarse cuando se calla, pero ahora alguien cuenta cuántas veces sonó.

postmortem tokens monitoring reconciliation