# 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 (57.128.200.27) │ 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