El Stack de Monitoreo Moderno
Prometheus y Grafana forman el stack de monitoreo open-source estándar de la industria. Prometheus recolecta y almacena métricas de series temporales, mientras Grafana las visualiza a través de dashboards personalizables. Para ingenieros QA, este stack proporciona insights en tiempo real sobre rendimiento de aplicaciones, salud de infraestructura y métricas de experiencia de usuario.
¿Por qué Prometheus + Grafana?
- Modelo Pull-Based - Prometheus extrae métricas de targets, no se necesita push desde el cliente
- Lenguaje de Consulta Poderoso (PromQL) - Consultas flexibles y agregación de métricas
- Service Discovery - Descubrimiento automático de targets en entornos dinámicos (Kubernetes, AWS, etc.)
- Alertas - Alert manager integrado con enrutamiento y silenciamiento
- Open Source - Sin vendor lock-in, gran soporte comunitario
- Visualización Grafana - Dashboards ricos con soporte multi data source
Arquitectura Prometheus
Componentes Principales
# Resumen arquitectura Prometheus
components:
prometheus_server:
- scrapes_metrics: true
- stores_timeseries: true
- evaluates_rules: true
exporters:
- node_exporter: "Métricas sistema (CPU, memoria, disco)"
- blackbox_exporter: "Probar endpoints (HTTP, DNS, TCP)"
- custom_exporters: "Métricas específicas de aplicación"
pushgateway:
- for_batch_jobs: true
- short_lived_processes: true
alertmanager:
- handles_alerts: true
- routes_notifications: true
- silences_alerts: true
service_discovery:
- kubernetes: true
- consul: true
- ec2: true
- dns: true
Instalar Prometheus
# Instalación Docker
docker run -d \
--name prometheus \
-p 9090:9090 \
-v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
# Instalación Kubernetes (usando Helm)
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/prometheus
# Archivo configuración: prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
static_configs:
- targets: ['localhost:9100']
- job_name: 'application'
static_configs:
- targets: ['app:8080']
metrics_path: '/metrics'
Instrumentar Aplicaciones
Aplicación Node.js
// app.js
const express = require('express');
const promClient = require('prom-client');
const app = express();
const register = promClient.register;
// Habilitar métricas por defecto (CPU, memoria, event loop lag)
promClient.collectDefaultMetrics({ register });
// Métricas personalizadas
const httpRequestDuration = new promClient.Histogram({
name: 'http_request_duration_seconds',
help: 'Duración de solicitudes HTTP en segundos',
labelNames: ['method', 'route', 'status_code'],
buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10]
});
const httpRequestTotal = new promClient.Counter({
name: 'http_requests_total',
help: 'Total de solicitudes HTTP',
labelNames: ['method', 'route', 'status_code']
});
const activeConnections = new promClient.Gauge({
name: 'active_connections',
help: 'Número de conexiones activas'
});
// Middleware para rastrear métricas
app.use((req, res, next) => {
const start = Date.now();
activeConnections.inc();
res.on('finish', () => {
const duration = (Date.now() - start) / 1000;
httpRequestDuration
.labels(req.method, req.route?.path || req.path, res.statusCode)
.observe(duration);
httpRequestTotal
.labels(req.method, req.route?.path || req.path, res.statusCode)
.inc();
activeConnections.dec();
});
next();
});
// Endpoint métricas
app.get('/metrics', async (req, res) => {
res.set('Content-Type', register.contentType);
res.end(await register.metrics());
});
// Lógica negocio
app.get('/api/users', async (req, res) => {
// Tu lógica aquí
res.json({ users: [] });
});
app.listen(3000, () => {
console.log('Servidor ejecutando en puerto 3000');
console.log('Métricas disponibles en http://localhost:3000/metrics');
});
PromQL: El Lenguaje de Consulta
Consultas Básicas
# Vector instantáneo - valor actual
http_requests_total
# Filtrar por labels
http_requests_total{method="GET", status_code="200"}
# Vector de rango - valores a lo largo del tiempo
http_requests_total[5m]
# Tasa de incremento (por segundo)
rate(http_requests_total[5m])
# Incremento durante período de tiempo
increase(http_requests_total[1h])
PromQL Avanzado
# Tasa de solicitudes por endpoint
sum(rate(http_requests_total[5m])) by (route)
# Porcentaje tasa de error
(
sum(rate(http_requests_total{status_code=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m]))
) * 100
# Latencia P95
histogram_quantile(0.95,
rate(http_request_duration_seconds_bucket[5m])
)
# Porcentaje disponibilidad
(
sum(up{job="application"})
/ count(up{job="application"})
) * 100
# Tasa crecimiento uso memoria
deriv(node_memory_MemAvailable_bytes[1h])
Dashboards Grafana
Instalar Grafana
# Instalación Docker
docker run -d \
--name=grafana \
-p 3000:3000 \
grafana/grafana
# Añadir data source Prometheus
# Navegar a: http://localhost:3000 (admin/admin)
# Configuration → Data Sources → Add Prometheus
# URL: http://prometheus:9090
Crear Dashboard de Rendimiento
{
"dashboard": {
"title": "Rendimiento Aplicación",
"panels": [
{
"title": "Tasa Solicitudes",
"targets": [
{
"expr": "sum(rate(http_requests_total[5m])) by (route)",
"legendFormat": "{{route}}"
}
],
"type": "graph"
},
{
"title": "Tasa Error",
"targets": [
{
"expr": "(sum(rate(http_requests_total{status_code=~\"5..\"}[5m])) / sum(rate(http_requests_total[5m]))) * 100",
"legendFormat": "Error %"
}
],
"type": "graph"
}
]
}
}
Alertas con Prometheus & Grafana
Reglas de Alerta Prometheus
# alerts.yml
groups:
- name: performance_alerts
interval: 30s
rules:
- alert: TasaErrorAlta
expr: |
(sum(rate(http_requests_total{status_code=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m]))) * 100 > 5
for: 5m
labels:
severity: critical
annotations:
summary: "Tasa error alta detectada"
description: "Tasa error es {{ $value }}% (umbral: 5%)"
- alert: LatenciaAlta
expr: |
histogram_quantile(0.95,
rate(http_request_duration_seconds_bucket[5m])
) > 2
for: 10m
labels:
severity: warning
annotations:
summary: "Latencia alta en {{ $labels.route }}"
description: "Latencia P95 es {{ $value }}s"
Mejores Prácticas Monitoreo
Las Cuatro Señales Doradas
# 1. LATENCIA - Duración solicitud
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket[5m])) by (le)
)
# 2. TRÁFICO - Tasa solicitud
sum(rate(http_requests_total[5m]))
# 3. ERRORES - Tasa error
sum(rate(http_requests_total{status_code=~"5.."}[5m]))
# 4. SATURACIÓN - Utilización recursos
avg(rate(node_cpu_seconds_total{mode!="idle"}[5m])) * 100
Conclusión
Prometheus y Grafana proporcionan un stack de monitoreo poderoso y flexible para ingenieros QA. Desde instrumentar aplicaciones hasta crear dashboards perspicaces y configurar alertas inteligentes, este stack habilita monitoreo proactivo de rendimiento y detección rápida de problemas.
Conclusiones Clave:
- Instrumentar aplicaciones con métricas personalizadas
- Dominar PromQL para consultas poderosas
- Crear dashboards accionables con Grafana
- Configurar alertas basadas en SLOs/SLIs
- Seguir metodologías monitoreo: RED, USE, Cuatro Señales Doradas
- Integrar monitoreo en workflows de pruebas de carga
El monitoreo efectivo no es solo recolectar métricas — es convertir datos en insights accionables.