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

5.3 KiB

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