Métricas y Dashboards: Guía de Prometheus y Grafana
Guía práctica sobre métricas y dashboards: instrumentación de aplicaciones, elección de tipos de métricas, control de cardinalidad, construcción de dashboards útiles y creación de pipelines de alertas con Prometheus, Grafana y Datadog.
Descripción General
Las métricas son mediciones numéricas recolectadas a lo largo del tiempo que te indican cómo se comportan tus sistemas. Los dashboards visualizan esas métricas para que los patrones sean visibles de un vistazo. Juntas son la base de la conciencia operativa: sin ellas estás adivinando, con ellas puedes detectar tendencias, identificar anomalías y defender decisiones de capacidad con datos.
Esta guía cubre el pipeline completo — instrumentar tu código, recolectar y almacenar series temporales, diseñar dashboards que la gente realmente usa, y conectar alertas encima. Profundiza en tipos de métricas, cardinalidad y PromQL, que es donde la mayoría de los equipos se complica.
Dos temas adyacentes tienen sus propias guías y no se repiten aquí: el ciclo de vida de las alertas (escalación, guardias, fatiga de alertas) está en la Guía de Gestión de Alertas, y el panorama de los tres pilares (métricas + logs + trazas juntos) está en la Guía de Observabilidad. Si necesitas alguno de esos, ve directo ahí — esta guía se concentra en el lado de las métricas.
Un chequeo rápido de cómo se ve “bien hecho”: un servicio con 20-40 métricas bien nombradas, una config de scrape que descubre targets automáticamente, un dashboard de señales doradas por servicio, un SLO con política de presupuesto de error escrita, y unas pocas alertas de burn rate que despiertan humanos lo suficientemente poco como para que sigan confiando en el pager. Eso es todo. El resto — cientos de dashboards, cincuenta reglas de alerta, una plataforma de monitoreo a medida — es decoración opcional sobre ese núcleo.
Cuándo Usar
- Necesitas monitorear salud y rendimiento del sistema a lo largo del tiempo
- Quieres detectar tendencias antes de que se conviertan en incidentes
- Tu equipo necesita una imagen operativa compartida
- Estás estableciendo SLOs y necesitas medir cumplimiento
- Quieres reducir el MTTR con datos visuales y consultables en lugar de bucear en logs
Cuándo no usar esta guía: si tu problema es que las alertas disparan demasiado seguido, las páginas llegan a la persona equivocada o las guardias están quemando gente, eso es un problema de proceso de alertado — la Guía de Gestión de Alertas lo cubre. Si estás eligiendo entre métricas, logs y trazas para un flujo de depuración concreto, empieza por la guía paraguas.
Conceptos Clave
| Concepto | Descripción |
|---|---|
| Counter | Métrica acumulativa que solo aumenta (peticiones servidas, errores) |
| Gauge | Métrica que puede subir o bajar (temperatura, profundidad de cola, CPU) |
| Histogram | Muestrea observaciones en buckets configurables (duración de petición) |
| Summary | Similar a histogram pero calcula percentiles del lado del cliente |
| Cardinalidad | Número de series temporales únicas (alta cardinalidad = costosa) |
| SLI / SLO / SLA | Indicador, Objetivo y Acuerdo de Nivel de Servicio |
| Regla de grabación | Resultado PromQL precomputado guardado como nueva serie temporal |
| Exemplar | Muestra de métrica anotada con un trace ID para saltar a la petición |
Un modelo que conviene interiorizar pronto: cada métrica es una serie temporal identificada por su nombre más su conjunto de labels. http_requests_total{status="200", path="/orders"} y http_requests_total{status="500", path="/orders"} son dos series distintas. Los labels son cómo segmentas los datos después — y también cómo explotas el almacenamiento.
Tipos de Métricas y Cuándo Usarlas
| Tipo | Caso de Uso | Ejemplo | No Usar Para |
|---|---|---|---|
| Counter | Contar eventos | http_requests_total | Valores que disminuyen |
| Gauge | Valores en un punto del tiempo | memory_usage_bytes, queue_size | Tasas o conteos acumulados |
| Histogram | Distribución de valores | request_duration_seconds | Cálculo exacto de percentiles (usa summary) |
| Summary | Percentiles precomputados | request_latency_quantile | Cuando necesitas heatmaps de histograma |
La decisión histogram-versus-summary confunde a mucha gente. Los histogramas agrupan observaciones en buckets del lado del servidor, así que puedes agregar entre instancias — histogram_quantile(0.95, sum(rate(...[5m])) by (le)) funciona en toda una flota. Las summaries calculan cuantiles dentro de cada proceso y no se pueden agregar después — un p95 de los p95s de diez servicios no significa nada. Usa histogramas por defecto; recurre a summaries solo para batch jobs que existen una vez y nunca se agregan.
Cardinalidad: La Métrica Que Te Cuesta Dinero
La cardinalidad se multiplica en silencio. Un contador con method (5 valores), status (5 clases) y path (40 endpoints) produce hasta 1.000 series por instancia — antes de que notes la explosión de labels. Añade pod (50 réplicas) y region (3 zonas) y estás en 150.000 series para una sola métrica. Prometheus se traga esto en RAM; los proveedores SaaS te lo cobran directamente.
El error clásico es etiquetar con valores sin límite: URLs crudas, IDs de usuario, IDs de sesión, query parameters, direcciones de email. Un equipo una vez envió labels path con URLs de petición completas — parámetros de tracking incluidos — y generó 2 millones de series en un fin de semana. La solución no es instrumentación heroica; es elegir labels de cardinalidad acotada desde el principio.
Mide lo que tienes antes de optimizar:
# Top familias de métricas por número de series
topk(15, count by (__name__)({__name__=~".+"}))
# Series por nombre de label (encuentra al culpable)
topk(10, count by (label_name)({__name__=~".+"}))
Mitigar es más barato en la ingesta que en la fuente: metric_relabel_configs puede eliminar un label o descartar la serie entera antes de que se almacene. Y si de verdad necesitas detalle por petición — la latencia de un usuario concreto, la ruta de un pedido específico — para eso están las trazas y los logs, no las métricas. La Guía de Distributed Tracing cubre ese lado.
Métricas y Dashboards Paso a Paso
El pipeline tiene cinco etapas: instrumentar, recolectar, visualizar, medir contra objetivos y alertar. Así encajan:
1. Instrumenta Tus Aplicaciones
Expone métricas en un formato que tu colector entienda:
# Ejemplo: Métricas de aplicación Python con cliente Prometheus
from prometheus_client import Counter, Histogram, Gauge, start_http_server
import time
# Definir métricas
http_requests_total = Counter(
'http_requests_total',
'Total HTTP requests',
['method', 'status', 'path']
)
request_duration_seconds = Histogram(
'request_duration_seconds',
'HTTP request duration',
['method', 'path'],
buckets=[0.01, 0.05, 0.1, 0.5, 1.0, 5.0]
)
active_connections = Gauge(
'active_connections',
'Number of active connections'
)
# Instrumentar tu código
@app.route("/api/orders/<order_id>")
def get_order(order_id):
start = time.time()
active_connections.inc()
try:
order = fetch_order(order_id)
http_requests_total.labels(method='GET', status='200', path='/api/orders').inc()
return jsonify(order)
except OrderNotFound:
http_requests_total.labels(method='GET', status='404', path='/api/orders').inc()
return jsonify({"error": "Not found"}), 404
finally:
request_duration_seconds.labels(method='GET', path='/api/orders').observe(time.time() - start)
active_connections.dec()
# Exponer endpoint de métricas
start_http_server(8000)
// Ejemplo: Spring Boot con Micrometer
@Configuration
public class MetricsConfig {
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return registry -> registry.config()
.commonTags("application", "orders-service");
}
}
@Service
public class OrderService {
private final Counter orderCounter;
private final Timer orderTimer;
public OrderService(MeterRegistry registry) {
this.orderCounter = Counter.builder("orders.processed")
.description("Total orders processed")
.register(registry);
this.orderTimer = Timer.builder("orders.processing.time")
.description("Order processing time")
.register(registry);
}
public Order processOrder(OrderRequest request) {
return orderTimer.recordCallable(() -> {
Order result = doProcess(request);
orderCounter.increment();
return result;
});
}
}
Checklist de instrumentación:
- Instrumenta las cuatro señales doradas: latencia, tráfico, errores, saturación
- Añade labels para dimensiones por las que filtrarás (servicio, entorno, endpoint)
- Usa nombres consistentes: sufijo
unit,totalpara contadores,secondspara duración - Evita labels de alta cardinalidad (IDs de usuario, IDs de sesión, IDs de petición)
- Mide métricas de negocio (pedidos realizados, pagos procesados) junto a las técnicas
Algo que el checklist no captura: elige los buckets del histograma para tu perfil de latencia real. Si tu objetivo de p99 es 300ms y tus buckets son [0.01, 0.05, 0.1, 0.5, 1.0, 5.0], no puedes distinguir una petición de 50ms de una de 499ms — ambas caen en el bucket le="0.5". Pon buckets alrededor de los umbrales sobre los que alertas.
Dos detalles de despliegue que conviene decidir pronto. Primero, sirve /metrics en un puerto dedicado (el ejemplo Python usa 8000) enlazado a una interfaz interna — el endpoint filtra el estado interno de tu servicio, así que no lo expongas públicamente ni tras la misma auth que el tráfico de usuarios. Segundo, mantén el endpoint barato: se hace scrape cada 15 segundos, y un endpoint de métricas que asigna mucha memoria o consulta la base de datos aparecerá en tus propios gráficos de latencia.
2. Recolecta y Almacena Métricas
Configura un pipeline de métricas:
# Ejemplo: Configuración de scrape de Prometheus
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
# Descartar labels de alta cardinalidad en la ingesta
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape_user_id]
action: drop
regex: true
Lo que funciona para recolección:
- Scrapea cada 10-30 segundos (más rápido para cambios de alta frecuencia)
- Usa descubrimiento de servicios (Kubernetes, Consul, DNS) en lugar de targets estáticos
- Ejecuta colectores en cada región/zona para minimizar latencia
- Usa remote write para almacenamiento a largo plazo (Thanos, Cortex, VictoriaMetrics)
- Federación para agregación jerárquica (edge → regional → global)
Las reglas de grabación merecen mención porque resuelven un problema real: dashboards que tardan 30 segundos en cargar. Si un panel ejecuta histogram_quantile(0.95, sum(rate(request_duration_seconds_bucket[5m])) by (le, service)) sobre un millón de series, precalcula:
# recording-rules.yml — evaluado cada 30s, guardado como series nuevas
groups:
- name: orders_sli
interval: 30s
rules:
- record: job_service:request_rate:5m
expr: sum(rate(http_requests_total[5m])) by (job, service)
- record: job:error_ratio:5m
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m]))
Las series grabadas se convierten en una métrica más — dashboards y alertas consultan job:error_ratio:5m en lugar de recomputar la división. También te da un nombre estable para alertar, útil cuando la query subyacente tiene que cambiar.
Sobre retención: el almacenamiento local de Prometheus es una ventana rodante, no un data lake. 15 días con scrape de 15 segundos es un default razonable para uso operativo; todo lo anterior va por remote-write a Thanos, Cortex o VictoriaMetrics con downsampling — conserva resolución de 15 segundos una semana, de 5 minutos un trimestre, de 1 hora un año. Consulta la resolución adecuada para la pregunta: no necesitas datos de 15 segundos para ver una tendencia mensual.
3. Construye Dashboards Útiles
Diseña dashboards que cuenten una historia:
| Tipo de Dashboard | Propósito | Paneles Clave |
|---|---|---|
| Resumen de servicio | Salud de un servicio individual | Tasa de error, latencia p95, throughput, uso de recursos |
| Señales doradas | Salud entre servicios | Métricas RED (Rate, Errors, Duration) por servicio |
| KPI de negocio | Impacto en ingresos/uso | Conversiones, usuarios activos, volumen de transacciones |
| Infraestructura | Salud de cluster/nodo | CPU, memoria, disco, red en todos los nodos |
| Respuesta a incidentes | Profundización durante incidentes | Latencia detallada por endpoint, desglose de errores, logs |
// Ejemplo: Fragmento JSON de dashboard Grafana (simplificado)
{
"dashboard": {
"title": "Orders Service - Golden Signals",
"panels": [
{
"title": "Request Rate",
"type": "timeseries",
"targets": [{
"expr": "sum(rate(http_requests_total{service=\"orders\"}[5m])) by (status)"
}]
},
{
"title": "Error Rate",
"type": "stat",
"targets": [{
"expr": "sum(rate(http_requests_total{service=\"orders\",status=~\"5..\"}[5m])) / sum(rate(http_requests_total{service=\"orders\"}[5m]))"
}],
"thresholds": [
{"value": 0.001, "color": "green"},
{"value": 0.01, "color": "yellow"},
{"value": 0.05, "color": "red"}
]
},
{
"title": "Latency p95",
"type": "timeseries",
"targets": [{
"expr": "histogram_quantile(0.95, sum(rate(request_duration_seconds_bucket{service=\"orders\"}[5m])) by (le))"
}]
}
]
}
}
Principios de diseño de dashboards:
- Pon los paneles más importantes arriba a la izquierda
- Usa colores consistentes: verde = bien, amarillo = advertencia, rojo = crítico
- Añade links a dashboards relacionados, logs y trazas
- Mantén el número de paneles por dashboard bajo 20
- Usa variables de plantilla para servicio, entorno y rango de tiempo
Un dashboard de resumen de servicio que funciona se parece a esto:
┌─ Señales doradas ────────────────────────────────────┐
│ Tasa de peticiones │ Ratio de error │ Latencia p95 │
├─ Saturación ─────────────────────────────────────────┤
│ CPU / memoria / profundidad de cola │
├─ Negocio ────────────────────────────────────────────┤
│ Pedidos/min │ Tasa de éxito de pagos │ Carritos │
├─ Drill-down (colapsado) ─────────────────────────────┤
│ Latencia por endpoint, desglose por pod, queries │
└──────────────────────────────────────────────────────┘
Las métricas de negocio merecen paneles de primera clase. orders_per_minute y payment_success_rate importan más a tus stakeholders que la latencia p99, y a menudo son el detector de incidentes más temprano — un deploy que mantiene la latencia plana pero reduce a la mitad las conversiones de pedidos es un deploy roto. Emítelas desde la misma instrumentación (orders_total, payment_attempts_total{result}) en lugar de mantener un pipeline de analítica separado para preguntas operativas.
Dos antipatrones a evitar. Primero, el “muro de gráficos”: cuarenta paneles de CPU y memoria cruda que nadie lee porque nada responde “¿está sano este servicio?”. Encabeza con paneles estilo SLI (ratio de error, cuantil de latencia, tasa de peticiones) y deja debajo una sección de drill-down para ingenieros en medio de un incidente. Segundo, dashboards que solo existen para demos — un dashboard que nadie abre durante una alerta es decoración. Revisa qué dashboards reciben tráfico; borra el resto.
3.5 Patrones PromQL Que Realmente Ayudan
Un puñado de formas de query cubre la mayoría del trabajo de dashboards y alertas:
| Patrón | Query | Uso |
|---|---|---|
| Tasa de eventos | rate(http_requests_total[5m]) | Throughput en el tiempo |
| Tasa instantánea | irate(http_requests_total[5m]) | Picos volátiles (solo gráficos — ruidosa para alertas) |
| Cambio en ventana | increase(http_requests_total[1h]) | Totales para informes |
| Percentil | histogram_quantile(0.95, rate(..._bucket[5m])) | SLIs de latencia |
| Top infractores | topk(5, ...) | ”¿Qué servicio se come la CPU?” |
| Datos ausentes | absent(http_requests_total{job="orders"}) | ”¿Está caído el exporter?” |
| Previsión capacidad | predict_linear(disk_free_bytes[6h], 4*24*3600) < 0 | ”¿Se llenará el disco en 4 días?” |
Dos trampas que vale la pena memorizar: rate() necesita al menos dos muestras en la ventana (usa [2*scrape_interval] como mínimo, y 5 minutos funciona mejor que 1 en la mayoría de gráficos). Y sum(rate()) agrega después del rate — rate(sum(...)) casi nunca es lo que quieres porque calcula la tasa de una suma que ya mezcló series.
4. Define SLIs y SLOs
Traduce métricas en objetivos de confiabilidad:
# Ejemplo: Consultas de SLI para objetivos comunes
# SLI de disponibilidad: % de peticiones exitosas
(
sum(rate(http_requests_total{status!~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
) * 100
# SLI de latencia: % de peticiones bajo umbral
(
sum(rate(request_duration_seconds_bucket{le="0.5"}[5m]))
/
sum(rate(request_duration_seconds_bucket{le="+Inf"}[5m]))
) * 100
# Presupuesto de error: errores aceptables restantes
# SLO: 99.9% disponibilidad
# Presupuesto de error: 0.1% del total de peticiones por mes
0.001 * sum(increase(http_requests_total[30d]))
| Objetivo | SLI | SLO | Ventana de Medición |
|---|---|---|---|
| Disponibilidad | Peticiones exitosas / total de peticiones | 99.9% | 30 días |
| Latencia | Peticiones bajo 200ms / total de peticiones | 99% bajo 200ms | 7 días |
| Tasa de error | Respuestas de error / total de respuestas | < 0.1% | 1 hora |
| Throughput | Peticiones por segundo | > 1000 rps | 5 minutos |
Los SLOs sin política de presupuesto de error son solo números en un dashboard. El presupuesto es lo que los hace accionables: con 99.9% tienes 0.1% de peticiones para gastar por ventana, y cuando el burn rate se dispara puedes decir “dejad de desplegar, arreglad la fiabilidad primero” con algo más que una corazonada. La Plantilla de Service Level Objective tiene la estructura para escribir esa política.
Las alertas por burn rate son el patrón que hace los SLOs pagineables en lugar de aspiracionales. La idea: no alertes cuando el ratio de error cruza una línea fija — alerta según la velocidad a la que se consume el presupuesto. Un SLO del 99.9% permite ~43 minutos de caída total al mes; una tasa de error que agotaría el presupuesto del mes en 1-2 días (burn rate ~14,4×) necesita una página ya, mientras que un consumo lento que tardaría una semana (2×) merece un ticket, no un despertar. El patrón multi-ventana del SRE workbook comprueba el mismo burn rate en una ventana corta (1h) y una larga (6h) para que un pico ya recuperado no pague:
# Burn rate > 14.4x sostenido en 1h Y 6h → page
(
sum(rate(http_requests_total{status=~"5.."}[1h]))
/ sum(rate(http_requests_total[1h]))
) > (14.4 * 0.001)
and
(
sum(rate(http_requests_total{status=~"5.."}[6h]))
/ sum(rate(http_requests_total[6h]))
) > (14.4 * 0.001)
Consumo rápido (page): 14,4× en 1h+6h. Consumo lento (ticket): 2× en 1d+3d. Ajusta los multiplicadores a tu SLO y tolerancia al ruido — los números de arriba asumen el presupuesto 99,9%/0,1% de la tabla.
5. Crea Alertas Significativas
Alerta sobre síntomas, no causas:
# Ejemplo: Reglas de alerta de Prometheus
groups:
- name: service_alerts
rules:
- alert: HighErrorRate
expr: |
(
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m]))
) > 0.01
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate in {{ $labels.service }}"
description: "Error rate is {{ $value | humanizePercentage }}"
- alert: LatencyDegradation
expr: |
histogram_quantile(0.95,
sum(rate(request_duration_seconds_bucket[5m])) by (le)
) > 1.0
for: 10m
labels:
severity: warning
annotations:
summary: "Latency p95 above 1s"
Alertmanager enruta entonces cada alerta: page para crítico, ticket para advertencia, resumen para informativo. Una config de enrutado mínima:
# alertmanager.yml — enruta por severidad, silencia duplicados
route:
receiver: 'team-pager'
group_by: ['alertname', 'service']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- match:
severity: critical
receiver: 'pagerduty-critical'
- match:
severity: warning
receiver: 'slack-warnings'
inhibit_rules:
- source_match:
alertname: 'ServiceDown'
target_match:
severity: 'critical'
equal: ['service']
La inhibición es lo que te salva durante un fallo en cascada: cuando ServiceDown dispara para orders, las diez HighErrorRate hijas del mismo servicio se silencian en lugar de generar diez páginas más. El group_by también ayuda — una notificación por incidente, no una por alerta.
Principios de diseño de alertas:
- Alerta sobre síntomas que impactan usuarios (tasa de error, latencia), no causas (disco lleno)
- Usa
for:para reducir ruido (requiere violación sostenida del umbral) - Añade links a runbooks y dashboards en cada alerta
- Niveles de severidad: página para crítico (impacto usuario), ticket para advertencia (tendencia)
- Revisa frecuencia de alertas regularmente y ajusta umbrales
Un número que ayuda a ajustar for:: ¿cuánto puede existir el síntoma antes de que un usuario lo note? Para una tasa de error de cara al cliente son quizá 2-5 minutos; para una profundidad de cola en aumento podría ser una hora. Pon for: justo antes del impacto visible al usuario — suficiente para saltar picos, suficientemente corto para seguir importando.
Lo que funciona
- Nombra métricas consistentemente. Formato
service_unit:orders_service_requests_total. - Documenta tus métricas. Cada métrica necesita descripción y unidad.
- Usa histogramas en lugar de promedios. Los promedios ocultan outliers; los histogramas muestran distribución.
- La cardinalidad es costo. Cada combinación única de labels crea una nueva serie temporal.
- Los dashboards son para exploración, no monitoreo. Las alertas notifican; los dashboards investigan.
- Prueba tus dashboards. Recorre escenarios de incidentes para verificar que proporcionan respuestas.
- Mantén el dashboard de SLI aburrido. Si necesita una leyenda para explicar qué línea es buena, reconstrúyelo.
Errores Comunes
- Métricas de alta cardinalidad. Etiquetar por ID de usuario o ID de petición explota el almacenamiento. Si necesitas detalle por usuario, para eso están logs y trazas.
- Alertar sobre todo. Demasiadas alertas crean ruido y reducen calidad de respuesta — cada una debería tener una acción asociada.
- Faltan unidades. Una métrica llamada
latencyes ambigua —latency_secondses clara. - Promediar percentiles. No puedes promediar p95s entre servicios. Usa histogramas.
- Sin reglas de agregación. Métricas de alta frecuencia en bruto abruman dashboards; agrega primero.
- Ignorar el burn rate. Una alerta que dispara al 1% de errores durante 5 minutos te despertará por un parpadeo de deploy de 30 segundos. Las alertas de burn rate capturan consumo sostenido de presupuesto en su lugar.
Frameworks de Instrumentación
Tres ecosistemas cubren la mayoría de los codebases:
- Librerías cliente de Prometheus (Python
prometheus_client, Goprometheus, Rustprometheus): el camino nativo — directo, mínimo, idiomático por lenguaje. - Micrometer (JVM): fachada vendor-neutral que alimenta Prometheus, Datadog o CloudWatch sin cambios de código — estándar en Spring Boot.
- OpenTelemetry: la elección moderna para servicios nuevos. Un SDK emite métricas, trazas y logs; el Collector convierte a remote-write de Prometheus u OTLP para tu backend. Configuración algo más pesada, pero dejas de pagar el impuesto de “tres SDKs”.
También está StatsD/DogStatsD para jobs push-based de corta duración — scripts batch y funciones serverless que no vivirán lo suficiente para ser scrapped. Pre-agrega del lado del cliente, lo que acota la cardinalidad a costa de perder visibilidad por instancia.
Vale mencionar dashboard-as-code en la misma línea: Grafana soporta provisioning de dashboards desde archivos JSON, librerías Jsonnet/grafonnet o Terraform. Guarda los dashboards junto al servicio que monitorizan, revísalos en PRs como cualquier otro código — un dashboard manual sin documentar es un huérfano esperando a pasar.
Variantes
- Pull-based: Prometheus scrapea exporters (estándar para Kubernetes)
- Push-based: StatsD, Telegraf o aplicación empuja a colector (mejor para jobs de corta duración — el Pushgateway existe para esto, úsalo con moderación)
- Nativo de nube: AWS CloudWatch, Google Cloud Monitoring, Azure Monitor (gestionado, pero específico de proveedor)
- Empresarial: Datadog, New Relic, Dynatrace (capacidades ricas, precio por host)
- OpenTelemetry: el camino de instrumentación más nuevo — los SDKs de OTel emiten métricas junto a trazas, y los collectors pueden convertir a formato Prometheus. Vale la pena adoptarlo en servicios nuevos ya que un SDK cubre los tres pilares y los exemplars vienen gratis, permitiéndote saltar de un pico de latencia directamente a la traza que lo causó.
Conclusión
Las métricas y dashboards convierten datos de sistema brutos en inteligencia operativa. Instrumenta consistentemente, controla la cardinalidad antes de que controle tu factura, diseña dashboards alrededor de las preguntas que la gente realmente hace, y alerta sobre síntomas en lugar de causas. Haz esas cuatro cosas y el stack de observabilidad empieza a pagar el alquiler — el ciclo de vida de alertas y el resto del panorama de tres pilares están cubiertos en las guías enlazadas arriba.
Lecturas Adicionales
- Guía de Observabilidad — el panorama de tres pilares: métricas, logs y trazas juntos.
- Guía de Gestión de Alertas — políticas de escalación, guardias y fatiga de alertas.
- Plantilla de Service Level Objective — escribe tus SLOs y política de presupuesto de error.
- Documentación de Prometheus — referencia PromQL, exporters y federación.
- Documentación de Grafana — dashboards, alertas y provisioning.
- Recursos companion — config de scrape, reglas de grabación y alerta, enrutado de Alertmanager, el JSON del dashboard de señales doradas y un ejemplo Flask instrumentado como archivos ejecutables.
Preguntas frecuentes
¿Cuántas métricas debería exponer mi aplicación?
10-50 métricas bien elegidas superan a 1000 autogeneradas. Enfócate en las cuatro señales doradas y KPIs de negocio. Si una métrica no alimenta un dashboard ni una alerta en un mes, elimínala — está gastando presupuesto de cardinalidad para nada.
¿Qué intervalo de scrape debería usar?
15 segundos es estándar. Usa 5 segundos para sistemas críticos donde un minuto de ceguera importa, 60 segundos para infraestructura de cambio lento como capacidad de disco. Bajar de 5 segundos no compra casi nada y duplica tu número de series.
¿Cómo manejo la cardinalidad de métricas?
Usa valores de label estáticos (clase de código de estado, no URL exacta). Descarta labels de alta cardinalidad en la ingesta con relabel_configs o metric_relabel_configs si no puedes arreglar la instrumentación. Para auditar qué consume almacenamiento: topk(20, count by (__name__)({__name__=~".+"})) muestra qué nombres de métrica dominan. Para datos realmente sin límite — latencia por usuario, detalle por petición — enrútalo a logs o trazas en lugar de luchar contra el modelo de métricas.
¿Cuál es la diferencia entre un histogram y una summary?
Los histogramas agrupan observaciones en buckets del lado del servidor, así que puedes agregar entre instancias y re-calcular cuantiles después. Las summaries calculan cuantiles dentro de cada proceso y no se pueden agregar después. Usa histogramas por defecto; summaries solo para batch jobs puntuales que nunca se agregan.
¿Debería usar Prometheus o una solución SaaS?
Prometheus es gratis pero requiere expertise operacional — tú gestionas retención, escalado y upgrades. El SaaS reduce overhead pero cuesta más a escala. Muchos equipos usan ambos: Prometheus para alertas en tiempo real, SaaS o almacenamiento remote-write (Thanos, VictoriaMetrics) para largo plazo.
Recursos Relacionados
Guía Completa de Observabilidad con el Stack de Grafana
Monta el stack completo de observabilidad de Grafana: Prometheus, Loki, Tempo, Alloy y Grafana con un solo docker-compose, correlación de señales y alertado por SLO.
GuideGestión de Alertas: Alertas en Guardia que Funcionan
Guía práctica de gestión de alertas: reduce la fatiga de alertas, define niveles de severidad, políticas de escalado y rotaciones de guardia sostenibles.
GuideTrazado distribuido: OpenTelemetry, Jaeger y Zipkin
Domina el trazado distribuido con OpenTelemetry, Jaeger y Zipkin. Propagación de trazas entre servicios, contexto de span, estrategias de muestreo y depuración en producción.
RecipeExpón métricas de aplicación con Python y Prometheus
Construye un exporter de métricas Prometheus en Python con prometheus_client. Cubre counters, gauges, histograms, summaries e integración con Flask y FastAPI.
RecipeDashboards de Grafana para Observabilidad con Prometheus
Construye dashboards de Grafana que visualizan métricas de Prometheus. Usá paneles, variables de template, provisioning y alertas para observabilidad del equipo.
DocPlantilla de Objetivo de Nivel de Servicio (SLO)
Una plantilla para definir objetivos de confiabilidad, presupuestos de error y metodos de medicion para servicios y sistemas.