🎨 Sysprovider Code
Sysprovider LogoWiki
🇪🇸Hosting español para ecommerce

Monitorización con Prometheus, Grafana y OpenTelemetry

Actualizado el 24 de febrero de 2026

Cuando hablamos de monitorización SysAdmin en entornos modernos, la combinación de Prometheus Grafana y OpenTelemetry se ha convertido en el estándar de facto. Ya no basta con instalar un agente SNMP o revisar logs a mano. Necesitamos un stack que permita recolectar métricas, trazas y logs de forma unificada, con capacidad de escalar horizontalmente y ofrecer alertas avanzadas sin depender de soluciones propietarias.

Este artículo es una guía completa para implementar este trío de herramientas en un servidor Linux. Cubriremos desde la instalación y configuración básica hasta la integración de OpenTelemetry para obtener visibilidad de extremo a extremo, pasando por dashboards en Grafana y alertas inteligentes con Prometheus.


¿Por qué Prometheus, Grafana y OpenTelemetry juntos?

Antes de entrar en materia, entendamos el papel de cada componente:

  • Prometheus: Sistema de recolección y almacenamiento de métricas basado en un modelo de datos multidimensional (etiquetas). Destaca por su potente lenguaje de consultas (PromQL) y su capacidad de autodescubrimiento.
  • Grafana: Herramienta de visualización y dashboards. Se conecta a Prometheus (y a cientos de otras fuentes) para crear paneles interactivos y compartibles.
  • OpenTelemetry: Conjunto de APIs, SDKs y herramientas para generar, recolectar y exportar telemetría (métricas, trazas y logs). Es el pegamento que nos permite instrumentar aplicaciones sin atarnos a un vendor específico.

La magia ocurre cuando OpenTelemetry envía métricas a Prometheus (a través de exporters o el OTLP Receiver) y las trazas a sistemas como Jaeger o Tempo, todo visualizado en Grafana. Esto nos da una visión holística del sistema: desde la CPU del servidor hasta el tiempo de respuesta de una petición HTTP.

[INFO] OpenTelemetry es un proyecto de CNCF (Cloud Native Computing Foundation), al igual que Prometheus. Esta alineación garantiza compatibilidad y futuro.


Instalación del Stack en Linux

Vamos a instalar todo en un servidor Ubuntu 22.04 LTS. Usaremos Docker Compose para simplificar el despliegue, pero también veremos opciones bare-metal.

Requisitos previos

  • Servidor Linux con Docker y Docker Compose instalados.
  • Puertos abiertos: 9090 (Prometheus), 3000 (Grafana), 4318 (OpenTelemetry Collector).
  • Acceso root o sudo.

Despliegue con Docker Compose

Creamos un directorio de trabajo y un archivo docker-compose.yml:

version: '3.8'

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
    ports:
      - "9090:9090"
    restart: unless-stopped

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin123
    volumes:
      - grafana_data:/var/lib/grafana
    ports:
      - "3000:3000"
    restart: unless-stopped

  otel-collector:
    image: otel/opentelemetry-collector-contrib:latest
    container_name: otel-collector
    command: ["--config=/etc/otel-collector-config.yml"]
    volumes:
      - ./otel-collector-config.yml:/etc/otel-collector-config.yml
    ports:
      - "4317:4317"   # gRPC
      - "4318:4318"   # HTTP
    restart: unless-stopped

volumes:
  prometheus_data:
  grafana_data:

Ahora necesitamos los archivos de configuración.

