Evita di saturare Puma in diretta, separa i check Rails/pubblico e traccia la latenza /up per alert più affidabili. Co-authored-by: Cursor <cursoragent@cursor.com>
5.4 KiB
Monitoraggio ops — Match Live TV
Sistema integrato per health check continui, analisi log, dashboard incidenti e notifiche push.
Componenti
| Componente | Ruolo |
|---|---|
Ops::HealthMonitorJob |
Sidekiq — health check ogni ~3 min |
Ops::HealthChecks |
Disco, DB, Redis, MediaMTX, Garage, Sidekiq, HTTP Rails (critical), latenza p95 /up, HTTP pubblico (warning) |
Ops::LogScanner |
Pattern regex su log Docker (cron ogni 10 min) |
Ops::Incident |
DB — incidenti con deduplicazione |
Ops::Notifier |
Push ntfy + email opzionale |
/admin/ops |
Dashboard incidenti |
GET /up/deep |
Health check esteso (JSON) |
Setup notifiche ntfy self-hosted (telefono)
Le push ops (disco pieno, Sidekiq, servizi giù) non passano da Firebase: Rails invia un POST al server ntfy incluso in docker-compose.prod.yml.
1. Server (Docker)
cd /opt/matchlivetv/infra
docker compose -f docker-compose.prod.yml --env-file .env up -d ntfy
Servizio in ascolto su LAN http://192.168.1.146:8090 (non esporre 8090 su Internet).
2. HTTPS (Nginx Proxy Manager)
Crea un Proxy Host (consigliato sottodominio dedicato):
| Campo | Valore |
|---|---|
| Domain | ntfy.matchlivetv.it |
| Forward | http://192.168.1.146:8090 |
| WebSockets | ON |
| SSL | Let's Encrypt |
In infra/.env:
NTFY_PUBLIC_URL=https://ntfy.matchlivetv.it
OPS_NTFY_TOPIC=matchlivetv-ops-eminux-a8f3b2 # topic segreto, a piacere
OPS_NTFY_URL=http://ntfy:80/matchlivetv-ops-eminux-a8f3b2
OPS_NOTIFY_SEVERITIES=critical,warning
OPS_NOTIFY_COOLDOWN_MINUTES=30
OPS_NTFY_URL usa il nome Docker ntfy (rete interna). Il telefono usa invece NTFY_PUBLIC_URL.
3. App sul telefono
- Installa ntfy (Android/iOS)
- Impostazioni → Default server (o «Usa altro server») →
https://ntfy.matchlivetv.it
In casa, in alternativa:http://192.168.1.146:8090 - + → iscriviti al topic
OPS_NTFY_TOPIC(es.matchlivetv-ops-eminux-a8f3b2) - Abilita notifiche per quel topic
4. Test
docker compose -f docker-compose.prod.yml exec -T rails bundle exec rails ops:test_notify
Dovresti ricevere una push «Test notifica ops» sul telefono.
Sicurezza
- Il topic è la «password»: usa un nome lungo e casuale, non pubblicarlo
- Opzionale: abilita auth su ntfy (
OPS_NTFY_TOKEN+ utente inuser.db) per topic protetti
Variabili ambiente
Vedi infra/.env.production.example.
| Variabile | Default | Descrizione |
|---|---|---|
OPS_NTFY_URL |
— | URL POST ntfy |
OPS_NTFY_TOKEN |
— | Bearer token (topic protetto) |
OPS_ALERT_EMAIL |
— | Fallback email |
OPS_HEALTH_INTERVAL_SECS |
180 | Intervallo health job |
OPS_HTTP_RAILS_URL |
http://edge/up |
Check Rails via edge (no hairpin NPM) |
OPS_HTTP_PUBLIC_INTERVAL_SECS |
900 | Intervallo check URL pubblico (warning) |
OPS_UP_LATENCY_WARN_MS |
2000 | Soglia warning latenza p95 /up |
OPS_UP_LATENCY_CRIT_MS |
5000 | Soglia critical latenza p95 /up |
OPS_UP_LATENCY_SAMPLES |
60 | Campioni Redis per p95 |
OPS_UP_LATENCY_MIN_SAMPLES |
5 | Campioni minimi prima di alert latenza |
OPS_HEALTH_TOKEN |
— | Token per /up/deep |
OPS_DISK_CRIT_PERCENT |
90 | Soglia critical disco |
OPS_LOG_SUBSCRIBER |
false | Cattura 500 in-process |
Cron produzione
cd /opt/matchlivetv/infra && bash scripts/install_production_cron.sh
| Schedule | Task |
|---|---|
| ogni 3 min (Sidekiq) | Ops::HealthMonitorJob |
*/10 * * * * |
scan_ops_logs.sh → ops:ingest_logs |
Uptime Kuma (consigliato)
Watchdog esterno se Rails è completamente giù:
- HTTP:
https://www.matchlivetv.it/up - HTTP deep:
https://www.matchlivetv.it/up/deep(headerX-Ops-Token) - TCP: porta 1935 (RTMP)
- Notifica: stesso topic ntfy
Workflow rilascio
cd backend && bundle exec rspec(o equivalente in Docker dev)- Ciclo patch/test fino a 0 failure
git commit→git pushbash scripts/deploy/release_production.sh(sync + deploy con pagina di cortesia)- In alternativa manuale: sync → sul server
bash scripts/deploy/release_production.sh --local
- In alternativa manuale: sync → sul server
- Smoke test:
curl -sf https://www.matchlivetv.it/upbundle exec rails ops:health_check(nel container)- Apri
/admin/ops
Downtime durante il rilascio
| Componente | Comportamento |
|---|---|
edge (nginx :3000) |
Resta sempre su — NPM non vede mai connection refused |
| Rails in restart | Pagina di cortesia HTML (auto-refresh 15s), non 502 NPM |
| RTMP :1935 / replay | Non toccati dal rilascio web |
/up |
Pass-through diretto (monitoraggio ops vede il breve gap) |
Config edge: infra/nginx-edge/. Script: scripts/deploy/release_production.sh.
Sentry (opzionale)
Imposta SENTRY_DSN dopo bundle install. Gli errori creano anche incidenti ops.
Troubleshooting
| Problema | Azione |
|---|---|
| Nessuna push | Verifica OPS_NTFY_URL, test con ops:test_notify |
| Troppi alert | Aumenta OPS_NOTIFY_COOLDOWN_MINUTES, usa Mute 24h in admin |
| Sidekiq stale | Verifica container sidekiq e log Sidekiq |
| Log scanner vuoto | Controlla ${MATCHLIVETV_VIDEOS_ROOT}/log/cron-ops.log (es. /media/videos/matchlivetv/log/cron-ops.log) |