Monitoreo de salud del sistema cada 15 min con alertas por WhatsApp (doc tecnica)

This commit is contained in:
2026-09-08 06:11:01 +00:00
parent b71b730a73
commit e8690dd74e

102
docs/healthcheck.md Normal file
View File

@@ -0,0 +1,102 @@
# Monitoreo SKEEN con alertas por WhatsApp (`skeen-healthcheck`)
Actualizado: 2026-09-08
## Qué es
Healthcheck cada 15 minutos (systemd timer) de todos los servicios de la VM.
Si un componente falla **2 corridas seguidas** (con 1 reintento interno de 5 s
por corrida para descartar reinicios transitorios), envía **una alerta por
WhatsApp** a los destinatarios configurados. Al recuperarse, envía un aviso de
recuperación. **Una sola alerta por incidente** (no re-alerta cada 15 min del
mismo fallo).
## Componentes monitoreados
| Check | Qué verifica |
|---|---|
| `odoo_web` | HTTP 200 en `:8069/web/login` |
| `frontend_nginx` | HTTP 200 del vhost nginx (Host `skeen.consultoria-as.com` → `/`) |
| `wacrm` | HTTP 200 en `:3000/login` |
| `hermes_gateway` | HTTP 200 en `:8080/health` |
| `hermes_bridge` | HTTP 200 en `:8090/health` |
| `cloudflare_tunel` | HTTP 200 en `https://skeen.consultoria-as.com/` (túnel + nginx) |
| `svc_*` | `systemctl is-active` de: `odoo-skeen`, `hermes-gateway`, `hermes-bridge`, `cloudflared-skeen`, `nginx` |
Salida OK/FAIL por componente al journal (`journalctl -u skeen-healthcheck`).
Exit code 1 si hubo fallos.
## Archivos
| Ruta | Uso |
|---|---|
| `/root/scripts/healthcheck.py` | Script principal (checks + lógica de alertas) |
| `/root/scripts/healthcheck_alerts.conf` | Destinatarios de WhatsApp, **un número E.164 por línea** (`#` = comentario). Ej. México: `526644990030`. Editar el archivo y listo — no requiere reiniciar nada |
| `/root/scripts/healthcheck_state.json` | Estado persistente (fallos consecutivos, alertado, hora de caída). Se regenera solo; se puede borrar para resetear incidentes |
## Servicios systemd
- `skeen-healthcheck.service` — oneshot que corre el script.
- `skeen-healthcheck.timer` — cada 15 min (`OnCalendar=*:0/15`, `Persistent=true`).
```bash
systemctl list-timers skeen-healthcheck.timer # ver próxima corrida
systemctl start skeen-healthcheck.service # correr a mano
journalctl -u skeen-healthcheck -n 50 # ver resultados
```
## Envío de alertas
Vía la API v1 del WACRM (envío real por Meta):
```
POST http://127.0.0.1:3000/api/v1/messages
Authorization: Bearer wacrm_live_ffac5531d76645acb239dba71ace6d1c
{"to": "+526644990030", "type": "text", "text": "⚠️ SKEEN: ..."}
```
Devuelve **201** en éxito; crea contacto/conversación automáticamente si no
existen. Mensajes: `⚠️ SKEEN: <componente> NO responde desde las HH:MM. Revisar.`
(fallos agrupados en un mensaje) y `✅ SKEEN: <componente> recuperado.`
Si el envío falla, se reintenta en la siguiente corrida (no se marca alertado).
## Cómo agregar/quitar checks
Editar la lista `CHECKS` en `/root/scripts/healthcheck.py`:
```python
('id_check', 'http', ('http://127.0.0.1:PUERTO/ruta', {200})), # web
('id_check', 'http', ('https://dominio/', {200}, None, 20)), # web + timeout
('id_check', 'http', ('http://127.0.0.1/', {200}, {'Host': 'dom'})), # vhost por Host
('svc_unidad', 'systemd', ('nombre-unidad',)), # systemd
```
Y su nombre legible en `NOMBRES` (es el que sale en el mensaje de WhatsApp).
## ⚠️ Limitación conocida (importante)
Meta **rechaza la entrega** de mensajes salientes a un número cuyo **cliente no
ha escrito en las últimas 24 horas** (regla de WhatsApp; no hay plantillas
aprobadas aún). Efecto observado en la prueba real del 2026-09-08: los 3
mensajes de alerta a Ivan salieron (Meta asignó wamid) pero quedaron en
estado `failed` porque su ventana de 24 h estaba cerrada (último mensaje suyo:
3-sep).
- **Mientras no haya plantillas**: las alertas solo llegan a números que
escribieron al número de la clínica en las últimas 24 h. Para activar a un
destinatario nuevo, pedirle que mande un WhatsApp al número de la clínica
(abre la ventana 24 h).
- **Solución definitiva**: cargar plantillas aprobadas en el WACRM
(Settings → Templates) y enviar las alertas como plantilla. Pendiente del
cliente.
- El estado `failed` no rompe el monitoreo: el script marca el incidente como
alertado y no re-spamea.
## Prueba real del 2026-09-08
1. `systemctl stop hermes-bridge` → 2 corridas del check → alerta enviada:
`⚠️ SKEEN: Hermes Bridge NO responde desde las 06:04 y servicio hermes-bridge NO responde desde las 06:04. Revisar.`
2. `systemctl start hermes-bridge` → corrida siguiente → 2 avisos:
`✅ SKEEN: Hermes Bridge recuperado.` / `✅ SKEEN: servicio hermes-bridge recuperado.`
3. Entrega bloqueada por la ventana 24 h (ver arriba). Los mensajes quedaron
guardados en el WACRM como evidencia.