37 puntos por GN⁺ 2025-12-22 | 1 comentarios | Compartir por WhatsApp
  • En los sistemas distribuidos modernos, los enfoques tradicionales de logging tienen limitaciones estructurales que les impiden transmitir la verdad
  • Los logs siguen diseñados con la premisa de un entorno de servidor único al estilo de 2005, por lo que pierden el contexto de una solicitud que pasa por múltiples servicios, bases de datos y cachés
  • La simple búsqueda de cadenas no entiende la estructura, las relaciones ni la correlación, lo que dificulta encontrar la causa raíz de los problemas
  • La solución es dejar, para cada solicitud, un único “Wide Event” (o “Canonical Log Line”) con todo el contexto
  • Con esto, los logs dejan de ser texto plano y se convierten en un activo de datos analizable

El problema fundamental del logging

  • Los logs tradicionales se crearon pensando en la era de los servidores monolíticos, y no reflejan la arquitectura moderna de servicios distribuidos
    • Una sola solicitud pasa por varios servicios, BD, cachés y colas, pero los logs aún se registran con una lógica de servidor único
  • En el ejemplo de logs, se generan 13 líneas por solicitud; con 10,000 usuarios concurrentes eso produce 130,000 líneas por segundo, pero la mayoría es información sin valor
  • Cuando ocurre un problema, lo que hace falta es contexto, pero los logs actuales carecen de él

Los límites de la búsqueda por cadenas

  • Cuando un usuario reporta “no puedo pagar”, aunque busques en los logs por email o por user_id, es difícil obtener resultados útiles porque no existe una estructura consistente
    • El mismo ID de usuario puede registrarse de decenas de formas distintas, como user-123, user_id=user-123, {"userId":"user-123"}
  • Como el formato de logs cambia entre servicios, es imposible rastrear eventos relacionados
  • El problema central es que los logs están diseñados con foco en la escritura (write), pero no están optimizados para la consulta (query)

Definición de conceptos clave

  • Structured Logging: forma de registrar datos en formato clave-valor (JSON) en lugar de cadenas
  • Cardinality: cantidad de valores únicos de un campo; por ejemplo, user_id es muy alta
  • Dimensionality: cantidad de campos dentro de un evento de log; cuanto más alta, mayor capacidad de análisis
  • Wide Event / Canonical Log Line: un único evento de log por solicitud, rico en contexto
  • La mayoría de los sistemas de logging limitan los datos de alta cardinalidad por costos, aunque en la práctica son los más útiles para depurar

Las limitaciones de OpenTelemetry

  • OpenTelemetry (OTel) es un conjunto de protocolos y SDKs que solo proporciona estándares para recopilar y transportar datos
  • Sin embargo, OTel no hace lo siguiente
    1. No decide qué registrar
    2. No agrega automáticamente contexto de negocio (por ejemplo, nivel de suscripción, monto del carrito, etc.)
    3. No cambia la forma de pensar sobre logging de los desarrolladores
  • Incluso usando la misma librería, la experiencia de depuración cambia radicalmente entre una instrumentación que agrega contexto de forma intencional y una instrumentación básica
  • OTel es simplemente una infraestructura de transporte (plumbing), y qué hacer circular por ella lo decide el desarrollador

Enfoque Wide Event / Canonical Log Line

  • Hay que dejar atrás el logging centrado en “qué hace el código” y registrar “qué le pasó a la solicitud
  • Para cada solicitud, se genera un evento amplio por servicio
    • Puede incluir más de 50 campos sobre la solicitud, el usuario, el pago, los errores, el entorno, etc.
  • El JSON de ejemplo incluye user_id, subscription_tier, service_version, error_code y todo el contexto necesario para depurar
  • Esto permite analizar de inmediato, con una sola búsqueda, cosas como la causa de fallas de pago en usuarios premium

Uso de consultas sobre Wide Event

  • Wide Event no se trata con búsqueda simple de texto, sino con consultas sobre datos estructurados
  • A partir de datos de alta cardinalidad y alta dimensionalidad, permite una depuración al nivel de análisis en tiempo real
  • Ejemplo: se puede ejecutar de inmediato una consulta como “agrupar la tasa de fallas de pago de usuarios premium por código de error durante la última hora”

