Observabilidad: logs, monitoreo y backups
¿Qué es?
Observabilidad es la capacidad de saber qué está haciendo tu aplicación en producción sin tener que adivinar. Se apoya en tres patas: logs (el diario de lo que ocurre, línea a línea), métricas y monitoreo (números que miden salud y rendimiento, más alarmas cuando algo se sale de rango) y backups (copias de seguridad para recuperarte de un desastre). Sin observabilidad, un despliegue es una caja negra: te enteras de que algo falló cuando un usuario se queja.
¿Cómo funciona?
Tu contenedor escribe sus logs a la salida estándar; Docker los recoge y los puedes consultar con docker logs. Para no perderlos al reiniciar, se rotan y archivan. El monitoreo funciona con un servicio que cada cierto tiempo le pregunta a tu API "¿estás viva?" pegándole al endpoint /health que creamos en el módulo de Docker; si no responde, dispara una alerta. Los backups son tareas programadas (con cron) que copian tus datos a un lugar seguro y, crucial, se prueban restaurándolos. Un backup que nunca restauraste no es un backup, es una ilusión.
¿Para qué sirve?
Sirve para detectar problemas antes que tus usuarios, para diagnosticar rápido cuando algo falla (logs claros = arreglo rápido) y para dormir tranquilo sabiendo que un borrado accidental o un disco quemado no te borran del mapa. Es la pieza que mantiene vivo el despliegue: cierra el ciclo de DevOps, porque desplegar sin observar es desplegar a ciegas.
Pieza del despliegue que construye este módulo
Añadimos al despliegue del módulo anterior: rotación de logs en Compose, un monitor de salud que alerta si la API se cae y un backup automatizado con su script de restauración probado.
Paso 1: logs que no llenan el disco
# añade esto al servicio api en docker-compose.prod.yml
services:
api:
image: ghcr.io/tu-usuario/mi-api:latest
ports:
- "127.0.0.1:8000:8000"
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m" # cada archivo de log llega a 10 MB como máximo
max-file: "3" # conserva 3 archivos; los viejos se borran
docker compose -f docker-compose.prod.yml logs -f --tail 100 api # sigue los últimos 100 logs en vivo
Sin max-size, los logs de un contenedor pueden crecer sin límite y llenar el disco del servidor hasta tumbarlo. Es una de las causas más frecuentes de caídas en producción.
Paso 2: monitor de salud con alerta
Un script que revisa /health y avisa por correo o webhook si falla:
#!/usr/bin/env bash
# /home/deploy/scripts/monitor.sh
URL="https://mi-api.com/health"
WEBHOOK="${WEBHOOK_URL}" # define WEBHOOK_URL en el entorno
codigo=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "$URL")
if [ "$codigo" != "200" ]; then
curl -s -X POST "$WEBHOOK" \
-H "Content-Type: application/json" \
-d "{\"text\": \"ALERTA: la API respondió $codigo en $URL\"}"
fi
chmod +x /home/deploy/scripts/monitor.sh
# Programa el chequeo cada minuto con cron:
( crontab -l 2>/dev/null; echo "* * * * * WEBHOOK_URL='https://...' /home/deploy/scripts/monitor.sh" ) | crontab -
Reutiliza el endpoint /health del módulo de Docker. Por eso lo creamos desde el principio: ahora es el latido que el monitor escucha.
Paso 3: backup automatizado y restaurable
#!/usr/bin/env bash
# /home/deploy/scripts/backup.sh
set -euo pipefail
FECHA=$(date +%F_%H-%M)
DESTINO="/home/deploy/backups"
mkdir -p "$DESTINO"
# Ejemplo: respaldar un volumen de datos de la API
docker run --rm \
-v mi-api_datos:/datos:ro \
-v "$DESTINO":/backup \
alpine tar czf "/backup/datos-$FECHA.tar.gz" -C /datos .
# Conserva solo los últimos 7 backups
ls -1t "$DESTINO"/datos-*.tar.gz | tail -n +8 | xargs -r rm
echo "Backup creado: datos-$FECHA.tar.gz"
# Programa el backup diario a las 3 a. m.
( crontab -l 2>/dev/null; echo "0 3 * * * /home/deploy/scripts/backup.sh" ) | crontab -
Y el script que prueba la restauración (esto es lo que casi nadie hace):
#!/usr/bin/env bash
# /home/deploy/scripts/restaurar.sh
set -euo pipefail
ARCHIVO="$1"
docker run --rm \
-v mi-api_datos:/datos \
-v /home/deploy/backups:/backup:ro \
alpine sh -c "rm -rf /datos/* && tar xzf /backup/$ARCHIVO -C /datos"
echo "Restaurado desde $ARCHIVO"
Un backup que nunca probaste restaurar no cuenta. Programa una prueba de restauración periódica en un entorno aparte; el día del desastre no es momento de descubrir que tus copias estaban corruptas.
Tech English: log = registro/bitácora; to monitor = monitorear; uptime = tiempo en línea; alert / alerting = alerta/alertado; cron job = tarea programada; to restore = restaurar.
Ejercicios
-
Detección automática de caídas. Configura el monitor con cron y un webhook real (Slack, Discord o similar). Detén el contenedor a propósito y demuestra que la alerta llega en menos de dos minutos. Se evalúa que la alerta se dispare sola, sin intervención.
-
Backup que se restaura. Programa el backup diario, ejecuta
restaurar.shcon uno de los archivos generados y verifica que los datos vuelven idénticos. Entrega los dos scripts y la salida de la prueba. Se evalúa que la restauración sea reproducible y deje los datos íntegros.