Curso Profesional de DevOps

Toma las primeras clases gratis

⏱ Tiempo estimado: 25 minutos

🎯 Rama / Perfil: SRE / DevOps / backend devs que quieren medir confiabilidad con datos reales.

🧠 Conocimiento previo necesario: Clases 17 a 20 del curso (SLOs y SLIs, monitoreo, logs vs métricas) y Docker básico.

💡 ¿Qué vas a lograr? Medir la disponibilidad de una app con un SLI real, verlo en un dashboard y disparar una alerta cuando incumples tu SLO de 99%.

🛠 Lo que necesitas antes de empezar

📋 Pasos

Paso 1: Crea una app que expone métricas

Estructura:

slo-lab/
├─ app/ (server.js, package.json, Dockerfile)
├─ prometheus.yml
├─ alerts.yml
└─ docker-compose.yml

En app/ ejecuta npm init -y && npm install express prom-client. Luego crea app/server.js:

js

const express = require('express');
const client = require('prom-client');
const app = express();
client.collectDefaultMetrics();

const requests = new client.Counter({
  name: 'http_requests_total', help: 'Total de requests',
  labelNames: ['route', 'status']
});
const latency = new client.Histogram({
  name: 'http_request_duration_seconds', help: 'Latencia',
  labelNames: ['route'], buckets: [0.05, 0.1, 0.25, 0.5, 1, 2]
});

app.use((req, res, next) => {
  const end = latency.startTimer();
  res.on('finish', () => {
    requests.inc({ route: req.path, status: res.statusCode });
    end({ route: req.path });
  });
  next();
});

app.get('/', (req, res) => setTimeout(() => res.send('ok'), Math.random() * 300));
app.get('/flaky', (req, res) => {
  if (Math.random() < 0.2) return res.status(500).send('error');
  res.send('ok');
});
app.get('/metrics', async (req, res) => {
  res.set('Content-Type', client.register.contentType);
  res.send(await client.register.metrics());
});
app.listen(3000);

Crea app/Dockerfile:

dockerfile

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --omit=dev
COPY server.js .
CMD ["node", "server.js"]

🔗 prom-client (librería oficial de métricas para Node): https://github.com/siimon/prom-client

Paso 2: Configura Prometheus y la regla de alerta del SLO

prometheus.yml:

yaml

global:
  scrape_interval: 5s
rule_files:
  - alerts.yml
scrape_configs:
  - job_name: app
    static_configs:
      - targets: ['app:3000']

alerts.yml (SLO: 99% de requests sin error 5xx):

yaml

groups:
  - name: slo
    rules:
      - alert: SLODisponibilidadIncumplido
        expr: |
          sum(rate(http_requests_total{status!~"5.."}[1m]))
          / sum(rate(http_requests_total[1m])) < 0.99
        for: 1m
        labels:
          severity: page
        annotations:
          summary: "Disponibilidad por debajo del SLO de 99%"

Paso 3: Levanta todo con Docker Compose

docker-compose.yml:

yaml

services:
  app:
    build: ./app
    ports: ["3000:3000"]
  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - ./alerts.yml:/etc/prometheus/alerts.yml
    ports: ["9090:9090"]
  grafana:
    image: grafana/grafana
    ports: ["3001:3000"]

bash

docker compose up -d --build

Verifica en 🔗 http://localhost:9090/targets que app aparezca en estado UP. 🔗 Prometheus: https://prometheus.io/docs/introduction/overview/ · Grafana: https://grafana.com/docs/grafana/latest/

Paso 4: Genera tráfico y mide tu SLI

bash

for i in $(seq 1 3000); do curl -s localhost:3000/flaky > /dev/null; sleep 0.05; done

En Prometheus (http://localhost:9090/graph) ejecuta esta consulta, que es tu SLI de disponibilidad:

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

Verás un valor cercano a 0.8, porque /flaky falla el 20% de las veces.

Paso 5: Visualízalo en Grafana

Abre http://localhost:3001 (usuario admin, contraseña admin; te pedirá cambiarla). Ve a Connections → Data sources → Add → Prometheus y usa la URL http://prometheus:9090. Crea un dashboard con 2 paneles:

  • Disponibilidad (SLI): la consulta del paso 4.
  • Latencia p95: histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[1m])) by (le))

Paso 6: Mira la alerta dispararse

Con el tráfico corriendo, espera un par de minutos y abre 🔗 http://localhost:9090/alerts. La alerta pasará de Pending a Firing. Ahora apunta el tráfico a / (sin fallos) y verás que se resuelve. Acabas de ver un error budget agotarse y recuperarse.

✅ Resultado esperado

Un stack local de 3 contenedores con una app instrumentada, un SLI de disponibilidad calculado en Prometheus, un dashboard de disponibilidad y latencia p95 en Grafana, y una alerta basada en un SLO de 99%.

🔥 Tu reto (siguiente acción)

Define un segundo SLO de latencia (por ejemplo, “95% de las requests a / en menos de 250 ms”) y escribe su regla de alerta usando http_request_duration_seconds_bucket{le="0.25"}. Luego conecta la alerta a Slack o email con Alertmanager.

📚 Recursos para ir más lejos

Curso Profesional de DevOps

Toma las primeras clases gratis

0 Comentarios

para escribir tu comentario

Artículos relacionados