MAISON CODE .
/ DevOps · OpenTelemetry · SRE · Monitoring · Backend

Observabilidad: visión de rayos X para sistemas distribuidos

Por qué los registros no son suficientes. Una guía técnica detallada sobre OpenTelemetry, registro estructurado y filosofía de alerta SRE (SLI/SLO).

AB
Alex B.
Observabilidad: visión de rayos X para sistemas distribuidos

“El sitio es lento.”

Este ticket de cuatro palabras es la pesadilla de todo equipo de ingeniería. ¿Lento dónde? ¿Está bloqueada la CPU de la base de datos? ¿La red móvil es inestable? ¿Se está agotando el tiempo de espera de la API de envío de terceros? ¿Implementamos un código incorrecto ayer?

Si su estrategia de depuración se basa en console.log y en la verificación de los gráficos de la CPU del servidor, está depurando en la oscuridad. El monitoreo le indica que el sistema no funciona (Panel rojo). La observabilidad te dice por qué se rompió.

En Maison Code Paris, operamos plataformas comerciales de alto tráfico donde 1 minuto de inactividad equivale a decenas de miles de euros. No adivinamos. Usamos instrumentación de código para obtener visión de rayos X en la pila distribuida.

Por qué Maison Code habla de esto

En Maison Code Paris, actuamos como la conciencia arquitectónica de nuestros clientes. A menudo heredamos stacks “modernos” construidos sin una comprensión fundamental de la escala.

Discutimos este tema porque representa un punto de inflexión crítico en la madurez de la ingeniería. Implementarlo correctamente diferencia un MVP frágil de una plataforma resistente de nivel empresarial.

Los tres pilares de la observabilidad

Para comprender un sistema complejo, se necesitan tres tipos distintos de datos de telemetría:

  1. Registros: Eventos discretos. “Algo pasó a las 10:00:01”.
  2. Métricas: Números agregados. “La CPU estuvo al 80 % durante 5 minutos”.
  3. Traces: el ciclo de vida de una solicitud. “El usuario hizo clic en el botón -> API -> DB -> API -> UI”.

1. Registros: estructurados y con capacidad de búsqueda

A los desarrolladores les encanta console.log("Error de usuario no encontrado" + id). Los DevOps lo odian. En un sistema que produce 1000 registros por segundo, la búsqueda de “Usuario con error” es lenta. Analizarlo es imposible. No se puede graficar la “tasa de errores por ID de usuario”.

La regla de oro: los registros deben ser JSON estructurado.

{
  "nivel": "error",
  "message": "Tiempo de espera de la pasarela de pago",
  "marca de tiempo": "2025-10-23T14:00:00Z",
  "servicio": "api de pago",
  "contexto": {
    "ID de usuario": "u_123",
    "cartId": "c_456",
    "puerta de enlace": "raya",
    "latencia": 5002
  },
  "traceId": "a1b2c3d4e5f6"
}

Ahora, en herramientas como Datadog o ELK (Elasticsearch), puedes ejecutar consultas:

  • servicio:checkout-api @context.gateway:stripe @nivel:error
  • “Muéstrame un gráfico de errores de pago agrupados por Gateway”.

2. Métricas: El Pulso

Las métricas son baratas de almacenar. Son sólo números.

  • Contadores: “Solicitudes totales” (Sube).
  • Indicadores: “Uso de memoria” (Sube y baja).
  • Histogramas: “Distribución de latencia” (95 % de las solicitudes < 200 ms).

La trampa de la cardinalidad: Los ingenieros jóvenes a menudo intentan etiquetar métricas con datos de alta cardinalidad. http_request_duration_segundos{user_id="u_123"}. Si tiene 1 millón de usuarios, crea 1 millón de series temporales. Esto bloqueará su servidor Prometheus o arruinará su cuenta Datadog. Regla: Las métricas son para Salud del sistema. Los registros/rastreos son para Específicos del usuario.

3. Seguimiento: el contexto

En una arquitectura de microservicios o sin cabeza, un solo clic de usuario llega a: CDN -> Función Edge -> API de nodo -> Base de datos -> API de terceros. Si la solicitud tarda 3 segundos, una métrica dice “Latencia alta”. Un Rastreo te muestra:

  • API de nodo: 10 ms
  • Base de datos: 5 ms
  • API de envío: 2900 ms

El rastreo resuelve el “juego de la culpa”.

OpenTelemetry: el estándar de la industria

Históricamente, tenías que instalar el SDK de Datadog o el SDK de New Relic. Si quería cambiar de proveedor, tenía que reescribir el código. OpenTelemetry (OTel) es el estándar abierto (CNCF) para recopilar telemetría. Instrumentas tu código una vez con OTel. Luego puede canalizar esos datos a Datadog, Prometheus, Jaeger o simplemente a stdout.

Instrumentación automática de Node.js

OTel moderno permite la “Auto-Instrumentación”. No reescribes tus controladores Express. Parcha bibliotecas estándar (http, pg, redis) en tiempo de ejecución.

// instrumentación.ts
importar {NodeSDK} desde '@opentelemetry/sdk-node';
importar {HttpInstrumentation} desde '@opentelemetry/instrumentation-http';
importar {PgInstrumentation} desde '@opentelemetry/instrumentation-pg';
importar {OTLPTraceExporter} desde '@opentelemetry/exporter-trace-otlp-proto';

const sdk = nuevo NodeSDK({
  traceExporter: nuevo OTLPTraceExporter ({
    url: 'https://api.honeycomb.io/v1/traces', // O su coleccionista
  }),
  instrumentaciones: [
    new HttpInstrumentation(), // Rastrea todos los HTTP entrantes/salientes
    new PgInstrumentation(), // Rastrea todas las consultas de Postgres
  ],
  nombre del servicio: 'maison-code-api',
});

