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
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>
5.3 KiB
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_incidentsna podstawie logów down/up - Koreluje z
internal_health_logs— ustawiacauseautomatycznie - Env:
UPTIMEROBOT_API_KEYw .env
Dashboard /admin/uptime
Sekcje
- Aktualny status — badge UP/DOWN, czas ostatniego sprawdzenia, response time
- 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"
- Wykres response time — Chart.js, przełącznik 24h/7d/30d
- Lista incydentów — tabela z: data, czas trwania, przyczyna (ISP/Serwer/Infra), notatki (edytowalne)
- Analiza wzorców — wykres słupkowy: awarie wg godziny/dnia tygodnia
- 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)
- Konto na uptimerobot.com (free tier)
- Monitor: HTTP(s), URL
https://nordabiznes.pl/health, interwał 5 min - Alert contact: email
- API key (Main API Key, read-only) →
.envjakoUPTIMEROBOT_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