Files
MatchLiveTv/docs/OPS_MONITORING.md
Emiliano Frascaro a44d9fbadd HLS su edge e monitoraggio ops con latenza p95.
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>
2026-06-14 21:19:32 +02:00

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

  1. Installa ntfy (Android/iOS)
  2. Impostazioni → Default server (o «Usa altro server») → https://ntfy.matchlivetv.it
    In casa, in alternativa: http://192.168.1.146:8090
  3. + → iscriviti al topic OPS_NTFY_TOPIC (es. matchlivetv-ops-eminux-a8f3b2)
  4. 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 in user.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.shops: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 (header X-Ops-Token)
  • TCP: porta 1935 (RTMP)
  • Notifica: stesso topic ntfy

Workflow rilascio

  1. cd backend && bundle exec rspec (o equivalente in Docker dev)
  2. Ciclo patch/test fino a 0 failure
  3. git commitgit push
  4. bash scripts/deploy/release_production.sh (sync + deploy con pagina di cortesia)
    • In alternativa manuale: sync → sul server bash scripts/deploy/release_production.sh --local
  5. Smoke test:
    • curl -sf https://www.matchlivetv.it/up
    • bundle 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)