Patrón de implementación

  • El evento se va construyendo durante todo el ciclo de vida de la solicitud y se emite una sola vez al final
    • En el middleware se inicializan campos base como request_id, timestamp, method, path, etc.
    • En el handler se agregan gradualmente datos del usuario, carrito, pago y errores
  • Al final, se registra un único evento JSON con logger.info(event)

Control de costos con sampling

  • Registrar más de 50 campos por solicitud dispara los costos, por lo que hace falta sampling
  • El muestreo aleatorio simple puede hacer que se pierdan errores
  • Se propone una estrategia de Tail Sampling
    1. Los errores (como 500) siempre se guardan
    2. Las solicitudes lentas (por encima de p99) siempre se guardan
    3. Las sesiones de usuarios VIP o con flags específicos siempre se guardan
    4. Del resto, solo se toma una muestra aleatoria del 1 al 5%
  • Así se logra reducir costos y conservar los eventos clave al mismo tiempo

Aclarando malentendidos comunes

  • Structured Logging ≠ Wide Event: usar JSON no basta; el contexto es lo esencial
  • Usar OpenTelemetry ≠ tener observabilidad completa: solo estandariza la recolección; qué registrar sigue siendo decisión del desarrollador
  • No es lo mismo que tracing: el tracing muestra el flujo entre servicios; Wide Event aporta contexto dentro del servicio
  • La distinción de que los logs son para depurar y las métricas para dashboards ya no hace falta: Wide Event cubre ambos usos
  • La idea de que los datos de alta cardinalidad son caros está desactualizada; bases de datos modernas como ClickHouse y BigQuery los procesan eficientemente

Efectos de adoptar Wide Event

  • La depuración pasa de la exploración arqueológica (archaeology) al análisis (analytics)
  • En lugar de hacer grep sobre logs de 50 servicios para encontrar una “falla de pago de usuario”,
    se pasa a un análisis basado en una sola consulta, como “consultar la tasa de fallas de pago de usuarios premium por código de error”
  • Como resultado, los logs dejan de ser una herramienta que decía mentiras y se convierten en un activo de datos que dice la verdad

