DevPath · Aprende a programar ESPTEN

Observabilidad y rendimiento

Los tres pilares de la observabilidad

Monitorización vs. observabilidad

Monitorizar es vigilar señales que ya sabes que importan (¿está vivo el servidor? ¿cuánta CPU usa?). Observabilidad es poder responder preguntas que no habías anticipado a partir de lo que el sistema emite. La diferencia práctica: cuando algo falla a las 3 de la madrugada, ¿tienes datos suficientes para entender por qué, sin desplegar código nuevo?

Esos datos se apoyan en tres pilares: logs, métricas y trazas. Son complementarios, no intercambiables.

1. Logs estructurados

Un log es un registro de un evento puntual. El error clásico es escribir texto libre (console.log("usuario " + id + " hizo login")): legible para una persona, inservible para una máquina. Un log estructurado es un objeto (que se serializa a JSON) con campos consistentes:

{ "nivel": "info", "mensaje": "login", "usuarioId": 42, "ts": "2026-06-22T10:00:00Z", "requestId": "abc-123" }

Así puedes filtrar y agregar: "dame todos los error del usuarioId 42 en la última hora". Cada log lleva un nivel que indica su gravedad y permite silenciar el ruido en producción:

2. Métricas

Una métrica es un número agregado en el tiempo, barato de almacenar (no guardas cada evento, sino su recuento o distribución). Tipos habituales:

Sobre la latencia, nunca mires solo la media: una media de 100 ms puede esconder que 1 de cada 20 usuarios espera 3 segundos. Por eso se usan percentiles. El p95 es el valor por debajo del cual cae el 95 % de las peticiones: "el 95 % responde en menos de 200 ms". El p99 captura la cola, la peor experiencia. Mejorar el p95/p99 suele importar más que mejorar la media.

3. Trazas (distributed tracing)

En un sistema con varios servicios, una sola petición del usuario cruza muchos saltos: gateway → servicio de pedidos → base de datos → servicio de pagos. Una traza sigue esa petición de extremo a extremo. Cada salto es un span con su duración, y todos comparten un mismo request id (o trace id) que se propaga en las cabeceras. Así ves dónde se va el tiempo: si la petición tarda 800 ms, la traza te dice que 700 fueron en una consulta lenta a la BD.

Ese mismo requestId debe ir también en los logs: es el hilo que cose los tres pilares. Con él saltas de "esta petición fue lenta" (traza) a "y además registró este error" (log).

Lo que construyes encima

Regla práctica: instrumenta primero los golden signals — latencia, tráfico, errores y saturación. Cubren la mayoría de los incidentes.

Ejemplos

Un log estructurado en JSON, listo para indexar

function log(nivel, mensaje, contexto = {}) {
  return JSON.stringify({
    nivel,
    mensaje,
    ts: new Date().toISOString(),
    ...contexto,
  });
}

console.log(log("error", "pago rechazado", { usuarioId: 42, requestId: "abc-123" }));

p95: el percentil 95 de una lista de latencias (ms)

function percentil(valores, p) {
  const orden = [...valores].sort((a, b) => a - b);
  const i = Math.ceil((p / 100) * orden.length) - 1;
  return orden[Math.max(0, i)];
}

const latencias = [80, 90, 95, 100, 110, 120, 130, 140, 150, 900];
console.log("p95:", percentil(latencias, 95), "ms"); // la cola asoma
Pon esto en práctica

DevPath es un curso práctico: aquí lees la teoría; en la app la pones en práctica con ejercicios que se ejecutan de verdad, sin conexión.

Empezar gratis en la app →
Rendimiento: caché, lazy loading y la BD →