Javier Valencia Javier Valencia
Prometheus y Grafana para servicios pequeños

Prometheus y Grafana para servicios pequeños

Javier Valencia · · 5 min de lectura · 8 visitas · DevOps
devops prometheus grafana monitorizacion observabilidad

Cuando se habla de Prometheus y Grafana casi siempre es en el contexto de Kubernetes, de clusters con cientos de nodos, de arquitecturas de observabilidad con Thanos, Cortex, Mimir, Loki, Tempo y otros nombres tomados de la mitología griega. Todo eso existe y tiene su sitio, pero hay una realidad más modesta que también merece atención: el desarrollador o sysadmin con dos o tres VPS y un puñado de servicios, que necesita saber qué está pasando sin montar una plataforma entera.

Este post cubre exactamente eso. Cómo instalar, configurar y aprovechar Prometheus y Grafana en una VPS para monitorizar tu blog, tu API, tu base de datos y tu servidor, sin complicaciones.

Por qué Prometheus y no otra cosa

Prometheus y Grafana para servicios pequeños

Existen alternativas: InfluxDB, Datadog, New Relic, Zabbix, incluso scripts caseros con cron y correo. Cada una tiene su hueco. Prometheus gana en los proyectos pequeños por tres razones concretas.

La primera es que es gratuito y autoalojado. Sin costes por host, sin métricas "premium", sin límites de retención. Todo corre en tu máquina, todos los datos son tuyos.

La segunda es el modelo de pull. Prometheus es quien pregunta a tus servicios cada X segundos "dame tus métricas", no al revés. Esto elimina toda una clase de problemas de seguridad y configuración: tus servicios no tienen que saber dónde vive el colector ni tener credenciales para escribir en él.

La tercera es la cantidad de exporters disponibles. Hay un exporter para casi cualquier cosa: node_exporter para el sistema, postgres_exporter para PostgreSQL, nginx_exporter para Nginx, blackbox_exporter para hacer pings HTTP. Conectar un servicio nuevo suele ser cuestión de minutos.

Arquitectura mínima

Para una VPS, la arquitectura que recomiendo es esta:

┌──────────────────────────────────────────────┐
│  VPS (la misma donde corre tu servicio)      │
│                                              │
│  ┌─────────────┐      ┌──────────────────┐   │
│  │ node_exporter│←────┤                 │   │
│  └─────────────┘      │                 │   │
│                       │   Prometheus    │   │
│  ┌─────────────┐      │   (puerto 9090) │   │
│  │  tu app     │←─────┤                 │   │
│  │  /metrics   │      └────────┬────────┘   │
│  └─────────────┘               │            │
│                                ↓            │
│                        ┌──────────────┐     │
│                        │   Grafana    │     │
│                        │ (puerto 3000)│     │
│                        └──────────────┘     │
└──────────────────────────────────────────────┘

Todo en la misma máquina. Prometheus se conecta a los exporters localmente, Grafana consulta a Prometheus, y expones Grafana por HTTPS con el reverse proxy que ya tengas.

Para dos o tres VPS la variante es: un Prometheus central que consulta a los exporters de todas las máquinas. Nada más hasta que llegas a una escala que ya no es "pequeña".

Instalación con systemd, sin Docker

Prometheus y Grafana para servicios pequeños

En Docker es trivial, pero si no estás usando Docker en tus VPS, no tiene sentido meterlo solo para esto. La instalación nativa es igual de simple.

Descarga el binario de Prometheus:

wget https://github.com/prometheus/prometheus/releases/download/v2.52.0/prometheus-2.52.0.linux-amd64.tar.gz
tar xzf prometheus-2.52.0.linux-amd64.tar.gz
sudo mv prometheus-2.52.0.linux-amd64/prometheus /usr/local/bin/
sudo mv prometheus-2.52.0.linux-amd64/promtool /usr/local/bin/
sudo useradd --no-create-home --shell /bin/false prometheus
sudo mkdir -p /etc/prometheus /var/lib/prometheus
sudo chown prometheus:prometheus /var/lib/prometheus

Un unit file de systemd razonable:

[Unit]
Description=Prometheus
After=network-online.target
Wants=network-online.target