Configuración de Prometheus (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: 'otel-collector'
    scrape_interval: 10s
    static_configs:
      - targets: ['otel-collector:8888']  # Puerto de métricas del collector

[WARNING] Asegúrate de que el scrape_interval no sea demasiado agresivo si tienes muchos targets. 15s es un buen equilibrio.

Configuración de OpenTelemetry Collector (otel-collector-config.yml)

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:
    timeout: 1s
    send_batch_size: 1024

exporters:
  prometheus:
    endpoint: "0.0.0.0:8888"
    namespace: "otel"

service:
  pipelines:
    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [prometheus]

Este collector recibe métricas vía OTLP y las expone en formato Prometheus en el puerto 8888.


Instrumentando una aplicación con OpenTelemetry

Para ver la magia, necesitamos una aplicación que envíe telemetría. Usaremos un ejemplo en Python con Flask.

Instalación de dependencias

pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp opentelemetry-instrumentation-flask

Código de ejemplo (app.py)

from flask import Flask
import random
from opentelemetry import trace, metrics
from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.instrumentation.flask import FlaskInstrumentor

app = Flask(__name__)

# Instrumentar Flask automáticamente
FlaskInstrumentor().instrument_app(app)

# Configurar métricas
exporter = OTLPMetricExporter(endpoint="http://localhost:4318/v1/metrics")
reader = PeriodicExportingMetricReader(exporter)
provider = MeterProvider(metric_readers=[reader])
metrics.set_meter_provider(provider)

meter = metrics.get_meter("mi-app")

# Crear métrica personalizada
request_counter = meter.create_counter(
    "app.requests.count",
    description="Número de peticiones",
    unit="1"
)

@app.route("/")
def hello():
    request_counter.add(1, {"endpoint": "/"})
    return "Hola, mundo!"

@app.route("/error")
def error():
    request_counter.add(1, {"endpoint": "/error"})
    return "Error simulado", 500

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

Ejecutamos la aplicación y, tras unas cuantas peticiones, las métricas aparecerán en Prometheus bajo el prefijo otel_.

[TIP] Usa curl para generar tráfico: while true; do curl http://localhost:5000/; sleep 2; done


Dashboards en Grafana

Conectamos Grafana a Prometheus como fuente de datos (URL: http://prometheus:9090). Ahora podemos importar dashboards predefinidos o crear los nuestros.

Dashboard básico de métricas del sistema

  1. En Grafana, ve a Create > Dashboard > Add new panel.
  2. Usa PromQL para consultar métricas. Por ejemplo:
    • 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) → Uso de CPU.
    • node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 → Memoria disponible.
  3. Añade paneles para métricas de OpenTelemetry:
    • rate(otel_app_requests_count_total[5m]) → Tasa de peticiones.

Dashboard de Trazas (opcional, con Tempo)

Si quieres ver trazas, despliega Grafana Tempo y configúralo como fuente de datos. OpenTelemetry puede exportar trazas directamente a Tempo vía OTLP.


Alertas avanzadas con Prometheus y Alertmanager

Las alertas avanzadas van más allá de simples umbrales. Podemos crear reglas que evalúen tendencias, ratios o incluso basadas en logs.

Configuración de Alertmanager

Añadimos el servicio al docker-compose.yml:

alertmanager:
  image: prom/alertmanager:latest
  container_name: alertmanager
  volumes:
    - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml
  ports:
    - "9093:9093"
  restart: unless-stopped

Reglas de alerta en Prometheus (alert.rules.yml)

groups:
  - name: sysadmin_alerts
    rules:
      - alert: AltaCargaCPU
        expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "CPU alta en {{ $labels.instance }}"
          description: "CPU al {{ $value }}% durante más de 5 minutos."

      - alert: TasaErroresApp
        expr: rate(otel_app_requests_count_total{endpoint="/error"}[5m]) > 0.5
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Alta tasa de errores en /error"
          description: "Tasa de errores: {{ $value }} peticiones/segundo."

      - alert: PrediccionDiscoLleno
        expr: predict_linear(node_filesystem_avail_bytes{fstype!="tmpfs"}[6h], 24*3600) < 0
        for: 1h
        labels:
          severity: critical
        annotations:
          summary: "Disco se llenará en 24h en {{ $labels.instance }}"

[INFO] La función predict_linear es una de las más potentes de PromQL. Permite anticipar problemas usando regresión lineal.

Configuración de Alertmanager (alertmanager.yml)

route:
  receiver: 'slack'
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h

receivers:
  - name: 'slack'
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/TXXXXX/BXXXXX/XXXXXXXX'
        channel: '#alertas-sysadmin'
        send_resolved: true

Ahora, cada vez que se cumpla una regla, recibirás una notificación en Slack (o correo, PagerDuty, etc.).


Integración avanzada: Métricas de bases de datos y servicios

Monitorización de PostgreSQL con OpenTelemetry

Podemos usar el receptor postgresql del OpenTelemetry Collector para obtener métricas de la base de datos.

En otel-collector-config.yml, añadimos:

receivers:
  postgresql:
    endpoint: localhost:5432
    username: monitor
    password: secret
    databases: [mydb]

Luego, en el pipeline:

service:
  pipelines:
    metrics:
      receivers: [otlp, postgresql]
      processors: [batch]
      exporters: [prometheus]

Esto expondrá métricas como postgresql_connections, postgresql_transactions, etc.

Monitorización de Nginx

Usamos el receptor nginx del collector (o un exporter externo). El collector puede parsear el estado de Nginx si está configurado con stub_status.


Buenas prácticas para SysAdmin

Etiquetado semántico

Usa etiquetas (labels) de forma consistente. Por ejemplo:

  • env: producción, staging, desarrollo.
  • service: nombre del microservicio.
  • team: equipo responsable.

Esto facilita el filtrado en Grafana y la creación de alertas granulares.

Almacenamiento y retención

Prometheus no es una base de datos de larga duración. Para retención > 30 días, usa Thanos o Cortex. Configura --storage.tsdb.retention.time=30d.

Seguridad

  • Protege Grafana con autenticación (por defecto, admin/admin).
  • Usa HTTPS en producción.
  • Restringe el acceso a los endpoints de Prometheus y OpenTelemetry.

Solución de problemas comunes

ProblemaCausa posibleSolución
Prometheus no ve el collectorPuerto incorrectoVerifica que el collector exponga métricas en :8888
Grafana no carga dashboardsFuente de datos mal configuradaRevisa la URL de Prometheus (usa el nombre del contenedor)
OpenTelemetry no envía métricasEndpoint OTLP incorrectoUsa http://localhost:4318/v1/metrics
Alertas no se disparanRegla mal escritaUsa promtool check rules para validar

[WARNING] Siempre prueba las reglas de alerta en un entorno de desarrollo antes de pasarlas a producción. Un falso positivo puede generar fatiga.


Conclusión

La combinación de Prometheus Grafana y OpenTelemetry ofrece una solución de monitorización SysAdmin robusta, escalable y open source. Con OpenTelemetry, podemos instrumentar cualquier aplicación de forma estandarizada, mientras que Prometheus se encarga del almacenamiento y las alertas avanzadas, y Grafana proporciona la visualización.

Este stack no solo te permite reaccionar ante incidentes, sino anticiparte a ellos mediante reglas predictivas y dashboards proactivos. Es la base de cualquier operación moderna, ya sea en un clúster Kubernetes o en un servidor bare-metal.

El siguiente paso es integrar logs con Loki o Elastic, y trazas con Tempo o Jaeger. Pero eso ya es otra historia.

¿Necesitas ayuda?Son dos de nuestros técnicos, Agustín y Mikel, y están disponibles para resolver cualquier problema.

Hablar con ellos ahora
Agustín y Mikel