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

Monitoreo proactivo de servidores con Prometheus y Grafana dashboards

Actualizado el 6 de enero de 2026

Introducción: De la Reactividad a la Proactividad en la Gestión de Infraestructura

En el ecosistema actual de hosting y servidores, la diferencia entre un incidente que pasa desapercibido y una caída catastrófica de servicio se mide en milisegundos. Las herramientas de monitoreo tradicionales, basadas en umbrales estáticos y alertas reactivas, ya no son suficientes. El SysAdmin moderno necesita un sistema que no solo le avise cuando algo falla, sino que le permita predecir tendencias, identificar cuellos de botella y optimizar recursos antes de que afecten al usuario final.

Aquí es donde entra en juego el stack Prometheus + Grafana. Prometheus actúa como el cerebro de la recolección y almacenamiento de métricas, mientras que Grafana se convierte en el panel de control visual que transforma datos crudos en inteligencia accionable. Este artículo desglosa, paso a paso, cómo implementar un sistema de monitoreo proactivo que te permita dormir tranquilo, sabiendo que tus servidores están bajo vigilancia constante y predictiva.

¿Por qué Prometheus y Grafana? El "Por Qué" Detrás de la Elección

Antes de ensuciarnos las manos con código, es crucial entender por qué este stack ha devenido en el estándar de facto para la monitorización de infraestructuras modernas.

  • Modelo de Datos Multidimensional: A diferencia de herramientas como Nagios o Zabbix, Prometheus no etiqueta las métricas con un simple nombre de host. Utiliza un modelo de datos con labels (etiquetas) clave-valor. Esto permite consultas extremadamente flexibles y granuladas. Por ejemplo, puedes preguntar: rate(http_requests_total{job="api", status=~"5.."}[5m]) para obtener la tasa de errores 5xx de todos los endpoints de tu API, sin necesidad de configurar cada uno manualmente.
  • Recolección Pull vs. Push: Prometheus "tira" (pull) de las métricas de los endpoints expuestos por tus servicios. Esto simplifica la gestión de firewalls y NATs, ya que no necesitas que cada servidor se conecte a un servidor central. Además, puedes saber instantáneamente si un target está caído porque Prometheus no puede obtener sus métricas.
  • Lenguaje de Consultas (PromQL): Es el corazón del sistema. PromQL permite realizar agregaciones, operaciones aritméticas, predicciones y análisis de series temporales con una sintaxis potente y concisa. No es SQL, pero es igual de expresivo para datos temporales.
  • Grafana como Frontend Unificado: Grafana no es solo un "dashboard bonito". Es una plataforma de observabilidad que puede consumir datos de Prometheus, Elasticsearch, InfluxDB, y cientos de fuentes más. Te permite crear paneles dinámicos, alertas visuales y anotaciones que enriquecen el contexto de tus métricas.

## Fase 1: Despliegue de Prometheus Server (El Cerebro)

Vamos a desplegar Prometheus utilizando Docker, lo que garantiza un entorno aislado y reproducible. Asumimos que tienes un servidor Linux (Ubuntu 22.04 LTS recomendado) con Docker y Docker Compose instalados.

1.1. Estructura de Directorios y Configuración Base

Primero, creamos la estructura de directorios y el archivo de configuración principal.

mkdir -p /opt/prometheus/data
mkdir -p /opt/prometheus/config
cd /opt/prometheus/config

El archivo prometheus.yml es el punto de entrada. Aquí definimos qué targets monitorear y cada cuánto tiempo.

# /opt/prometheus/config/prometheus.yml
global:
  scrape_interval: 15s      # ¿Por qué 15s? Balance entre granularidad y carga de CPU/red.
  evaluation_interval: 15s  # Frecuencia con la que se evalúan las reglas de alerta.

# Reglas de alerta (las cargaremos más tarde)
rule_files:
  - "alerts.yml"

# Configuración de scraping
scrape_configs:
  # El trabajo 'prometheus' monitorea el propio servidor de Prometheus.
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # Ejemplo: Monitoreo de un servidor web Nginx con el exportador oficial.
  - job_name: 'nginx'
    static_configs:
      - targets: ['192.168.1.100:9113']  # IP del servidor web con nginx_exporter
    metrics_path: '/metrics'            # Ruta por defecto para el exportador.

  # Ejemplo: Monitoreo de métricas del sistema (CPU, RAM, Disco) vía Node Exporter.
  - job_name: 'node'
    static_configs:
      - targets: ['192.168.1.100:9100', '192.168.1.101:9100'] # Múltiples servidores
    relabel_configs:
      - source_labels: [__address__]
        regex: '(.*):.*'
        target_label: instance
        replacement: '${1}'  # Extraemos la IP como label 'instance' para identificar el host.