[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
    --config.file=/etc/prometheus/prometheus.yml \
    --storage.tsdb.path=/var/lib/prometheus \
    --storage.tsdb.retention.time=30d \
    --web.listen-address=127.0.0.1:9090
Restart=on-failure
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/prometheus
ProtectHome=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Dos detalles importantes: retención a 30 días (por defecto son 15, en un servicio pequeño 30-90 días suelen sobrar), y escucha solo en localhost. No quieres exponer Prometheus a internet.

Grafana tiene paquete oficial en APT, así que en Debian/Ubuntu es:

sudo apt install -y apt-transport-https software-properties-common
sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt install grafana
sudo systemctl enable --now grafana-server

Grafana escucha por defecto en :3000. Ponle un reverse proxy delante con Nginx y HTTPS, y autenticación básica si no vas a usar la de Grafana.

Configuración de Prometheus

Un prometheus.yml mínimo para un setup pequeño:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']

  - job_name: 'blog'
    static_configs:
      - targets: ['localhost:8080']
    metrics_path: /metrics

scrape_interval a 15 segundos es un buen compromiso: suficiente para detectar problemas rápido, no tanto como para generar gigas de datos innecesarios.

Recarga Prometheus con un SIGHUP (systemctl reload prometheus) para que aplique cambios de configuración sin perder histórico.

node_exporter: lo que realmente importa

Prometheus y Grafana para servicios pequeños

De todos los exporters, node_exporter es el imprescindible. Te da CPU, memoria, disco, red, load average, temperatura, procesos... todo lo que necesitas para saber si tu máquina está bien.

wget https://github.com/prometheus/node_exporter/releases/download/v1.8.0/node_exporter-1.8.0.linux-amd64.tar.gz
tar xzf node_exporter-1.8.0.linux-amd64.tar.gz
sudo mv node_exporter-1.8.0.linux-amd64/node_exporter /usr/local/bin/

Con un unit file similar al de Prometheus, ExecStart=/usr/local/bin/node_exporter --web.listen-address=127.0.0.1:9100. Hecho.

Exponer métricas desde tu propia app

Si tu aplicación es en Go, el cliente oficial es trivial:

import (
    "net/http"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var requestsTotal = prometheus.NewCounterVec(
    prometheus.CounterOpts{
        Name: "http_requests_total",
        Help: "Total HTTP requests by status",
    },
    []string{"path", "status"},
)

func init() {
    prometheus.MustRegister(requestsTotal)
}

func main() {
    http.Handle("/metrics", promhttp.Handler())
    http.ListenAndServe(":8080", nil)
}

Incrementa el contador en tus handlers y ya tienes métricas. Lo mismo para otros lenguajes: hay librerías oficiales para Python, Ruby, Node, Rust, Java.

Las cuatro métricas básicas que recomiendo exponer desde el principio:

  • http_requests_total{path, status}: contador de peticiones por ruta y código.
  • http_request_duration_seconds: histograma de latencias.
  • db_queries_total{status}: contador de queries a BD.
  • background_jobs_total{job, status}: trabajos en segundo plano si los hay.

Con estas cuatro ya puedes construir los paneles esenciales: tráfico, latencia, errores y salud de tareas async.

Queries PromQL que vas a usar

PromQL tiene fama de enrevesado pero el 90% del tiempo usas cuatro patrones.

Tasa de peticiones por segundo:

sum by (path) (rate(http_requests_total[5m]))

Porcentaje de errores:

sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))

Percentil 95 de latencia:

histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))

Uso de memoria del sistema:

(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes

Con esto cubres el 80% de los paneles que tendrás en tu dashboard.

Dashboards de Grafana: importa primero, retoca después

No empieces desde cero. Grafana tiene un repositorio público con miles de dashboards ya hechos. Para node_exporter, el dashboard 1860 es excelente: lo importas con un ID en Grafana y tienes CPU, memoria, disco y red listos en dos minutos.

Haz lo mismo para PostgreSQL (9628), Nginx (12708), Redis (11835). El 80% de lo que vas a querer ver ya está diseñado, probado y mantenido por alguien. Retoca después lo que te falta, pero no reinventes.

Alertas: Alertmanager o un script

Prometheus puede generar alertas y mandarlas a Alertmanager, que se encarga de enviarlas por email, Slack, Telegram o lo que quieras. Para un setup pequeño, Alertmanager puede ser overkill.

Alternativa sencilla: un cron cada cinco minutos que consulta la API de Prometheus y manda un correo si algo está mal. Con curl y jq lo haces en veinte líneas. Cuando te canse, pasas a Alertmanager. Mientras tanto, funciona.

Tres alertas básicas para empezar:

  1. El servicio responde con 5XX más del 1% del tráfico durante más de 5 minutos.
  2. La latencia p95 sube por encima del doble de lo habitual durante 10 minutos.
  3. El disco está por encima del 85% de uso.

Con estas tres ya te enteras de la mayoría de problemas serios antes de que tus usuarios te escriban.

Lo que no necesitas (todavía)

Hay cosas que la industria asume como estándar y que en un setup pequeño son ruido:

  • Thanos / Cortex: escalabilidad horizontal y retención multi-año. No los necesitas hasta que tengas múltiples Prometheus.
  • Loki para logs: si tu servicio cabe en una VPS, journalctl es suficiente.
  • Tracing distribuido: útil en microservicios. Si tienes un monolito, una buena logging estructurada es más práctica.
  • Service mesh: si tienes que preguntarte si lo necesitas, no lo necesitas.

Añade estas piezas cuando tengas un problema concreto que no puedes resolver con lo que ya hay. No antes.

Conclusión

Prometheus y Grafana no son herramientas exclusivas de grandes empresas. Con una VPS, media hora y un par de dashboards importados tienes más visibilidad de tu servicio que el 90% de los proyectos pequeños que conozco, que viven a ciegas hasta que algo falla y entonces revisan logs.

La inversión inicial es pequeña. El retorno, cada vez que te enteras de que un disco se está llenando antes de que se llene, que la latencia está subiendo antes de que los usuarios lo noten, que una query nueva está matando la base de datos, justifica con creces ese esfuerzo inicial. Observabilidad no es un lujo de escala: es una red de seguridad que cualquier proyecto serio debería tener desde el primer mes.