nordabiz/docs/superpowers/specs/2026-03-15-uptime-monitoring-design.md
Maciej Pienczyn 110d971dca
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions
feat: migrate prod docs to OVH VPS + UTC→Warsaw timezone in all templates
Production moved from on-prem VM 249 (10.22.68.249) to OVH VPS
(57.128.200.27, inpi-vps-waw01). Updated ALL documentation, slash
commands, memory files, architecture docs, and deploy procedures.

Added |local_time Jinja filter (UTC→Europe/Warsaw) and converted
155 .strftime() calls across 71 templates so timestamps display
in Polish timezone regardless of server timezone.

Also includes: created_by_id tracking, abort import fix, ICS
calendar fix for missing end times, Pros Poland data cleanup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-06 13:41:53 +02: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 (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