- 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
- No decide qué registrar
- No agrega automáticamente contexto de negocio (por ejemplo, nivel de suscripción, monto del carrito, etc.)
- 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
- Los errores (como 500) siempre se guardan
- Las solicitudes lentas (por encima de p99) siempre se guardan
- Las sesiones de usuarios VIP o con flags específicos siempre se guardan
- 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
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.
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
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
log.error(data)ywide_event.attach(error, data)son, en esencia, lo mismoLa 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.logya 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)
grep '\"uid\": \"user-123\"'. También puedes usar la opción--contextpara ver las líneas cercanasHe 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 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
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
Cuanto mayor es el volumen de logs, más se ajusta automáticamente la tasa de muestreo para no sobrecargar el sistema
trace_id mod 100 == 0En 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
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
Los logs con contexto rico, combinados con un motor de análisis, también pueden usarse para mejorar el producto
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
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