Nota Técnica: El scrape_interval no debe ser demasiado bajo (ej. 1s) en servidores con cientos de targets, ya que puede saturar la red y el disco de Prometheus. Para servidores de hosting, 15-30s es un buen punto de partida.

1.2. Docker Compose para Prometheus

Creamos el archivo docker-compose.yml en /opt/prometheus/.

# /opt/prometheus/docker-compose.yml
version: '3.8'

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    restart: unless-stopped
    volumes:
      - ./config/prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - ./config/alerts.yml:/etc/prometheus/alerts.yml:ro
      - ./data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention.time=30d' # ¿Por qué 30 días? Balance entre histórico y espacio en disco.
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
      - '--web.enable-lifecycle'  # Permite recargar configuración sin reiniciar: curl -X POST localhost:9090/-/reload
    ports:
      - "9090:9090"
    networks:
      - monitoring

networks:
  monitoring:
    driver: bridge

Iniciamos el servicio:

docker-compose up -d
docker-compose logs -f prometheus  # Verificar que no haya errores

## Fase 2: Despliegue de Exporters (Los Sensores)

Prometheus no puede leer métricas del sistema por sí mismo. Necesita exporters, pequeños agentes que exponen métricas en un formato que Prometheus entiende (HTTP, puerto específico).

2.1. Node Exporter (Métricas del Sistema Operativo)

Es el exportador más común. Se instala en cada servidor Linux que quieras monitorear.

# En el servidor objetivo (ej. 192.168.1.100)
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-1.7.0.linux-amd64.tar.gz
tar xvf node_exporter-1.7.0.linux-amd64.tar.gz
sudo cp node_exporter-1.7.0.linux-amd64/node_exporter /usr/local/bin/

# Crear usuario de servicio (seguridad: no ejecutar como root)
sudo useradd -rs /bin/false node_exporter

# Crear servicio systemd
sudo tee /etc/systemd/system/node_exporter.service > /dev/null <<EOF
[Unit]

Description=Node Exporter

After=network.target

[Service]

User=node_exporter

Group=node_exporter

Type=simple

ExecStart=/usr/local/bin/node_exporter \
    --web.listen-address=:9100 \
    --path.rootfs=/ \
    --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($|/) \
    --collector.netclass.ignored-devices=^(veth|docker|br-|lo)$

[Install]

WantedBy=multi-user.target

EOF

sudo systemctl daemon-reload
sudo systemctl enable node_exporter
sudo systemctl start node_exporter

# Verificar que expone métricas
curl http://localhost:9100/metrics | head -20

¿Por qué estas flags?

  • --path.rootfs=/: Permite que Node Exporter acceda al sistema de archivos raíz correctamente, especialmente dentro de contenedores.
  • --collector.filesystem.mount-points-exclude: Evita que escanee sistemas de archivos virtuales (proc, sys) que no aportan valor y generan ruido.
  • --collector.netclass.ignored-devices: Filtra interfaces de red virtuales (Docker, bridges) para centrarse en las interfaces físicas (eth0, ens33).

2.2. Nginx Exporter (Métricas del Servidor Web)

Para monitorear Nginx, necesitas que el propio Nginx exponga un status page (stub_status) y luego un exportador que lo lea.

Paso 1: Habilitar stub_status en Nginx

# /etc/nginx/sites-available/default (o tu configuración)
server {
    listen 80;
    server_name _;

    location /nginx_status {
        stub_status on;
        access_log off;
        allow 127.0.0.1;    # Solo acceso local
        allow 192.168.1.0/24; # O la IP de tu servidor Prometheus
        deny all;
    }
}
sudo nginx -t && sudo systemctl reload nginx

Paso 2: Instalar y configurar nginx_exporter

# En el servidor web
wget https://github.com/nginxinc/nginx-prometheus-exporter/releases/download/v0.11.0/nginx-prometheus-exporter_0.11.0_linux_amd64.tar.gz
tar xvf nginx-prometheus-exporter_0.11.0_linux_amd64.tar.gz
sudo cp nginx-prometheus-exporter /usr/local/bin/

sudo tee /etc/systemd/system/nginx_exporter.service > /dev/null <<EOF
[Unit]

Description=Nginx Prometheus Exporter

After=network.target

[Service]

User=nobody

Group=nogroup

Type=simple

ExecStart=/usr/local/bin/nginx-prometheus-exporter \
    --nginx.scrape-uri=http://127.0.0.1/nginx_status \
    --web.listen-address=:9113

[Install]

WantedBy=multi-user.target

EOF

