Definition
Imagina intentar entender la salud de tu coche sin un tablero - sin velocímetro, sin medidor de combustible, sin luz de advertencia de temperatura del motor. Estarías conduciendo a ciegas, solo descubriendo problemas cuando algo catastrófico pasara. Las métricas son el tablero de tu aplicación: mediciones numéricas que te dicen qué tan rápido vas, cuánto combustible te queda, y si el motor se está sobrecalentando.
Las métricas son datos de series temporales que capturan mediciones cuantitativas sobre el comportamiento de tu sistema. A diferencia de los logs (que capturan eventos individuales) o las trazas (que siguen rutas de peticiones), las métricas agregan información en números: tasa de peticiones (peticiones por segundo), latencia (P50, P95, P99), tasa de error (porcentaje de peticiones fallidas), y utilización de recursos (CPU, memoria, conexiones). Estos números te dicen el “qué” de la salud del sistema de un vistazo.
El poder de las métricas está en su eficiencia y comparabilidad. Mientras que almacenar el log completo de cada petición podría ser prohibitivo, almacenar “procesamos 10,000 peticiones/segundo con latencia del percentil 99 de 200ms” es barato e inmediatamente útil. Las métricas habilitan dashboards, alertas, planificación de capacidad, y análisis de tendencias. Son la base de los SLIs (Service Level Indicators) que definen si estás cumpliendo tus promesas a los usuarios.
Example
Las Cuatro Señales Doradas en Google: El equipo SRE de Google monitorea cuatro métricas clave para cada servicio: Latencia (cuánto tardan las peticiones), Tráfico (cuántas peticiones recibes), Errores (qué porcentaje falla), y Saturación (qué tan “llenos” están tus recursos). Estas cuatro métricas capturan la esencia de la salud del servicio.
Dashboard de Black Friday en E-commerce: Amazon monitorea miles de métricas durante picos de compras. Las métricas muestran peticiones por segundo subiendo de 10K a 100K, latencia de checkout manteniéndose bajo 500ms, tasa de error manteniéndose en 0.1%, y conexiones de base de datos acercándose a límites. Un vistazo al dashboard dice a los operadores si están sobreviviendo la carga.
Aplicación de Rate Limiting de API: Cloudflare rastrea tasas de petición por clave API como métricas. Cuando una clave excede 1000 peticiones/minuto (visible como un pico en el gráfico de métricas), el rate limiting entra en acción. Las métricas históricas muestran qué clientes consistentemente alcanzan límites y podrían necesitar cuotas más altas.
Calidad de Streaming en Netflix: Netflix monitorea métricas como eventos de buffering por hora de espectador, tiempo de inicio de video, y estabilidad de bitrate. Una métrica mostrando “eventos de buffering aumentaron 50% en la última hora en región EU” inmediatamente dispara investigación, frecuentemente capturando problemas antes de que los usuarios se quejen.
Autoescalado de Cluster Kubernetes: Las plataformas cloud usan métricas (utilización de CPU, presión de memoria, profundidad de cola de peticiones) para escalar recursos automáticamente. Cuando el CPU promedio entre pods excede 80% por 5 minutos, las métricas disparan horizontal pod autoscaling para añadir más instancias.
Analogy
El Tablero del Coche: El tablero de tu coche muestra velocidad, RPM, nivel de combustible, y temperatura del motor - todas métricas. No necesitas entender cada componente del motor; los medidores te dicen si todo está normal o si deberías detenerte inmediatamente. Las métricas de aplicación sirven el mismo propósito.
El Monitor de Signos Vitales del Hospital: En un hospital, los pacientes están conectados a monitores mostrando frecuencia cardíaca, presión arterial, saturación de oxígeno, y temperatura. Los doctores miran estos números para evaluar la salud del paciente sin correr pruebas diagnósticas completas cada minuto. Las métricas son los signos vitales de tu aplicación.
El Ticker del Mercado de Valores: Los precios de acciones son métricas - números que cambian a lo largo del tiempo, inmediatamente visibles, comparables a través del tiempo y entre acciones. Así como los inversores usan métricas de acciones para decisiones, los operadores usan métricas de aplicación para decisiones de capacidad y confiabilidad.
El Rastreador de Fitness: Tu rastreador de fitness registra pasos, frecuencia cardíaca, calidad de sueño, y calorías como números a lo largo del tiempo. Las tendencias semanales muestran si te estás volviendo más saludable o necesitas cambiar hábitos. Las métricas de aplicación similarmente muestran tendencias de salud del sistema.
Code Example
// Implementación de métricas estilo Prometheus
import { Registry, Counter, Histogram, Gauge } from 'prom-client';
const registry = new Registry();
// Counter: solo sube (peticiones, errores, bytes procesados)
const requestsTotal = new Counter({
name: 'http_requests_total',
help: 'Número total de peticiones HTTP',
labelNames: ['method', 'path', 'status'],
registers: [registry]
});
// Histogram: mide distribuciones (latencia, tamaño de petición)
const requestDuration = new Histogram({
name: 'http_request_duration_seconds',
help: 'Duración de petición HTTP en segundos',
labelNames: ['method', 'path'],
buckets: [0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
registers: [registry]
});
// Gauge: puede subir o bajar (conexiones, tamaño de cola, temperatura)
const activeConnections = new Gauge({
name: 'active_connections',
help: 'Número de conexiones activas',
registers: [registry]
});
const queueSize = new Gauge({
name: 'job_queue_size',
help: 'Número de trabajos esperando en cola',
labelNames: ['queue_name'],
registers: [registry]
});
// Middleware para recolectar métricas
function metricsMiddleware(req: Request, res: Response, next: NextFunction) {
const startTime = Date.now();
activeConnections.inc();
res.on('finish', () => {
const duration = (Date.now() - startTime) / 1000;
const labels = {
method: req.method,
path: req.route?.path || req.path,
status: res.statusCode.toString()
};
requestsTotal.inc(labels);
requestDuration.observe(
{ method: req.method, path: req.route?.path || req.path },
duration
);
activeConnections.dec();
});
next();
}
// Métricas de negocio
const paymentsProcessed = new Counter({
name: 'payments_processed_total',
help: 'Total de pagos procesados',
labelNames: ['currency', 'status'],
registers: [registry]
});
const paymentAmount = new Histogram({
name: 'payment_amount_dollars',
help: 'Montos de pago en dólares',
buckets: [10, 50, 100, 500, 1000, 5000, 10000],
registers: [registry]
});
// Uso en código de aplicación
async function processPayment(payment: Payment) {
const timer = requestDuration.startTimer({ method: 'POST', path: '/payments' });
try {
const result = await paymentService.process(payment);
paymentsProcessed.inc({
currency: payment.currency,
status: 'success'
});
paymentAmount.observe(payment.amount);
return result;
} catch (error) {
paymentsProcessed.inc({
currency: payment.currency,
status: 'failed'
});
throw error;
} finally {
timer();
}
}
// Exponer endpoint de métricas para scraping de Prometheus
app.get('/metrics', async (req, res) => {
res.set('Content-Type', registry.contentType);
res.end(await registry.metrics());
});
// Ejemplo de salida de métricas:
// # HELP http_requests_total Número total de peticiones HTTP
// # TYPE http_requests_total counter
// http_requests_total{method="GET",path="/api/users",status="200"} 15420
// http_requests_total{method="POST",path="/api/payments",status="201"} 3241
// http_requests_total{method="POST",path="/api/payments",status="400"} 127
//
// # HELP http_request_duration_seconds Duración de petición HTTP en segundos
// # TYPE http_request_duration_seconds histogram
// http_request_duration_seconds_bucket{method="GET",path="/api/users",le="0.1"} 14200
// http_request_duration_seconds_bucket{method="GET",path="/api/users",le="0.5"} 15100
// http_request_duration_seconds_sum{method="GET",path="/api/users"} 892.5
// http_request_duration_seconds_count{method="GET",path="/api/users"} 15420
Diagram
flowchart TB
subgraph MetricTypes["Tipos de Métricas"]
C[Counter
Solo aumenta]
G[Gauge
Sube y baja]
H[Histogram
Buckets de distribución]
S[Summary
Cuantiles]
end
subgraph Examples["Ejemplos"]
C1[Total de peticiones
Conteo de errores
Bytes procesados]
G1[Conexiones activas
Tamaño de cola
Temperatura]
H1[Latencia de petición
Tamaño de respuesta
Montos de pago]
S1[Percentiles
P50, P95, P99]
end
subgraph Pipeline["Pipeline de Métricas"]
A[Aplicación] --> P[Prometheus
Scraper]
P --> T[(Time Series DB)]
T --> D[Grafana
Dashboard]
T --> L[Alert Manager]
end
C --> C1
G --> G1
H --> H1
S --> S1
style C fill:#93c5fd
style G fill:#86efac
style H fill:#fcd34d
style S fill:#f9a8d4
Best Practices
- Usa el método RED para servicios - Rate (peticiones/seg), Errors (tasa de error), Duration (latencia) cubren la mayoría de necesidades de monitoreo
- Usa el método USE para recursos - Utilización, Saturación, Errores para CPU, memoria, disco, red
- Elige tipos de métricas apropiados - Counters para cosas que solo aumentan, Gauges para cosas que suben/bajan, Histograms para distribuciones
- Usa labels significativas - Pero no demasiadas; labels de alta cardinalidad (como user_id) pueden explotar costos de almacenamiento
- Define SLIs basados en métricas - “99% de peticiones completan en menos de 200ms” es medible desde histogramas de latencia
- Configura alertas sobre métricas - Tasa de error > 1%, latencia P99 > 500ms, CPU > 80% por 5 minutos
- Crea dashboards para diferentes audiencias - Resumen ejecutivo, ingenieros de guardia, y debugging detallado cada uno necesita diferentes vistas
- Mide métricas de negocio - Órdenes procesadas, ingresos, registros de usuario - no solo métricas técnicas
- Mantén nombres de métricas consistentes - Usa convenciones de nombrado como
service_operation_unit(ej.,http_requests_total) - Monitorea tu monitoreo - Asegura que tu pipeline de métricas esté saludable y no esté perdiendo datos
Common Mistakes
Demasiadas labels (alta cardinalidad): Usar user_id como label crea millones de series temporales, explotando costos de almacenamiento y tiempos de consulta.
Medir todo: Recolectar cada métrica posible es caro y ruidoso. Enfócate en métricas que impulsen decisiones.
Ignorar percentiles: Los promedios ocultan problemas. Latencia P99 de 10 segundos significa que 1% de usuarios tienen experiencia terrible, incluso si el promedio es 100ms.
Sin líneas base: Sin saber cómo luce “normal”, no puedes detectar anomalías. Establece líneas base antes de alertar.
Alertar sobre cosas incorrectas: Alertar sobre utilización de CPU es menos útil que alertar sobre tasa de error o latencia - enfócate en síntomas que experimentan los usuarios.
Caos en nombrado de métricas: Nombrado inconsistente (request_count vs requestsTotal vs http_reqs) hace dashboards y consultas dolorosos.
No medir resultados de negocio: Las métricas técnicas importan, pero últimamente te importan órdenes colocadas, usuarios retenidos, ingresos generados.
Gaps en recolección de métricas: Métricas faltantes de algunos servicios crea puntos ciegos. Asegura cobertura consistente.