Observabilidad para microservicios: metricas, traces y logs que realmente importan
847 alertas en una semana
Eso es lo que recibia el equipo de operaciones de un cliente cuando empezamos a trabajar con ellos. 847 alertas en 7 dias. El resultado predecible: las ignoraban todas. Cuando una alerta real surgio (un servicio de pagos con latencia degradada que estaba causando timeouts para un 12% de los clientes), tardo 4 horas en detectarse. No porque no hubiera una alerta. Habia 23 alertas relacionadas. Pero estaban enterradas en un mar de ruido.
Ese escenario es el resultado directo de confundir monitorizacion con observabilidad. Monitorizar es recoger datos. Observar es entender el sistema. La diferencia no es semantica. Es operativa. Y tiene un coste medible en downtime, en horas de ingenieria perdidas, y en clientes que se van sin decir por que.
Que metricas instrumentar (y cuales ignorar)
El instinto natural es instrumentar todo. CPU, memoria, disco, red, latencia de cada endpoint, tasa de error de cada servicio, longitud de cada cola. El resultado es un dashboard con 200 paneles que nadie mira y un sistema de alertas que genera 847 notificaciones semanales.
La alternativa: empezar por las cuatro senales doradas de Google SRE.
Latencia. Tiempo que tarda una peticion en completarse. Pero no la media. La media es mentirosa. Un servicio con latencia media de 120ms puede tener un p99 de 3.2 segundos, lo que significa que 1 de cada 100 usuarios espera mas de 3 segundos. Instrumentamos p50, p95, y p99. El p50 nos dice como va el usuario tipico. El p99 nos dice como van los usuarios que peor lo pasan. Si el p99 se dispara pero el p50 se mantiene, tenemos un problema que afecta a pocos usuarios pero de forma severa.
Y hay un detalle critico: medir latencia por separado para peticiones exitosas y fallidas. Las peticiones que devuelven un error 500 a menudo son rapidas (el servicio falla rapido). Si las mezclas con las exitosas, la latencia media baja cuando hay mas errores. Counterintuitivo y peligroso.
Trafico. Peticiones por segundo. Pero desglosado por tipo de operacion, no agregado. El trafico de lectura y el de escritura tienen perfiles completamente diferentes. Un pico de lecturas puede ser normal (campana de marketing, hora punta). Un pico de escrituras puede ser anomalo (un script descontrolado, un ataque, un loop en un microservicio).
Errores. Tasa de errores como porcentaje del trafico total. No numero absoluto. 500 errores por hora suena terrible. 500 errores por hora con 2 millones de peticiones por hora es una tasa del 0.025%, que probablemente esta dentro de tu SLO. 500 errores por hora con 10,000 peticiones por hora es un 5%, y eso es una crisis.
Saturacion. Cuanto de la capacidad del servicio esta en uso. CPU, memoria, conexiones a base de datos, goroutines, threads, lo que sea el recurso limitante de tu servicio particular. La saturacion es la metrica predictiva: te dice cuando vas a tener un problema, no cuando ya lo tienes.
Esas cuatro metricas, bien instrumentadas, cubren el 80% de las necesidades de observabilidad. Todo lo demas es contexto adicional para diagnostico, no para alerting.
Distributed tracing: la pieza que cambia todo
Imagina una peticion de un usuario que pasa por el API gateway, luego al servicio de autenticacion, luego al servicio de pedidos, que llama al servicio de inventario, que consulta la base de datos, que genera un evento en Kafka, que es consumido por el servicio de facturacion. Siete servicios. Si la peticion tarda 4 segundos, donde esta el cuello de botella?
Sin tracing distribuido, la respuesta es: no tenemos idea. Cada servicio tiene sus propios logs. Correlacionar los logs de siete servicios para una peticion individual es un ejercicio manual que lleva 30 minutos como minimo. Y si tienes miles de peticiones por minuto, encontrar la que fallo es buscar una aguja en un pajar.
Con tracing distribuido (OpenTelemetry, que es el estandar de facto), cada peticion recibe un trace ID que la sigue a traves de todos los servicios. Cada paso dentro de un servicio genera un span con su duracion, sus atributos, y su relacion con el span padre. El resultado es un arbol de llamadas que te muestra exactamente donde se gasto el tiempo.
Implementamos tracing con OpenTelemetry SDK en cada servicio. Los traces se envian a un collector (OpenTelemetry Collector) que los exporta a Jaeger o Tempo. En produccion, no tracemos el 100% de las peticiones. Tracemos un 10% con muestreo probabilistico, mas un 100% de las peticiones que devuelven error, mas un 100% de las peticiones con latencia superior al p95. Eso nos da suficiente cobertura para diagnosticar problemas sin el coste de almacenar traces de cada peticion.
Correlacion con metricas de negocio
Aqui es donde el tracing deja de ser una herramienta de infra y se convierte en una herramienta de negocio.
Anadimos atributos de negocio a los spans. No solo el endpoint y el metodo HTTP. El ID del cliente, el tipo de operacion (compra, devolucion, consulta), el valor monetario de la transaccion. Con esos atributos, podemos responder preguntas como: los clientes premium experimentan la misma latencia que los estandar? Las transacciones de alto valor tienen mas errores? La degradacion de latencia del servicio de inventario esta afectando a las ventas?
Un ejemplo real: detectamos que el 8% de las peticiones al servicio de pagos con tarjeta tenian una latencia superior a 5 segundos. Sin correlacion de negocio, eso era “un problema de rendimiento”. Con correlacion, descubrimos que el 100% de esas peticiones lentas eran pagos con tarjeta internacional procesados por una pasarela de pagos secundaria. El problema no era nuestro servicio. Era el timeout del proveedor externo. La solucion fue aumentar el timeout y mostrar un spinner al usuario, no optimizar nuestro codigo.
Sin los atributos de negocio en el trace, habriamos pasado dias optimizando un servicio que no era el problema.
Logs: menos es mas
Los logs son la senal de observabilidad mas antigua y la mas abusada. La mayoria de equipos logean demasiado. Un servicio que genera 500 MB de logs por hora esta generando ruido, no informacion.
Nuestras reglas para logging efectivo:
Structured logging siempre. JSON, no texto libre. Un log como {"level":"error","service":"payments","trace_id":"abc123","error":"timeout","gateway":"secondary","latency_ms":5200} es buscable, filtrable, y parseable. Un log como ERROR: Payment failed after 5.2 seconds on secondary gateway requiere regex para extraer datos. En produccion, con millones de lineas, la diferencia es critica.
Un evento, un log. No tres logs para una operacion: “Starting payment processing”, “Payment sent to gateway”, “Payment completed”. Un solo log al final con el resultado y los datos relevantes: exito o fallo, duracion, gateway utilizada, importe. Los logs intermedios son utiles en desarrollo. En produccion, son ruido.
Log levels con disciplina. ERROR es algo que requiere accion humana inmediata. WARN es algo que podria convertirse en error si no se resuelve. INFO son eventos de negocio significativos (pedido creado, pago procesado, usuario registrado). DEBUG solo se activa temporalmente para diagnosticar un problema especifico y se desactiva despues.
Hemos reducido el volumen de logs de clientes entre un 60% y un 80% sin perder informacion relevante. El resultado: busquedas mas rapidas en Loki/Elasticsearch, facturas de almacenamiento mas bajas, y operadores que pueden encontrar la informacion que necesitan en segundos en vez de minutos.
Alerting: la parte que todo el mundo hace mal
Volvamos a las 847 alertas semanales. Como se llega ahi?
Se llega alertando sobre sintomas en vez de sobre impacto al usuario. Una alerta de “CPU al 85%” no dice nada sobre si los usuarios estan afectados. Puede que el servicio funcione perfectamente al 85% de CPU. Puede que falle al 60%. La CPU es un input, no un outcome.
Las alertas deben definirse en terminos de SLOs (Service Level Objectives). Un SLO dice: “el 99.5% de las peticiones al servicio de pagos tendran una latencia inferior a 2 segundos”. La alerta se dispara cuando el error budget se esta consumiendo mas rapido de lo esperado, no cuando una metrica individual cruza un umbral.
Implementamos alertas basadas en burn rate. Si tu SLO es 99.5% de disponibilidad mensual (equivalente a 3.6 horas de downtime permitido), y en las ultimas 6 horas has consumido el 20% de tu error budget, la alerta se dispara. Eso te da tiempo de reaccionar antes de violar el SLO, pero no te despierta a las 3 de la manana porque un servicio tuvo 5 errores en un minuto.
Resultado para el cliente de las 847 alertas: redujimos a 12-15 alertas semanales. Cada una requeria atencion. La tasa de falsos positivos bajo del 94% al 8%. El MTTR (Mean Time To Resolve) bajo de 4 horas a 22 minutos, porque cuando sonaba una alerta, los ingenieros sabian que era real y tenian el trace ID en la notificacion para empezar a diagnosticar inmediatamente.
El stack que recomendamos
Despues de implementar observabilidad en una docena de entornos de microservicios, este es el stack que converge para empresas medianas:
Metricas: Prometheus + Grafana. Open source, maduro, ecosistema enorme de exporters. Para quien no quiera operar Prometheus, Grafana Cloud ofrece Prometheus-as-a-service con un tier gratuito generoso.
Traces: OpenTelemetry + Tempo (o Jaeger). OpenTelemetry como SDK de instrumentacion es no-negociable: es el estandar, tiene soporte en todos los lenguajes, y es vendor-neutral. Tempo como backend de traces si ya usas Grafana. Jaeger si prefieres algo independiente.
Logs: Loki + Grafana. Loki es significativamente mas barato que Elasticsearch para logs porque no indexa el contenido completo, solo las etiquetas. Para busquedas full-text frecuentes, Elasticsearch sigue siendo superior. Pero para la mayoria de casos de uso de logs en produccion, Loki es suficiente y cuesta una fraccion.
Alerting: Grafana Alerting con SLOs definidos en Prometheus. Alertas basadas en burn rate, no en umbrales estaticos.
El coste total de operar este stack para un entorno de 15-20 microservicios esta entre 400 y 800 euros/mes si lo autogestionas, o entre 600 y 1,200 euros/mes en Grafana Cloud. Comparado con Datadog (que para el mismo volumen puede costar 3,000-5,000 euros/mes), es una diferencia significativa.
Datadog es un producto excelente. Pero para una empresa mediana, el coste escala de forma agresiva con el volumen de datos. Y el volumen de datos de observabilidad crece mas rapido de lo que esperas.
Donde empezar
Si tu sistema de microservicios no tiene observabilidad o tiene la variante “monitorizacion basica con demasiadas alertas”, el plan de implementacion es:
Semana 1-2: Instrumentar las cuatro senales doradas con Prometheus en los 3-5 servicios mas criticos. Crear un dashboard en Grafana con p50/p95/p99 de latencia, tasa de error, y trafico por servicio.
Semana 3-4: Implementar tracing con OpenTelemetry en esos mismos servicios. Configurar muestreo al 10% con 100% para errores y latencia alta. Desplegar Tempo o Jaeger.
Semana 5-6: Definir SLOs para los servicios criticos. Crear alertas basadas en burn rate. Eliminar todas las alertas de umbral estatico existentes.
Semana 7-8: Consolidar logs en Loki. Migrar a structured logging. Aplicar las reglas de “un evento, un log” y reducir el volumen.
Es un esfuerzo de dos meses para un equipo de 2-3 ingenieros trabajando a tiempo parcial. El retorno es inmediato: la primera incidencia que diagnosticas en 20 minutos en vez de 4 horas paga la inversion.
Para equipos que necesitan ayuda con la implementacion, nuestros servicios de cloud y DevOps incluyen observabilidad como componente estandar. Porque un sistema que no puedes observar es un sistema que no puedes operar. Tambien puedes revisar como la observabilidad conecta con las estrategias de despliegue sin downtime y con el testing en produccion.
Etiquetas
Sobre el autor
abemon engineering
Equipo de ingenieria
Equipo multidisciplinar de ingenieria, datos e IA con sede en Canarias. Construimos, desplegamos y operamos soluciones de software a medida para empresas de cualquier escala.
