Contactar →
← Todas las entradas
Operaciones2026.04.22

Métricas, logs y uptime no son la misma señal

«Monitorización» suena a una sola cosa: un panel, una herramienta, una casilla que se marca una vez y ya está. En realidad es una palabra que esconde un error de categoría: los tres tipos de señal que normalmente se meten bajo ese paraguas responden a tres preguntas genuinamente distintas, y confundirlos es la manera de acabar mirando un panel en verde mientras un servicio está caído de verdad, o persiguiendo una gráfica de métricas para explicar algo que solo una línea de log te va a poder contar.

En una plataforma de infraestructura a escala personal, esto importa más de lo que parece a primera vista, precisamente porque la tentación de usar una sola herramienta para todo es más fuerte cuando todo el stack es responsabilidad de una sola persona. Es tentador pensar «tengo un panel, ya estoy cubierto». Los tres tipos de señal no se fusionan entre sí solo porque el operador sea uno solo.

Tres preguntas, no una

Las métricas responden: ¿va lento, y cuánto? Una métrica es un número muestreado a lo largo del tiempo: latencia de las peticiones, carga de CPU, profundidad de cola, tasa de error como porcentaje de peticiones. Todo su valor está en la tendencia y en el umbral: la latencia p95 de este endpoint ha ido subiendo de 80 ms a 400 ms en las últimas dos semanas, o la latencia de escritura de este disco tiene un pico cada noche a la misma hora. Las métricas son baratas de almacenar con alta resolución precisamente porque descartan el evento concreto y se quedan solo con el agregado. Ese es también su límite: una métrica puede decirte que algo se ha vuelto lento, y más o menos cuándo, pero no puede decirte por qué falló una petición concreta.

Los logs responden: ¿qué ha pasado exactamente? Una línea de log es un registro puntual, con marca de tiempo, de un evento concreto: esta petición entró, pasó por esta ruta de código, lanzó esta excepción, con este stack trace. Donde una métrica agrega y descarta detalle para seguir siendo barata, todo el valor de un log está en el detalle que conserva. Cuando una gráfica de métricas muestra un pico de tasa de error a las 03:14, la propia métrica no puede decirte qué peticiones fallaron ni por qué; esa es una pregunta que solo pueden responder los logs de esa ventana de tiempo. La propia documentación de Loki de Grafana deja esta separación explícita como una decisión de diseño y no como un detalle de implementación: Loki indexa solo un conjunto pequeño de labels por log stream en lugar del texto completo de cada línea, manteniendo deliberadamente barato el almacenamiento de logs de una forma estructuralmente parecida a como se mantienen baratas las métricas, sin dejar de conservar el contenido real del evento que una métrica nunca tuvo, para empezar (Loki overview — documentación de Grafana Loki).

Las comprobaciones de uptime/disponibilidad responden: ¿es accesible desde fuera, ahora mismo? Esta es la que más fácil resulta confundir con redundante respecto a las otras dos, y no lo es. Una comprobación de uptime es, explícitamente, una comprobación de fuera hacia dentro: no pregunta qué pinta tienen las métricas internas ni qué dicen los logs que ha pasado; hace la misma pregunta que, implícitamente, se hace un usuario externo real, que es «¿puedo llegar a esto, desde donde de verdad estoy?». El propio blackbox exporter del proyecto Prometheus ilustra bien el patrón: lanza sondeos contra un objetivo por HTTP, TCP, DNS o ICMP desde el punto de vista de dondequiera que esté el propio exporter, y reporta un único valor probe_success (1 o 0) además de latencia y código de estado, deliberadamente separado de lo que el propio endpoint de métricas internas del objetivo reporte sobre sí mismo (prometheus/blackbox_exporter, GitHub; Understanding and using the multi-target exporter pattern — documentación de Prometheus). Un servicio puede tener unas métricas internas perfectamente sanas (latencia baja, sin errores, CPU lejos de la saturación) y aun así ser completamente inaccesible desde fuera por un problema de enrutamiento, una regla de firewall o una mala configuración de DNS que quede totalmente fuera de la propia visión que el servicio tiene de sí mismo. Las métricas internas no tienen forma de darse cuenta de eso; solo una comprobación que se ejecute desde fuera del perímetro puede hacerlo.

Cada tipo de señal alerta de forma distinta, y eso no es casualidad

La separación en tres no es solo cuestión de almacenamiento y de forma de consulta: cambia qué aspecto tiene una alerta sensata para cada tipo, y mezclarlos produce un sistema de alertas que, de forma predecible, o hace demasiado ruido o se queda demasiado callado.

Una alerta basada en métricas es, por naturaleza, una condición de umbral o de tasa de cambio: dispararse cuando la latencia p95 se mantiene por encima de cierto número durante una ventana sostenida, dispararse cuando la tasa de error en porcentaje cruza una línea, dispararse cuando el uso de disco pasa del 90%. Este tipo de alertas tolera bien el ruido porque la señal subyacente es un número suave: un umbral con una cláusula «durante 5 minutos» incorporada es un seguro barato frente a que una única muestra ruidosa dispare un aviso para nada. Acertar con el emparejamiento entre un umbral de warning y un umbral crítico es un problema de diseño en sí mismo, separado de la separación por tipo de señal de la que veníamos hablando: véase Fatiga de alertas por diseño para lo que pasa cuando ambos umbrales se disparan por la misma condición subyacente.

