Observabilidad: por qué importan los logs, las métricas y las trazas
Alejandro Alonso Noguerales
5 may 2026
Llevo años con microservicios, Kafka, Spring Boot. Lo que nunca había tenido que hacer es montar la observabilidad desde cero — en todos mis trabajos anteriores lo gestionaba otro equipo, o venía configurado de serie. Hasta que empezamos a construir un ERP sin equipo de plataforma, sin nada preconfigurado. Todo lo que el sistema necesita, lo montamos nosotros.
01 — Monitorización no es observabilidad
La diferencia importa. La monitorización responde a la pregunta “¿está rota?”. La observabilidad responde a “¿por qué está rota y dónde?”.
Un dashboard con la latencia media de tus endpoints es monitorización. Una alarma que se dispara cuando la cola de Kafka pasa de 10.000 mensajes es monitorización. Es útil — fundamental, de hecho. Pero solo te dice que algo va mal. Para entender qué está pasando necesitas otra cosa.
Observabilidad es la capacidad de entender qué está haciendo tu sistema por dentro sin tener que añadir código nuevo cada vez que algo nuevo se rompe. Si cada incidente acaba con un “voy a meter unos logs aquí para ver qué pasa la próxima vez”, no tienes observabilidad. Tienes un sistema poco observable que vas parcheando reactivamente.
Un sistema observable te deja hacer preguntas que no anticipaste cuando lo escribiste. Y eso es lo que necesitas cuando algo raro pasa a las 3 de la mañana.
02 — Las tres señales
La observabilidad moderna se apoya en tres tipos de señales: logs, métricas y trazas. Cada una responde a una pregunta distinta y tiene fortalezas y limitaciones distintas.
Logs
Lo que llevamos haciendo toda la vida. Eventos discretos en formato texto: “el usuario X hizo login”, “se publicó un evento en Kafka”, “esta query falló con timeout”.
Los logs son insustituibles cuando necesitas el detalle exacto de qué pasó: el mensaje de error completo, el ID del recurso afectado, el stack trace. Pero a escala, son ruido. Una API con tráfico medio genera millones de líneas al día. Buscar manualmente entre ellas es como buscar una aguja en un pajar — y con frecuencia no sabes ni qué aguja estás buscando.
Su gran limitación: te dicen qué pasó en un punto del sistema, pero no cómo se conecta ese evento con el resto. El log de una excepción en el servicio A no sabe nada del log de la petición que la originó en el servicio B.
Métricas
Valores numéricos agregados en el tiempo: latencia media, throughput, número de errores por minuto, uso de CPU, profundidad de la cola. Son baratas de almacenar, baratas de consultar, fáciles de visualizar en un dashboard y perfectas para alertar.
Las métricas te dan la fotografía global del sistema: si todo está dentro de los márgenes habituales o si algo se está saliendo de la norma.
Su limitación es la otra cara de su fortaleza: están agregadas. Una métrica te dice que el percentil 99 de latencia ha subido. No te dice por qué, ni qué peticiones concretas son las que se están ralentizando, ni dónde dentro de tu sistema se está perdiendo el tiempo.
Trazas
Aquí está el cambio de paradigma. Una traza sigue una petición concreta desde que entra en tu sistema hasta que sale, atravesando todos los servicios y componentes que tocó por el camino.
Cada paso que da la petición se registra como un span: la entrada al endpoint HTTP, la query a la base de datos, la publicación en Kafka, el procesamiento en el consumer del otro servicio, todo. Y todos esos spans están unidos por un mismo trace_id.
El resultado es una vista de árbol con la cronología completa de una petición. Ves exactamente cuánto tiempo pasó en cada componente, qué llamadas hizo a otros servicios, dónde se encontró el cuello de botella. Para sistemas distribuidos, no hay nada más útil.
03 — Las tres juntas son más que la suma
Si te quedas con una sola idea de este artículo, que sea esta: el valor real está en la correlación.
Una métrica te dice que la latencia ha subido. Una traza te enseña qué peticiones concretas son las lentas. Y los logs de los servicios que aparecen en esa traza te dicen qué estaba pasando exactamente cuando se ralentizaron.
El flujo de un incidente en un sistema bien observado es así:
- Una alarma salta porque una métrica se sale de su umbral.
- Abres el dashboard, identificas el servicio afectado y miras las trazas de las peticiones lentas o fallidas.
- Una traza concreta te lleva al span que tarda demasiado o devuelve error.
- Saltas a los logs de ese span — filtrados por
trace_id, no por timestamp — y ves el detalle exacto de qué pasó.
Sin correlación, cada paso es una investigación independiente. Con correlación, son cuatro clics. La diferencia entre diagnosticar en cinco minutos o en cuatro horas se construye aquí.
Y por eso un log sin trace_id o sin span_id deja de ser útil en el momento en que tu sistema deja de ser un monolito. Si tu API publica eventos en Kafka que procesan otros servicios, el log “fallo al actualizar el saldo” sin más contexto es un acertijo. Con trace_id, es el final de un hilo que puedes seguir hacia atrás.
04 — Antes de OpenTelemetry
Instrumentar una aplicación significaba elegir vendor primero y atarte después.
Si querías mandar trazas a Datadog, instalabas el agente de Datadog. Si querías New Relic, el de New Relic. Si querías Jaeger, otro distinto. Cada vendor tenía su propia API, su propia forma de instrumentar, su propio agente Java. Cambiar de backend implicaba reinstrumentar la aplicación de cero. Y mantener el mismo código instrumentado para varios vendors a la vez era directamente un infierno.
Para métricas pasaba algo parecido. Para logs, cada agregador tenía su formato, sus parsers, sus convenciones.
El problema no era técnico. Era político. Cada vendor quería su lock-in y la fragmentación se mantenía artificialmente. La industria llevaba años pidiendo un estándar abierto.
05 — Qué resuelve OpenTelemetry
OpenTelemetry (OTel) es ese estándar. Es el resultado de fusionar dos proyectos previos (OpenTracing y OpenCensus) en una única especificación gobernada por la CNCF. Hoy es el segundo proyecto más activo en CNCF, solo por detrás de Kubernetes.
La promesa es simple y es exactamente la que hace falta: instrumentas una vez, eliges backend después. Tu aplicación habla OTel. Mañana puedes cambiar de Datadog a Grafana, o a Elastic, o a Jaeger, sin tocar una línea del código de la aplicación.
OpenTelemetry define tres cosas:
- Una API: cómo crea tu código spans, métricas y logs estructurados. Es lo que ves en tu IDE. La API es estable y compatible entre versiones.
- Un SDK: la implementación de esa API en cada lenguaje. Es lo que se ejecuta en tu aplicación.
- Un protocolo (OTLP): cómo viaja la telemetría desde tu aplicación hasta donde se almacene. Es un protocolo binario sobre gRPC o HTTP, eficiente y soportado por casi todos los backends modernos.
Y una pieza adicional que merece capítulo aparte:
- El Collector: un proceso intermedio (un binario en Go, normalmente) que recibe la telemetría de tus aplicaciones, opcionalmente la procesa (filtra, enriquece, transforma) y la reenvía al backend final.
El Collector es lo que hace todo el sistema flexible. Tus aplicaciones hablan OTLP siempre, contra un Collector. El Collector decide qué se manda dónde. Cambiar de backend = cambiar la configuración del Collector. Las aplicaciones siguen igual.
06 — Por qué importa esto en Spring Boot 4
Spring siempre tuvo una historia propia con observabilidad. Durante años, la API de referencia ha sido Micrometer — pensada por el propio equipo de Spring como una fachada vendor-neutral, mucho antes de que OpenTelemetry estuviera maduro. Para nosotros eso significaba un Spring Actuator que exponía métricas Prometheus, un agente externo de algún vendor para las trazas, y los logs por nuestra cuenta.
Spring Boot 4 cambia las reglas del juego al introducir spring-boot-starter-opentelemetry: una integración nativa con OTel. No es un agente Java externo que se cuelga del bytecode. No es una librería de terceros con su propia configuración. Es un starter Spring más, configurable como cualquier otro.
Esto importa porque cierra el círculo: las tres señales (logs, métricas, trazas) salen de la aplicación hablando OTLP, correlacionadas entre sí, sin que tú tengas que pegar piezas a mano. Y por debajo, Spring sigue usando Micrometer para lo que Micrometer ya hacía bien, conectado al SDK de OTel para que la salida sea estándar.
Pero hablar de cómo funciona esto en código es lo que hacemos en la siguiente parte.
07 — Lo que viene en la segunda parte
En el próximo artículo vamos a coger lo que aquí hemos descrito en abstracto y montarlo de verdad. La demo no es un ejemplo de libro — es una versión en miniatura de lo que he montado en el ERP. Misma arquitectura, mismas decisiones, mismos problemas reales. Cogemos dos servicios Spring Boot 4 conectados por Kafka, los instrumentamos con spring-boot-starter-opentelemetry, y vemos:
- Qué te da gratis el starter y qué tienes que configurar tú.
- Cómo se propaga una traza desde una petición HTTP, atraviesa Kafka, llega al consumer y termina escribiendo en una base de datos. Todo con el mismo
trace_id. - Qué pasa cuando exportas esa telemetría primero a un Collector vanilla y luego a un stack ELK. Sin tocar ni una línea del código de las aplicaciones.
Este último punto es el que más nos interesa: demostrar que la promesa de OpenTelemetry es real. La instrumentación es una decisión, el backend es otra completamente distinta, y eso es lo que hace que merezca la pena.
Si te llevas algo de este post, que sea lo siguiente. Mira tu aplicación más crítica y pregúntate: si algo se rompe ahora mismo, ¿cómo lo descubres? ¿Cómo lo diagnosticas? ¿Tienes los tres tipos de señales? ¿Están correlacionadas?