sdk.start();

Con este archivo de 20 líneas, tendrá instantáneamente gráficos en cascada para cada consulta de base de datos y llamada API en su sistema de producción.

Propagación del contexto de seguimiento

¿Cómo sabe la base de datos qué “clic del usuario” provocó la consulta? Propagación de contexto. Cuando el Servicio A llama al Servicio B, inyecta un encabezado HTTP genérico: traceparent. traceparente: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01

El servicio B lee este encabezado. Comienza su propio lapso, utilizando la ID de A como “ID del padre”. Esto vincula las operaciones distribuidas en un único DAG (gráfico acíclico dirigido).

RUM (Monitoreo de usuarios reales)

La observabilidad del lado del servidor funciona perfectamente, pero los usuarios todavía se quejan. “Hice clic en el botón y no pasó nada”. Registros del servidor: “No se recibió ninguna solicitud”. Conclusión: JavaScript falló en el navegador antes de enviar la solicitud.

Para la observabilidad del frontend, utilizamos RUM (Sentry, LogRocket). Captura automáticamente:

  1. Core Web Vitals: pintura con contenido más grande (LCP), interacción con la siguiente pintura (INP).
  2. Errores de consola: indefinido no es una función.
  3. Repetición de sesión: una grabación similar a un vídeo de los movimientos del mouse del usuario.

Estudio de caso: Tuvimos un error de pago con 0 registros. Al mirar la repetición de la sesión, vimos que los usuarios del iPhone SE (pantalla pequeña) no podían desplazarse hasta el botón “Pagar” porque un “banner de cookies” lo cubría con .zIndex: 9999. Ningún registro podría habernos dicho eso. La observabilidad visual lo hizo.

Filosofía de alerta: principios de SRE

No llame al ingeniero a las 3 a.m. porque “la CPU está al 90%”. Quizás el 90% esté bien. Quizás la cola se esté procesando rápidamente. Alerta sobre síntomas, no sobre causas.

SLI (Indicador de Nivel de Servicio): Una métrica que le importa al usuario.

  • Ejemplo: “Disponibilidad de la página de inicio”.
  • Ejemplo: “Latencia de pago”.

SLO (Objetivo de Nivel de Servicio): El objetivo.

  • “La página de inicio debe estar 200 OK el 99,9% del tiempo”.
  • “El pago debe ser inferior a 2 chelines el 95 % del tiempo”.

Condición de alerta:

  • “Si tasa de error > 0,1% durante 5 minutos -> PagerDuty”.
  • “Si tasa de error > 5% -> Despierte al CEO”.

El costo de la observabilidad

Observarlo todo es caro. Si rastrea el 100% de las solicitudes, su factura de monitoreo podría exceder su factura de alojamiento. El muestreo es la solución.

  • Muestreo basado en cabeza: Decida al inicio de una solicitud. “Rastree el 10% de los usuarios”.
  • Muestreo basado en cola (avanzado): mantiene todos los rastros en la memoria. Si ocurre un error, envíe el seguimiento completo. Si tiene éxito, deséchelo.
    • Esto garantiza que capture el 100% de los errores pero el 0% de los aburridos registros de éxito.

10. Monitoreo de la lógica empresarial (Las señales de oro)

Los gráficos de CPU no pagan las cuentas. Pedidos pagan las facturas. Los registros de acceso no le indican si el botón “Agregar al carrito” está roto (si está roto, no hay registros). Definimos Métricas de Negocio:

  • pedidos_por_minuto
  • add_to_cart_value_total
  • tasa_de_rechazo_pasarela_de_pago Configuramos alertas de “Detección de anomalías”. “Si los pedidos/mínimo caen un 50% respecto al martes pasado -> PagerDuty”. Esto detecta “fallos silenciosos” (por ejemplo, un detector de eventos de Javascript roto) que los registros del servidor nunca verán.

11. Estrategias de control de costos

El perro de datos es caro. Almacenar cada console.log es un desperdicio. Implementamos Niveles de registro por entorno:

  • Desarrollo: Depurar (Todo). *Producción: Información (Eventos Clave) + Error. También utilizamos Filtros de exclusión a nivel de agente: “Elimine todos los registros que contengan Health Check OK”. Esto reduce el volumen en un 40% sin perder señal.

12. La explosión de la cardinalidad (Cómo arruinar la observabilidad)

Empieza inocente. metrics.increment('request_duration', {url: req.url }) Luego, un bot presiona /login?random=123. Luego /login?random=456. De repente, tienes 1 millón de valores de etiquetas únicos. Datadog le cobra por “Métricas personalizadas”. Factura: €15,000 / mes. Solución: Normaliza tus dimensiones. Reemplace /login?random=123 con /login?random=* en su middleware antes de emitir la métrica.

13. Registro de ROI: ¿Este registro vale €0,001?

Tratamos los troncos como bienes raíces. “Usuario conectado” -> Valor alto. Conservar durante 30 días. “Chequeo de salud aprobado” -> Valor bajo. Bájese inmediatamente. “Volcado de matriz de depuración” -> Valor negativo. Abarrota la búsqueda. Implementamos Muestreo Dinámico: Durante un incidente, active DEBUG para el 1% de los usuarios. Durante tiempos de paz, mantenlo apagado.

14. Conclusión

La observabilidad es la diferencia entre “Creo que funciona” y “Sé que funciona”. Cambia la cultura de “Culpa” (“El equipo de red falló”) a “Datos” (“El seguimiento muestra un tiempo de espera de 500 ms en el conmutador”).

En un entorno moderno, distribuido y de alto riesgo, el código sin instrumentación apenas es código. Es una caja negra esperando confundirte.


**[Contrate a nuestros arquitectos](/contact)**.