Una alerta basada en logs tiene una forma completamente distinta: normalmente es pattern matching sobre el contenido del evento: alertar cuando aparece una clase de excepción concreta, alertar cuando los fallos de autenticación desde un mismo origen superan cierto recuento en cierta ventana. Esto es potente para detectar cosas que una métrica nunca haría aflorar (una condición de error concreta y poco frecuente que no mueve ningún número agregado lo suficiente como para disparar un umbral), pero es mucho más fácil que salga mal en la dirección del ruido, porque el volumen y el contenido de los logs varían de formas en las que una serie temporal suave no varía, y un pattern match mal acotado se convierte rápidamente en una avalancha de alertas de poco valor.

Una alerta basada en uptime es la más simple de las tres y, no por casualidad, la que hay que tomarse más en serio cuando se dispara: un sondeo fallido desde fuera significa que lo que un usuario real experimentaría está roto, ahora mismo, con independencia de lo que estén reportando los otros dos tipos de señal. Esta es la alerta que no debería ajustarse para tolerar ruido de la forma en que puede ajustarse un umbral de métricas: una sola comprobación de salud externa fallida puede ser un bache puntual, pero un pequeño número de fallos consecutivos desde un punto de vista externo es lo más cerca que este stack llega de «hay una caída real en curso», y merece tratarse con más urgencia que el cruce de un umbral de métricas, precisamente porque es el único tipo de señal que de verdad está midiendo lo mismo que notaría un usuario real.

Meter los tres tipos de alerta en un único pipeline de alertas con un único modelo de severidad tiende a difuminar esto. Una alerta de patrón en logs y un fallo de comprobación de uptime pueden acabar con el mismo peso visual en un canal de notificaciones compartido, aunque una signifique «ha pasado algo raro, merece un vistazo» y la otra «el servicio está caído ahora mismo». Mantener los tres tipos de señal en sus propias herramientas no solo mantiene los datos más limpios: mantiene calibrado el sentido del operador sobre «cómo de urgente es esto» con lo que realmente ha fallado.

Por qué un solo panel para las tres es la forma equivocada

La razón para mantener esto como herramientas separadas con paneles separados, en lugar de fusionarlo todo en un único panel unificado, no es purismo con las herramientas: es que cada tipo de señal tiene un perfil de coste distinto, un lenguaje de consulta distinto que le va bien, y un modo de fallo distinto que se le da realmente bien detectar, y forzarlas a tener una única forma tiende a empeorar las tres a la vez.

Una herramienta de métricas (algo de la familia Prometheus/Grafana, o equivalente) está construida en torno al almacenamiento de series temporales y a alertas basadas en umbrales: barata de muestrear con frecuencia, eficiente de almacenar durante meses, y consultada con algo como PromQL, pensado para agregación y matemática de tasas de cambio, no para buscar en el contenido de eventos. Intentar meter el texto completo de los logs por ese mismo modelo de almacenamiento, o sale prohibitivamente caro en cualquier ventana de retención real, o obliga a la herramienta a descartar el texto que en realidad necesitabas. Un agregador de logs (un stack al estilo Loki o al estilo ELK) está construido justo al revés: optimizado para ingerir y buscar en texto de eventos y campos estructurados, aceptando en general un coste de almacenamiento por evento más alto a cambio de poder responder «enséñame todas las peticiones desde esta IP en la última hora» de una forma que ningún almacén de métricas está diseñado para hacer con eficiencia. Y un comprobador de uptime externo no es ninguna de las dos cosas: es una sonda pequeña, tonta y deliberadamente externa cuya única labor es fallar de forma ruidosa en el momento en que no pueda llegar hasta ti, con independencia de lo que tu propia infraestructura crea sobre su propia salud.

El modo de fallo real que evita esta separación es uno concreto y frecuente: las métricas internas y los logs parecen estar bien porque el propio proceso del servicio está sano, mientras la plataforma es inaccesible desde fuera por un motivo que no tiene nada que ver con el servicio: un cambio en una regla de firewall, un registro DNS que ha dejado de resolver, un cambio de enrutamiento aguas arriba del host. Si la comprobación de uptime se tratara como una métrica más, alimentando el mismo panel que la CPU y la latencia, sería fácil dejar que degenerase en silencio hasta convertirse en «otra gráfica que normalmente está en verde», en lugar de lo que de verdad necesita ser: una señal independiente, de fuera hacia dentro, que existe específicamente porque hay clases enteras de fallo que las señales internas no pueden ver.

Cómo se ve esto en la práctica, en general

Nada de esto exige un equipo grande ni un stack elaborado. El patrón se mantiene a cualquier escala: una herramienta de métricas haciendo scraping a un puñado de exporters y renderizando paneles de series temporales, un agregador de logs recogiendo e indexando la salida de log estructurada de los servicios que la producen, y un comprobador de uptime externo y separado (algo tan simple como una sonda programada que golpea un endpoint de salud desde fuera de la red) funcionando de forma independiente de los otros dos. La disciplina importante no es qué productos concretos cubren esos tres papeles; es resistir el tirón hacia una única herramienta o un único panel que, sin darse cuenta, empieza a responder las tres preguntas comprobando en realidad solo una de las tres. Cuando el comprobador de uptime es separado y externo por construcción, no puede convertirse por accidente en un proxy de la salud interna, y cuando las métricas y los logs se almacenan y se consultan mediante herramientas realmente construidas para su forma respectiva, ninguna de las dos tiene que forzarse en un formato pensado para la otra.

El error de categoría no es fatal por sí solo: muchos montajes funcionan con los tres tipos de señal mal separados y aun así detectan la mayoría de los problemas la mayor parte del tiempo. Pero el hueco que abre es concreto y predecible: es la caída en la que todo lo interno parece estar bien, porque «bien» solo se midió alguna vez desde dentro.

Fuentes:

← Todas las entradas