1 comentarios

 
GN⁺ 2025-12-22
Opiniones en Hacker News
  • El texto era difícil de leer y daba la impresión de haber sido ayudado por IA. Aun así, el mensaje tenía valor, y habría sido mejor si fuera más conciso.
    Algunas cosas que he pensado recientemente son las siguientes.

    • Como hay autenticación en toda la pila, empecé a incluir el user id en cada línea de log. Gracias a eso, se volvió mucho más fácil ver la experiencia completa que tuvo un usuario
    • Registrar los errores en una línea separada de los logs de la solicitud es incómodo. Se puede filtrar por trace, pero es difícil construir consultas como “muéstrame solo errores relacionados con solicitudes 5xx”
    • Agregar este tipo de contexto no basta; también hay que capacitar a los colegas para que sepan que existen campos nuevos. He visto muchos casos en que sufren solos por no saberlo
    • Si inviertes en mejores herramientas de tracing, puedes depurar a un nivel que con logs simples no es posible. Es como extender la idea de usar el user id como trace
    • Si en la base de código existe el concepto de request ID, también puede usarse para rastrear con más detalle el comportamiento del usuario
    • Si impones el uso de TID en todos los servicios, cualquier equipo puede seguir una transacción completa con solo un TID
    • Comentarios como “esto huele a IA” pronto se volverán una cultura criticada
  • En este tema es imposible no mencionar a Charity Majors. Ella lleva más de 10 años difundiendo las ideas de “wide events” y “observability”, y construyó Honeycomb.io sobre esa filosofía.
    Hoy en día este enfoque puede implementarse con varias herramientas. Lo importante es capturar wide events usando structured logs o traces, y usar herramientas con buenas visualizaciones como series temporales e histogramas

    • Aun así, ella no inventó el término “observability”. Ya era un concepto usado desde hace décadas en varios campos. Es una profesional influyente, pero no la creadora del término
    • Su blog y la historia detrás de Honeycomb son lectura obligada para cualquiera que trabaje en la industria. Fue uno de los primeros equipos en reconocer el valor de este enfoque
    • El texto se parecía tanto a su estilo que me sorprendió que no terminara con una publicidad de Honeycomb
    • En el ecosistema .NET, Nick Blumhardt ya venía trabajando desde hace mucho en “structured logging”, y Seq y Serilog lo apoyaban
    • Su contenido es bueno, pero nadie “marcó” la palabra “observability”. Hay que respetar su aporte, pero evitar afirmaciones exageradas
  • Estoy de acuerdo con parte del argumento del texto, pero el enfoque de dejar solo un wide event único tiene trampas. Si ocurre una excepción o un timeout en medio de la solicitud, puede que no quede nada registrado.
    También se pueden perder los logs del framework base del lenguaje o de las dependencias.
    Por eso, conviene usar esto como una capa adicional encima de los logs existentes. Puedes tener IDs por request/session y luego agregarlos en algo como ClickHouse

    • Si el problema es la visibilidad de las capas intermedias, entonces el evento no es lo suficientemente wide. log.error(data) y wide_event.attach(error, data) son, en esencia, lo mismo
    • Logs como “connection X:Y accepted at Z ns” y “closed at Z ns” son muy útiles para depurar sistemas lentos
    • Yo lo resolví en un framework PHP creando una LoggerInterface. Capturo las excepciones con un manejador global y las guardo en la BD en formato wide. Tiene algo de boilerplate, pero funciona tan bien que ahora me resultaría incómodo no tenerlo
  • La presentación y los ejemplos interactivos estuvieron excelentes. Pero al final se resume en “agrega etiquetas estructuradas a los logs”.
    Siento que los wide logs no ofrecen tanto beneficio frente a la complejidad y la pérdida de legibilidad.
    Si con grep \"uid=user-123\" application.log ya alcanza, no veo por qué habría que adjuntar también el método de envío del usuario.
    (Por cierto, en el navegador Brave para Android las casillas no funcionaban)

    • Si los logs están en JSON, todavía puedes buscar con grep '\"uid\": \"user-123\"'. También puedes usar la opción --context para ver las líneas cercanas
  • He trabajado en entornos de fabricación de semiconductores con sistemas que tenían miles de participantes en el bus de mensajes. Se generaban 300~400MB de logs por hora, pero solo con grep y herramientas CLI bastaba para manejarlos.
    Los logs eran simplemente una serie temporal de eventos, y el análisis detallado se hacía con consultas Oracle. Los logs son una herramienta para entender la causalidad de los incidentes

    • Los logs sirven para entender la línea de tiempo, no para contener todos los datos de cada request y response. Si metes demasiada información, al final se vuelve más difícil de entender.
      Los logs dicen “cuándo” y “qué” ocurrió; el “por qué” se encuentra combinando código, datos y eventos
      Personalmente, interfaces como las del stack ELK me resultan incómodas para la exploración intuitiva. Lo importante es poder seguir y leer los logs de manera instintiva
    • 400MB de logs por hora en realidad no es tanto. Por eso, con grep simple es más que suficiente
  • El consejo del final del texto de “registrar todos los errores, excepciones y requests lentos” es una idea peligrosa.
    Por ejemplo, si una dependencia se vuelve lenta, el volumen de logs puede dispararse 100 veces.
    En una situación de falla, el servicio debería hacer menos trabajo para recuperarse más fácilmente, pero una explosión de logs puede provocar una falla en cascada

    • En Cloudflare usan muestreo adaptativo. Agrupan los lotes de logs por campos y, de cada bucket, conservan solo la raíz cuadrada o el logaritmo de la cantidad de entradas.
      Cuanto mayor es el volumen de logs, más se ajusta automáticamente la tasa de muestreo para no sobrecargar el sistema
    • Este tipo de umbrales mágicos es peligroso. Valores como P(99) deberían actualizarse dinámicamente. Si el proveedor OTEL obtiene periódicamente los valores reales, es más seguro
    • Los servicios en producción deben diseñarse para que la recolección de logs escale según la demanda. Incluso solo con buffering en disco local ya se logra mucho
    • Si es un servicio de alto tráfico, puedes muestrear requests sanos con algo como trace_id mod 100 == 0
    • Si los logs se vuelven un cuello de botella, entonces el sistema está mal diseñado. Un logging eficiente puede manejar cientos de millones de eventos por segundo
  • En el software moderno es difícil que un solo log explique por completo “qué pasó”.
    Por eso hacen falta la correlación vertical (Vertical correlation) y la correlación horizontal (Horizontal correlation).
    Entre capas superiores e inferiores dentro de la pila se debe compartir el mismo valor de correlación, y en la comunicación entre sistemas hace falta correlación entre pares.
    Agregar esos valores a una API o protocolo es difícil, pero si diseñas desde antes un transaction ID, puedes rastrear todo de punta a punta

  • Me parece que registrar un dominio aparte para un solo artículo tiene poca sostenibilidad.
    Como hay que pagar la renovación cada año, me parece mejor usar un blog personal o un subdominio.
    Por ejemplo, algo como logging-sucks.boristane.com sería una buena opción

    • En realidad, este dominio y el artículo son para promocionar el observability SaaS del autor. Requiere una cuenta de Cloudflare, pero como es gratis, parece parte de una estrategia de marketing a largo plazo. Aun así, me resultó útil, y como tengo cuenta de CF, pienso probarlo
    • Este texto va en una línea parecida a “Give people something to link to” de Simon Willison
    • Esto se parece más a una landing page de generación de leads para marketing digital que a una entrada de blog. La promoción del servicio es evidente
  • Sobre la afirmación de que “los logs son un vestigio de la era monolítica”, yo creo que los logs locales siguen siendo válidos.
    Su función original es registrar la conversación del proceso local, y para entender qué pasa en otros servidores se necesita transaction tracing.
    Con solo mirar los logs del lugar correcto, puedes llegar a la causa raíz

    • Pero los logs no solo sirven para análisis de causa raíz; también pueden dar insights de negocio, como quiénes fueron afectados, la correlación entre rendimiento e inputs o el impacto de vulnerabilidades de seguridad.
      Los logs con contexto rico, combinados con un motor de análisis, también pueden usarse para mejorar el producto
    • Ante la frase “una request pasa por 15 servicios y 3 DB”, también hubo quien respondió que hay que evitar ese nivel de complejidad
    • A mí me parece que con APN/Kibana ya es suficiente para analizar logs
  • Estoy de acuerdo con la idea de “registrar no lo que hace el código, sino lo que le pasa a la request”, pero el autor parecía tener poca experiencia.
    Yo a esto le llamo “bug parts logging”, y creo que debería incluir señales precursoras como la ruta de procesamiento, la cantidad de veces y el tiempo.
    El logging no es lo mismo que las métricas ni que la auditoría. Si el logging falla, el procesamiento debe continuar; pero si falla la auditoría, eso sí es crítico.
    Igual que el concepto de “historian” en sistemas SCADA, hay que distinguir entre observables y evaluatives.
    Por ejemplo, los eventos detallados de un sensor de combustible pueden servir para diagnóstico, pero no son necesarios para responder la pregunta “¿se puede llegar al destino?”.
    Al final, lo importante es definir con claridad qué vas a observar y qué vas a evaluar

    • Yo apoyo una “teoría unificada de la observabilidad”. Logs, métricas y auditoría son, al final, solo flujos de bits y pueden transformarse sin pérdida.
      Aunque difieran en almacenamiento, transformación y consulta, los puntos de consumo y mecanismos pueden diseñarse de forma común.
      Así el diseño del sistema se simplifica, y además puedes reprocesar más adelante logs almacenados a largo plazo