nordabiz/docs/superpowers/specs/2026-03-15-uptime-monitoring-design.md
Maciej Pienczyn 9540f7f2e0
Some checks are pending
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
feat: add uptime monitoring dashboard with UptimeRobot integration
External monitoring via UptimeRobot (free tier) with internal health
logger to differentiate ISP outages from server issues. Includes:
- 4 new DB models (UptimeMonitor, UptimeCheck, UptimeIncident, InternalHealthLog)
- Migration 082 with tables, indexes, and permissions
- Internal health logger script (cron */5 min)
- UptimeRobot sync script (cron hourly) with automatic cause correlation
- Admin dashboard /admin/uptime with uptime %, response time charts,
  incident log with editable notes/causes, pattern analysis, monthly report
- SLA comparison table (99.9%/99.5%/99%)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 07:53:05 +01:00

150 lines
5.3 KiB
Markdown

# Uptime Monitoring - Design Spec
**Data:** 2026-03-15
**Status:** Zatwierdzony
## Problem
Portal nordabiznes.pl jest hostowany on-premise w INPI, za ISP Telewizja Kablowa Chopin. W ciągu ostatnich 2 miesięcy wystąpiły minimum 3 awarie internetu (10 marca, 14 marca + wcześniejszy incydent), powodujące niedostępność portalu z zewnątrz. Brak monitoringu uniemożliwia:
- Udokumentowanie skali problemu
- Odróżnienie awarii ISP od awarii serwera
- Podjęcie decyzji o ewentualnej migracji hostingu
## Rozwiązanie
Podejście B: UptimeRobot (zewnętrzny monitoring) + wewnętrzny health logger z korelacją awarii.
## Architektura
```
UptimeRobot.com (free) NORDABIZ-01 (10.22.68.249)
│ sprawdza co 5 min │ wewnętrzny logger co 5 min
│ HTTPS → nordabiznes.pl │ app/db/cpu/ram/disk → PostgreSQL
│ │
└── REST API ──────────────────→ │ sync co godzinę
│ korelacja: ISP vs serwer vs infra
/admin/uptime (dashboard)
```
### Korelacja awarii
| UptimeRobot | Wewnętrzny log | Diagnoza |
|---|---|---|
| DOWN | serwer OK | Awaria ISP (Chopin) |
| DOWN | serwer DOWN | Awaria serwera/VM |
| DOWN | brak logów | Awaria infrastruktury INPI |
| UP | serwer OK | Wszystko działa |
## Schemat bazy danych
### uptime_monitors
Konfiguracja monitorów UptimeRobot.
| Kolumna | Typ | Opis |
|---------|-----|------|
| id | SERIAL PK | |
| uptimerobot_id | INTEGER UNIQUE | ID monitora w UptimeRobot |
| name | VARCHAR(200) | Nazwa monitora |
| url | VARCHAR(500) | Monitorowany URL |
| check_interval_sec | INTEGER | Interwał sprawdzania (300 = 5 min) |
| is_active | BOOLEAN DEFAULT TRUE | |
| created_at | TIMESTAMP | |
### uptime_checks
Wyniki sprawdzeń z UptimeRobot (synchronizowane co godzinę).
| Kolumna | Typ | Opis |
|---------|-----|------|
| id | SERIAL PK | |
| monitor_id | INTEGER FK | → uptime_monitors.id |
| checked_at | TIMESTAMP | Czas sprawdzenia |
| status | VARCHAR(20) | 'up' / 'down' / 'paused' |
| response_time_ms | INTEGER | Czas odpowiedzi w ms |
| status_code | INTEGER | HTTP status code |
### uptime_incidents
Okresy niedostępności z automatyczną diagnozą przyczyny.
| Kolumna | Typ | Opis |
|---------|-----|------|
| id | SERIAL PK | |
| monitor_id | INTEGER FK | → uptime_monitors.id |
| started_at | TIMESTAMP | Początek awarii |
| ended_at | TIMESTAMP NULL | Koniec (NULL = trwa) |
| duration_seconds | INTEGER | Czas trwania |
| cause | VARCHAR(20) | 'isp' / 'server' / 'infra' / 'unknown' |
| notes | TEXT | Notatki admina |
| auto_resolved | BOOLEAN DEFAULT FALSE | Czy zakończony automatycznie |
### internal_health_logs
Wewnętrzny stan serwera (cron co 5 min, lokalnie).
| Kolumna | Typ | Opis |
|---------|-----|------|
| id | SERIAL PK | |
| checked_at | TIMESTAMP | |
| app_ok | BOOLEAN | /health odpowiada OK |
| db_ok | BOOLEAN | PostgreSQL dostępny |
| cpu_percent | REAL | Użycie CPU % |
| ram_percent | REAL | Użycie RAM % |
| disk_percent | REAL | Użycie dysku % |
| gunicorn_workers | INTEGER | Liczba aktywnych workerów |
## Skrypty
### scripts/internal_health_logger.py
- Cron: `*/5 * * * *`
- Sprawdza: localhost:5000/health, połączenie DB, psutil (CPU/RAM/disk), pgrep gunicorn
- Zapisuje do `internal_health_logs`
- Retencja: automatyczne czyszczenie logów starszych niż 90 dni
### scripts/uptimerobot_sync.py
- Cron: `0 * * * *` (co godzinę)
- Pobiera z UptimeRobot API: response times, logi (up/down events)
- Zapisuje do `uptime_checks`
- Tworzy/aktualizuje `uptime_incidents` na podstawie logów down/up
- Koreluje z `internal_health_logs` — ustawia `cause` automatycznie
- Env: `UPTIMEROBOT_API_KEY` w .env
## Dashboard /admin/uptime
### Sekcje
1. **Aktualny status** — badge UP/DOWN, czas ostatniego sprawdzenia, response time
2. **Uptime podsumowanie** — karty 24h/7d/30d/90d z procentem i oceną SLA
- ≥99.9% zielony, 99.5-99.9% żółty, <99.5% czerwony
- Kontekst: "99.5% = max 3.6h przestoju/miesiąc"
3. **Wykres response time** Chart.js, przełącznik 24h/7d/30d
4. **Lista incydentów** tabela z: data, czas trwania, przyczyna (ISP/Serwer/Infra), notatki (edytowalne)
5. **Analiza wzorców** wykres słupkowy: awarie wg godziny/dnia tygodnia
6. **Raport miesięczny** SLA %, łączny downtime, liczba incydentów, najdłuższa awaria, trend
### Dostęp
- Route: `/admin/uptime`
- Wymagana rola: `SystemRole.OFFICE_MANAGER`
- Auto-refresh: co 5 min (JSON API endpoint `/admin/api/uptime`)
- Link w nawigacji: sekcja System "Monitoring uptime"
## UptimeRobot Setup (manual)
1. Konto na uptimerobot.com (free tier)
2. Monitor: HTTP(s), URL `https://nordabiznes.pl/health`, interwał 5 min
3. Alert contact: email
4. API key (Main API Key, read-only) `.env` jako `UPTIMEROBOT_API_KEY`
## Retencja danych
| Tabela | Retencja |
|--------|----------|
| uptime_checks | 90 dni (sync script czyści starsze) |
| uptime_incidents | Bez limitu (kluczowe dla raportów) |
| internal_health_logs | 90 dni (health logger czyści starsze) |
## Technologie
- Backend: Flask route w `routes_status.py`
- Frontend: Jinja2 template, Chart.js (już używany w projekcie)
- Scheduled: systemowy cron (jak istniejące skrypty)
- External: UptimeRobot free API