sudo systemctl daemon-reload
sudo systemctl enable nginx_exporter
sudo systemctl start nginx_exporter

# Verificar
curl http://localhost:9113/metrics | grep nginx_connections

## Fase 3: Despliegue de Grafana (El Panel de Control)

Grafana se conectará a Prometheus como fuente de datos para visualizar las métricas.

3.1. Docker Compose para Grafana

Agregamos el servicio Grafana al mismo docker-compose.yml de Prometheus.

# /opt/prometheus/docker-compose.yml (añadir el servicio grafana)
  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=Str0ngP@ssw0rd!  # ¡Cambiar inmediatamente!
      - GF_INSTALL_PLUGINS=grafana-piechart-panel   # Plugins opcionales
    volumes:
      - ./grafana-data:/var/lib/grafana  # Persistencia de dashboards y config
      - ./grafana-config:/etc/grafana    # Configuración personalizada
    depends_on:
      - prometheus
    networks:
      - monitoring
docker-compose up -d grafana

3.2. Configurar Data Source en Grafana

  1. Accede a http://<IP_SERVIDOR>:3000 (usuario: admin, contraseña: la que pusiste).
  2. Ve a Configuration > Data Sources > Add data source.
  3. Selecciona Prometheus.
  4. En URL, pon http://prometheus:9090 (nombre del servicio en la red de Docker).
  5. Haz clic en Save & Test. Deberías ver un mensaje verde: "Data source is working".

## Fase 4: Diseño de Dashboards Proactivos con PromQL

Aquí es donde separamos a los SysAdmins de los ingenieros de sistemas. No se trata de poner bonitos gráficos, sino de diseñar paneles que te permitan predecir problemas.

4.1. Dashboard de "Salud General del Servidor"

Este dashboard debe responder preguntas como: ¿Está mi servidor sobrecargado? ¿Se está quedando sin memoria? ¿El disco está a punto de llenarse?

PanelMétrica PromQLInterpretación Proactiva
CPU Load (1m, 5m, 15m)node_load1, node_load5, node_load15Si load1 es consistentemente mayor que el número de núcleos de CPU, hay sobrecarga.
Memory Pressure(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100Si supera el 90% durante más de 10 minutos, el servidor está bajo presión de memoria.
Disk Prediction (LLENADO)predict_linear(node_filesystem_free_bytes{mountpoint="/"}[6h], 86400)Predice el espacio libre en disco en las próximas 24 horas. Si el valor es < 0, tienes un problema inminente.
Network Errorsrate(node_network_receive_errors_total[5m])Un aumento repentino puede indicar un cable defectuoso o un switch saturado.

Cómo crear un panel de predicción de disco:

  1. En Grafana, crea un nuevo dashboard y añade un panel Time series.
  2. En la consulta (PromQL), pega:
    predict_linear(node_filesystem_free_bytes{mountpoint="/"}[6h], 86400)
    
  3. En Legend, pon {{ instance }} - Predicción 24h.
  4. En Axis, cambia la unidad a bytes (IEC).
  5. Añade una alerta en el panel: Cuando predict_linear sea menor a 5GB, dispara una alerta.

¿Por qué predict_linear? Esta función utiliza regresión lineal sobre la serie temporal de los últimos 6 horas para proyectar el valor futuro. No es perfecta, pero es sorprendentemente precisa para detectar tendencias de llenado de disco o crecimiento de logs.

4.2. Dashboard de "Rendimiento Web (Nginx)"

Para un servidor de hosting, el rendimiento web es crítico.

PanelMétrica PromQLInterpretación Proactiva
Requests por segundorate(nginx_http_requests_total[1m])Picos anormales pueden indicar un ataque DDoS o un pico de tráfico legítimo.
Conexiones activasnginx_connections_activeSi se acerca al límite de worker_connections de Nginx, necesitas escalar.
Tiempo de respuesta (aproximado)rate(nginx_http_requests_total[5m]) / rate(nginx_http_upstream_response_msecs_sum[5m])Promedio de tiempo de respuesta. Un aumento sostenido indica un backend lento.
Errores 5xx por minutorate(nginx_http_requests_total{status=~"5.."}[1m])Cero errores es la meta. Una tasa > 0.1/s requiere investigación inmediata.

Panel de "Top URL por latencia": (Avanzado)

Si tu Nginx expone métricas con labels de host y uri, puedes hacer:

topk(10, sum by (uri) (rate(nginx_http_upstream_response_msecs_sum[5m]) / rate(nginx_http_upstream_response_msecs_count[5m])))

Esto te mostrará las 10 URLs más lentas. Si una URL de una página de inicio tarda 5 segundos, tienes un problema de frontend que debes solucionar.

## Fase 5

¿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