📘 Що таке Uptime Monitoring?
Uptime monitoring — це автоматична перевірка доступності вашого сайту/API через регулярні інтервали часу (наприклад, кожні 5 хвилин). Якщо сайт не відповідає (downtime), система негайно надсилає сповіщення через email, SMS, Slack, Telegram тощо.
- 🕒 Uptime — відсоток часу, коли сайт працював (ціль: 99.9%+)
- ⏱️ Response Time — швидкість відповіді сервера (ціль: <500ms)
- 🔴 Downtime — час, коли сайт був недоступний
- 🔔 Alerts — сповіщення про проблеми
Частина 1: Порівняння сервісів
| Сервіс |
Безкоштовний план |
Інтервал перевірки |
Кількість моніторів |
Локації |
Алертинг |
Status Page |
| UptimeRobot |
✅ Так |
5 хвилин |
50 моніторів |
1 локація |
Email, Webhook |
✅ Безкоштовна public status page |
| Pingdom |
⚠️ Обмежена (14 днів trial) |
1 хвилина |
10 моніторів (trial) |
100+ локацій |
Email, SMS, Slack |
✅ Включено |
| Better Uptime |
✅ Так |
3 хвилини |
10 моніторів |
6 регіонів |
Email, SMS, Slack, Teams |
✅ Красива public status page |
| Freshping |
✅ Так |
1 хвилина |
50 моніторів |
10 локацій |
Email, Slack, Webhook |
✅ Безкоштовна |
| StatusCake |
✅ Так |
5 хвилин |
Unlimited |
6 локацій |
Email, Webhook |
⚠️ Платна |
| Uptime.com |
⚠️ 21 день trial |
1 хвилина |
5 моніторів (trial) |
30+ локацій |
Email, SMS, Slack, PagerDuty |
✅ Включено |
🏆 Рекомендації для різних сценаріїв:
- UptimeRobot — найкращий безкоштовний варіант для малих проектів (50 моніторів!)
- Better Uptime — красива UI та чудова status page
- Pingdom — професійний рівень, максимальна точність
- Freshping — безкоштовні перевірки кожну хвилину
Частина 2: Налаштування UptimeRobot (безкоштовний план)
1
Реєстрація в UptimeRobot
- Відкрийте https://uptimerobot.com
- Натисніть "Start Monitoring for Free"
- Заповніть форму реєстрації (email + пароль)
- Підтвердіть email
2
Створення першого монітора
- Натисніть "+ Add New Monitor"
- Оберіть тип:
- HTTP(s) — перевірка веб-сайту (найпоширеніший)
- Ping — перевірка ICMP ping
- Port — перевірка відкритого порту (SSH, FTP, SMTP)
- Keyword — перевірка наявності тексту на сторінці
- Заповніть параметри:
Monitor Type: HTTP(s)
Friendly Name: SciCalc Main Site
URL (or IP): https://scientific-calculators.com
Monitoring Interval: 5 minutes (безкоштовний план)
- Додаткові налаштування:
- Натисніть "Create Monitor"
[Screenshot: UptimeRobot Dashboard з новим монітором]
3
Налаштування Alert Contacts (сповіщення)
UptimeRobot підтримує різні канали сповіщень:
Email сповіщення
- Перейдіть у My Settings → Alert Contacts
- Натисніть "Add Alert Contact"
- Оберіть Email
- Введіть email-адресу
- Підтвердіть через лист на пошті
Slack інтеграція
- У Slack: Settings → Manage Apps → Incoming Webhooks
- Натисніть "Add to Slack"
- Оберіть канал (наприклад,
#monitoring)
- Скопіюйте Webhook URL:
https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXX
- У UptimeRobot: Add Alert Contact → Webhook
- Вставте Slack Webhook URL
- POST Value:
{
"text": "*monitorFriendlyName* is *alertTypeFriendlyName* (alertDetails)"
}
Telegram інтеграція
- Створіть Telegram бота через @BotFather:
/newbot
Bot Name: UptimeRobot Alerts
Bot Username: sciCalcUptimeBot
- Отримайте Bot Token:
123456789:ABCdefGHIjklMNOpqrsTUVwxyz
- Отримайте свій Chat ID (напишіть боту /start, потім відкрийте):
https://api.telegram.org/bot123456789:ABCdefGHIjklMNOpqrsTUVwxyz/getUpdates
Знайдіть "chat":{"id":987654321}
- У UptimeRobot: Add Alert Contact → Webhook
- URL:
https://api.telegram.org/bot123456789:ABCdefGHIjklMNOpqrsTUVwxyz/sendMessage
- POST Value:
{
"chat_id": "987654321",
"text": "🚨 *monitorFriendlyName* is *alertTypeFriendlyName*\n\nDetails: *alertDetails*\nDuration: *alertDuration*",
"parse_mode": "Markdown"
}
4
Створення Public Status Page
- Перейдіть у Status Pages → Add New Status Page
- Оберіть монітори для відображення
- Налаштуйте дизайн:
- Page Name: Scientific Calculators Status
- Logo URL: https://scientific-calculators.com/images/logo.png
- Custom Domain (PRO): status.scientific-calculators.com
- Friendly URL: https://stats.uptimerobot.com/ABC123
- Додайте секції:
- Main Website — https://scientific-calculators.com
- API — https://api.scientific-calculators.com
- CDN Assets — https://cdn.scientific-calculators.com
- Натисніть "Create Status Page"
✅ Готово! Тепер ви можете поділитися посиланням:
https://stats.uptimerobot.com/ABC123
Користувачі побачать реальний час uptime ваших сервісів.
Частина 3: Налаштування Better Uptime (красивий UI)
2
Створення монітора
- Monitors → + Create Monitor
- Заповніть:
URL: https://scientific-calculators.com
Monitor Name: Main Site
Check frequency: Every 3 minutes
Pronounceable name: Say Calc Main Site (для голосових алертів!)
Regions: All available (6 регіонів)
- Advanced options:
- Expected Status Code: 200
- Request Timeout: 30 seconds
- SSL Certificate expiry alert: ✅ 30 days before
- Expected Keywords: Калькулятори
3
On-call Schedule (розклад чергувань)
Better Uptime дозволяє налаштувати escalation policy (хто отримає алерт і коли):
- On-call → + Create Schedule
- Додайте команду:
- Level 1 (негайно): Email + SMS головному розробнику
- Level 2 (через 5 хв якщо не відповів): Дзвінок + Slack у канал #incidents
- Level 3 (через 15 хв): PagerDuty/Opsgenie для всієї команди
# Приклад escalation policy
Incident detected:
├─ 0 min: Email → dev@company.com
├─ 0 min: SMS → +380501234567
├─ 5 min (no ack): Phone Call → +380501234567
├─ 5 min (no ack): Slack → #incidents
└─ 15 min (no ack): PagerDuty → Escalate to Team Lead
4
Status Page (найкрасивіша!)
- Status Pages → + Create Status Page
- Налаштування:
Company Name: Scientific Calculators
Subdomain: scicalc.betteruptime.com
Logo: [Upload PNG/SVG]
Timezone: Europe/Kyiv
Theme: Dark / Light / Auto
- Додайте Resources (сервіси):
- 🌐 Main Website
- ⚙️ Calculation API
- 📊 Analytics Dashboard
- Увімкніть Subscribe to Updates — користувачі зможуть підписатись на email сповіщення
- Custom Domain (опціонально):
# Додайте CNAME запис у DNS
status.scientific-calculators.com → scicalc.betteruptime.com
[Screenshot: Better Uptime Status Page з beautiful UI, uptime graphs, incident history]
Частина 4: Моніторинг API endpoints
Для API потрібні більш детальніші перевірки, ніж просто HTTP 200:
JSON Response Validation
// UptimeRobot → Advanced Settings → Expected Response
// Перевіряємо, чи API повертає коректну структуру
// Endpoint: https://api.scientific-calculators.com/v1/health
// Expected Response:
{
"status": "ok",
"version": "1.0.0",
"uptime": 123456
}
// Better Uptime → Assertion Rules:
// response.body.status == "ok"
// response.time < 500ms
POST Request Monitoring
# Better Uptime підтримує POST/PUT/PATCH запити
Method: POST
URL: https://api.scientific-calculators.com/v1/math/quadratic
Headers:
Content-Type: application/json
Authorization: Bearer sk_test_123
Body:
{
"a": 1,
"b": -5,
"c": 6
}
Expected Response:
{
"discriminant": 1,
"roots": {
"x1": 3,
"x2": 2
}
}
Assertions:
- response.status == 200
- response.body.discriminant > 0
- response.body.roots.x1 == 3
Частина 5: Self-hosted моніторинг (Uptime Kuma)
Якщо потрібен повний контроль без обмежень:
1
Встановлення Uptime Kuma (Docker)
# Встановлення через Docker
docker run -d \
--name uptime-kuma \
-p 3001:3001 \
-v uptime-kuma:/app/data \
--restart always \
louislam/uptime-kuma:1
# Відкрийте у браузері
http://localhost:3001
Або з docker-compose.yml:
version: '3.8'
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
volumes:
- ./uptime-kuma-data:/app/data
ports:
- "3001:3001"
restart: always
# Запуск
docker-compose up -d
# Логи
docker-compose logs -f
2
Налаштування Uptime Kuma
- Створіть адмін-акаунт
- Add New Monitor:
- Monitor Type: HTTP(s)
- Friendly Name: SciCalc Main
- URL: https://scientific-calculators.com
- Heartbeat Interval: 60 seconds
- Retries: 3
- Advanced: Expected Status Codes: 200-299
- Додайте Notification:
- Telegram: Bot Token + Chat ID
- Discord: Webhook URL
- Email (SMTP): Gmail/SendGrid credentials
- Slack: Incoming Webhook
Переваги Uptime Kuma
- ✅ Безкоштовний — unlimited monitors
- ✅ Self-hosted — ваші дані на вашому сервері
- ✅ Open-source — GitHub: louislam/uptime-kuma
- ✅ Beautiful UI — темна тема, responsive
- ✅ Status Pages — вбудовані публічні status pages
- ✅ Multi-language — українська мова!
Частина 6: Metrics та SLA розрахунки
Uptime % розрахунок
Формула:
Uptime % = (Total Time - Downtime) / Total Time × 100
Приклад за місяць (30 днів):
- Total Time: 30 днів × 24 год = 720 годин = 43200 хвилин
- Downtime: 25 хвилин
- Uptime % = (43200 - 25) / 43200 × 100 = 99.942%
SLA (Service Level Agreement) таблиця:
| Uptime % |
Downtime на рік |
Downtime на місяць |
Downtime на тиждень |
Рівень |
| 90% |
36.5 днів |
72 години |
16.8 годин |
❌ Неприйнятно |
| 95% |
18.25 днів |
36 годин |
8.4 години |
⚠️ Погано |
| 99% |
3.65 днів |
7.2 години |
1.68 годин |
⚠️ Прийнятно |
| 99.9% (three nines) |
8.76 годин |
43.2 хвилини |
10.1 хвилин |
✅ Добре |
| 99.99% (four nines) |
52.6 хвилин |
4.32 хвилини |
1.01 хвилина |
✅ Відмінно |
| 99.999% (five nines) |
5.26 хвилин |
25.9 секунд |
6.05 секунд |
🏆 Ідеально |
Response Time Metrics
# Цільові значення Response Time
Excellent: < 100ms ⚡ Блискавично швидко
Good: < 300ms ✅ Швидко
Acceptable: < 500ms ⚠️ Прийнятно
Slow: < 1000ms 🐌 Повільно
Critical: > 1000ms 🚨 Дуже повільно
# Percentiles (важливіше за середнє!)
p50 (median): 150ms — 50% запитів швидше
p95: 300ms — 95% запитів швидше
p99: 500ms — 99% запитів швидше
p99.9: 800ms — 99.9% запитів швидше
Частина 7: Troubleshooting та Best Practices
Поширені проблеми
⚠️ False Positives (помилкові алерти)
- Проблема: Сайт працює, але UptimeRobot каже "DOWN"
- Причини:
- Firewall/CDN блокує IP UptimeRobot
- Rate limiting спрацював
- Тимчасова мережева проблема
- Рішення:
- Whitelist IP addresses UptimeRobot:
69.162.124.224/28
- Збільште
Request Timeout до 30 секунд
- Збільште
Retries до 3
- Додайте
User-Agent whitelist
✅ Best Practices:
- Моніторте різні endpoints:
- Головна сторінка:
/
- Health endpoint:
/health або /api/ping
- Критичні сторінки:
/calculators/quadratic-equation.html
- Налаштуйте Maintenance Windows — вимкніть алерти під час планового обслуговування
- Використовуйте Multi-location checking — якщо доступно (щоб виключити локальні проблеми)
- SSL Certificate expiry alerts — отримайте попередження за 30 днів до закінчення
- Status Page on separate infrastructure — host status page НЕ на тому ж сервері
- Test your alerts — регулярно перевіряйте, чи працюють сповіщення
- Document incident response — створіть runbook для команди
Створення Runbook (інструкції для інцидентів)
# Incident Response Runbook
## 🚨 Алерт: Site Down
### Immediate Actions (перші 5 хвилин)
1. ✅ Підтвердити incident (не false positive?)
- Перевірити сайт у браузері (incognito mode)
- Перевірити з різних локацій: https://isitdownrightnow.com
- Ping сервер: `ping scientific-calculators.com`
2. ✅ Оцінити масштаб
- Повністю down чи тільки окремі сторінки?
- Всі користувачі чи тільки певні регіони?
- API працює?
3. ✅ Повідомити команду
- Написати в #incidents Slack channel
- Оновити Status Page з повідомленням "Investigating"
### Investigation (5-15 хвилин)
1. Перевірити сервер
```bash
ssh user@server
systemctl status nginx
systemctl status apache2
df -h # Disk space
free -h # RAM
top # CPU usage
```
2. Перевірити логи
```bash
tail -n 100 /var/log/nginx/error.log
journalctl -u nginx -n 100
```
3. Перевірити DNS
```bash
dig scientific-calculators.com
nslookup scientific-calculators.com
```
### Resolution
- Якщо знайдено проблему → виправити
- Якщо невідома причина → перезапустити сервіси
- Якщо не вирішується → escalate до senior engineer
### Post-Incident
1. Оновити Status Page: "Resolved"
2. Написати Post-Mortem (що сталося, чому, як запобігти)
3. Оновити Runbook якщо потрібно
Частина 6: Self-Hosted Monitoring (Uptime Kuma)
6.1. Чому self-hosted?
✅ Переваги self-hosted моніторингу:
- 🔒 Повний контроль — ваші дані на вашому сервері
- 💰 Безкоштовно — unlimited моніторів без обмежень
- ⚡ Швидші перевірки — можна < 30 секунд
- 🎨 Кастомізація — необ межені можливості налаштування
- 📊 Власна база даних — зберігання історичних даних
6.2. Встановлення Uptime Kuma
1
Docker встановлення (найпростіший спосіб)
# Завантажити Uptime Kuma
docker pull louislam/uptime-kuma:1
# Запустити контейнер
docker run -d --restart=always \
-p 3001:3001 \
-v uptime-kuma:/app/data \
--name uptime-kuma \
louislam/uptime-kuma:1
# Відкрити у браузері: http://localhost:3001
2
Docker Compose (для production)
# docker-compose.yml
version: '3.8'
services:
uptime-kuma:
image: louislam/uptime-kuma:1
container_name: uptime-kuma
restart: unless-stopped
ports:
- "3001:3001"
volumes:
- ./uptime-kuma-data:/app/data
environment:
- TZ=Europe/Kyiv # Ваш часовий пояс
# Опціонально: Nginx reverse proxy
nginx:
image: nginx:alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- uptime-kuma
# Запуск
docker-compose up -d
# Перегляд логів
docker-compose logs -f uptime-kuma
6.3. Налаштування Nginx Reverse Proxy
# nginx.conf
server {
listen 80;
server_name status.example.com;
# Redirect to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name status.example.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
location / {
proxy_pass http://uptime-kuma:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket підтримка
proxy_read_timeout 86400;
}
}
6.4. Uptime Kuma Features
✨ Можливості Uptime Kuma:
- ✅ 25+ типів моніторів: HTTP, TCP, Ping, DNS, Docker, MongoDB, Redis, PostgreSQL, MySQL
- ✅ Multi-language status page — підтримка української!
- ✅ Notifications: Email, Telegram, Discord, Slack, Teams, Webhook, SMS
- ✅ Keyword matching — перевірка наявності тексту
- ✅ Certificate expiry monitoring — попередження про закінчення SSL
- ✅ Custom intervals — від 20 секунд
- ✅ Push monitors — для cron jobs та scheduled tasks
Частина 7: Prometheus + Grafana для моніторингу
7.1. Prometheus встановлення
# docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=30d'
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
- GF_SERVER_ROOT_URL=https://monitoring.example.com
depends_on:
- prometheus
blackbox-exporter:
image: prom/blackbox-exporter:latest
container_name: blackbox-exporter
restart: unless-stopped
ports:
- "9115:9115"
volumes:
- ./blackbox.yml:/etc/blackbox_exporter/config.yml:ro
volumes:
prometheus-data:
grafana-data:
7.2. Prometheus конфігурація
# prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
# Blackbox exporter для HTTP/HTTPS моніторингу
- job_name: 'blackbox'
metrics_path: /probe
params:
module: [http_2xx] # HTTP 200 перевірка
static_configs:
- targets:
- https://scientific-calculators.com
- https://scientific-calculators.com/calculator
- https://scientific-calculators.com/api/health
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: blackbox-exporter:9115
# SSL certificate expiry monitoring
- job_name: 'ssl_expiry'
metrics_path: /probe
params:
module: [http_2xx]
static_configs:
- targets:
- https://scientific-calculators.com
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- target_label: __address__
replacement: blackbox-exporter:9115
7.3. Blackbox Exporter конфігурація
# blackbox.yml
modules:
http_2xx:
prober: http
timeout: 5s
http:
valid_http_versions: ["HTTP/1.1", "HTTP/2.0"]
valid_status_codes: [200]
method: GET
fail_if_ssl: false
fail_if_not_ssl: true
tls_config:
insecure_skip_verify: false
preferred_ip_protocol: "ip4"
http_post:
prober: http
timeout: 5s
http:
method: POST
headers:
Content-Type: application/json
body: '{"test":"data"}'
tcp_connect:
prober: tcp
timeout: 5s
icmp:
prober: icmp
timeout: 5s
7.4. Grafana Dashboard для Uptime
📊 Імпортуйте готовий dashboard:
- Увійдіть у Grafana: http://localhost:3000
- Dashboards → Import
- Вставте ID: 7587 (Prometheus Blackbox Exporter)
- Оберіть Prometheus data source
- Натисніть Import
Частина 8: SSL Certificate Monitoring
8.1. Автоматична перевірка SSL
# ssl-check.sh
#!/bin/bash
DOMAIN="scientific-calculators.com"
WARNING_DAYS=30
# Отримати дату закінчення сертифіката
EXPIRY_DATE=$(echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:443 2>/dev/null | \
openssl x509 -noout -enddate | cut -d= -f2)
# Конвертувати у Unix timestamp
EXPIRY_TIMESTAMP=$(date -d "$EXPIRY_DATE" +%s)
CURRENT_TIMESTAMP=$(date +%s)
# Дні до закінчення
DAYS_LEFT=$(( ($EXPIRY_TIMESTAMP - $CURRENT_TIMESTAMP) / 86400 ))
echo "SSL certificate for $DOMAIN expires in $DAYS_LEFT days"
if [ $DAYS_LEFT -lt $WARNING_DAYS ]; then
echo "⚠️ WARNING: Certificate expires soon!"
# Надіслати сповіщення
curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL \
-H 'Content-Type: application/json' \
-d "{\"text\":\"⚠️ SSL certificate for $DOMAIN expires in $DAYS_LEFT days!\"}"
fi
8.2. SSL Labs API моніторинг
# ssl_labs_check.py
import requests
import time
def check_ssl_grade(domain):
# Запустити аналіз
api_url = f"https://api.ssllabs.com/api/v3/analyze?host={domain}&publish=off&startNew=on"
response = requests.get(api_url)
# Чекати на завершення
while True:
response = requests.get(f"https://api.ssllabs.com/api/v3/analyze?host={domain}")
data = response.json()
if data['status'] == 'READY':
break
print(f"Status: {data['status']}... waiting")
time.sleep(10)
# Отримати grade
grade = data['endpoints'][0]['grade']
print(f"SSL Labs Grade for {domain}: {grade}")
if grade not in ['A+', 'A', 'A-']:
print(f"⚠️ WARNING: SSL grade is {grade} (not optimal)")
# Надіслати alert
return grade
check_ssl_grade('scientific-calculators.com')
Частина 9: API Endpoint Monitoring
9.1. Моніторинг REST API
// api-monitor.js
const axios = require('axios');
const endpoints = [
{
name: 'Calculator API',
url: 'https://api.example.com/calculate',
method: 'POST',
body: { operation: 'add', a: 2, b: 3 },
expectedStatus: 200,
expectedResponse: { result: 5 }
},
{
name: 'Health Check',
url: 'https://api.example.com/health',
method: 'GET',
expectedStatus: 200
}
];
async function monitorEndpoint(endpoint) {
const startTime = Date.now();
try {
const response = await axios({
method: endpoint.method,
url: endpoint.url,
data: endpoint.body,
timeout: 5000
});
const responseTime = Date.now() - startTime;
// Перевірка статусу
if (response.status !== endpoint.expectedStatus) {
console.error(`❌ ${endpoint.name}: Wrong status ${response.status}`);
sendAlert(`${endpoint.name} returned ${response.status}`);
return false;
}
// Перевірка response
if (endpoint.expectedResponse) {
const match = JSON.stringify(response.data) === JSON.stringify(endpoint.expectedResponse);
if (!match) {
console.error(`❌ ${endpoint.name}: Unexpected response`);
sendAlert(`${endpoint.name} returned unexpected data`);
return false;
}
}
console.log(`✅ ${endpoint.name}: OK (${responseTime}ms)`);
// Перевірка response time
if (responseTime > 1000) {
console.warn(`⚠️ ${endpoint.name}: Slow response (${responseTime}ms)`);
}
return true;
} catch (error) {
console.error(`❌ ${endpoint.name}: ${error.message}`);
sendAlert(`${endpoint.name} failed: ${error.message}`);
return false;
}
}
async function runMonitoring() {
for (const endpoint of endpoints) {
await monitorEndpoint(endpoint);
}
}
// Запускати кожні 60 секунд
setInterval(runMonitoring, 60000);
runMonitoring(); // Перший запуск негайно
9.2. GraphQL API моніторинг
const { request, gql } = require('graphql-request');
async function monitorGraphQL() {
const endpoint = 'https://api.example.com/graphql';
const query = gql`
query HealthCheck {
health {
status
uptime
version
}
}
`;
try {
const data = await request(endpoint, query);
if (data.health.status !== 'OK') {
sendAlert(`GraphQL API unhealthy: ${data.health.status}`);
}
console.log(`✅ GraphQL API: ${data.health.status}`);
} catch (error) {
console.error(`❌ GraphQL API failed: ${error.message}`);
sendAlert(`GraphQL API error: ${error.message}`);
}
}
Частина 10: Advanced Analytics та Metrics
10.1. Calculating SLA (Service Level Agreement)
# sla_calculator.py
from datetime import datetime, timedelta
def calculate_sla(downtime_minutes, period_days=30):
"""
Розрахунок SLA на основі downtime
"""
total_minutes = period_days * 24 * 60
uptime_minutes = total_minutes - downtime_minutes
sla_percentage = (uptime_minutes / total_minutes) * 100
return {
'sla': round(sla_percentage, 4),
'uptime_minutes': uptime_minutes,
'downtime_minutes': downtime_minutes,
'total_minutes': total_minutes
}
# Приклади
print("99.9% SLA:", calculate_sla(43.2, 30)) # ~43 хв downtime на місяць
print("99.95% SLA:", calculate_sla(21.6, 30)) # ~22 хв downtime на місяць
print("99.99% SLA:", calculate_sla(4.32, 30)) # ~4 хв downtime на місяць
# Ваш реальний downtime
actual_downtime = 15 # хвилин downtime за місяць
result = calculate_sla(actual_downtime, 30)
print(f"\nВаш SLA: {result['sla']}%")
print(f"Uptime: {result['uptime_minutes']} хвилин ({result['uptime_minutes']/60:.1f} годин)")
print(f"Downtime: {result['downtime_minutes']} хвилин")
10.2. MTTR (Mean Time To Recovery)
// mttr-calculator.js
const incidents = [
{ start: '2026-01-15 10:30', resolved: '2026-01-15 10:45' }, // 15 хв
{ start: '2026-01-20 14:20', resolved: '2026-01-20 14:50' }, // 30 хв
{ start: '2026-02-01 09:00', resolved: '2026-02-01 09:10' }, // 10 хв
];
function calculateMTTR(incidents) {
const recoveryTimes = incidents.map(incident => {
const start = new Date(incident.start);
const resolved = new Date(incident.resolved);
return (resolved - start) / 1000 / 60; // хвилини
});
const totalRecoveryTime = recoveryTimes.reduce((sum, time) => sum + time, 0);
const mttr = totalRecoveryTime / incidents.length;
console.log('Recovery times:', recoveryTimes, 'minutes');
console.log(`MTTR: ${mttr.toFixed(1)} minutes`);
console.log(`Total incidents: ${incidents.length}`);
return mttr;
}
calculateMTTR(incidents);
// Виведе: MTTR: 18.3 minutes
10.3. Availability Zones моніторинг
# multi_region_check.py
import requests
import concurrent.futures
regions = {
'us-east': 'https://us-east.api.example.com/health',
'eu-west': 'https://eu-west.api.example.com/health',
'ap-south': 'https://ap-south.api.example.com/health',
}
def check_region(region, url):
try:
response = requests.get(url, timeout=5)
latency = response.elapsed.total_seconds() * 1000
return {
'region': region,
'status': 'UP' if response.status_code == 200 else 'DOWN',
'latency': round(latency, 2),
'status_code': response.status_code
}
except Exception as e:
return {
'region': region,
'status': 'DOWN',
'error': str(e)
}
def check_all_regions():
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = [executor.submit(check_region, region, url)
for region, url in regions.items()]
results = [f.result() for f in concurrent.futures.as_completed(futures)]
for result in results:
if result['status'] == 'UP':
print(f"✅ {result['region']}: {result['latency']}ms")
else:
print(f"❌ {result['region']}: {result.get('error', 'Unknown error')}")
return results
check_all_regions()
Частина 11: Integration з DevOps Tools
11.1. PagerDuty Integration
# pagerduty_alert.py
import requests
def trigger_pagerduty_incident(summary, severity='error'):
"""
Створити incident у PagerDuty
"""
url = 'https://events.pagerduty.com/v2/enqueue'
payload = {
'routing_key': 'YOUR_ROUTING_KEY',
'event_action': 'trigger',
'payload': {
'summary': summary,
'severity': severity, # critical, error, warning, info
'source': 'uptime-monitor',
'custom_details': {
'url': 'https://scientific-calculators.com',
'incident_time': '2026-02-07 14:30:00'
}
}
}
response = requests.post(url, json=payload)
if response.status_code == 202:
print(f"✅ PagerDuty incident created: {summary}")
else:
print(f"❌ Failed to create incident: {response.text}")
11.2. Datadog Integration
# datadog_metrics.py
from datadog import initialize, api
options = {
'api_key': 'YOUR_API_KEY',
'app_key': 'YOUR_APP_KEY'
}
initialize(**options)
# Надіслати uptime метрику
api.Metric.send(
metric='uptime.status',
points=1, # 1 = UP, 0 = DOWN
tags=['env:production', 'service:calculators']
)
# Надіслати response time
api.Metric.send(
metric='uptime.response_time',
points=245, # мілісекунди
tags=['env:production', 'endpoint:api']
)
11.3. Custom Webhook Alerts
# webhook_alert.sh
#!/bin/bash
WEBHOOK_URL="https://your-server.com/webhook/alerts"
# Надіслати JSON payload
curl -X POST $WEBHOOK_URL \
-H "Content-Type: application/json" \
-d '{
"type": "downtime",
"service": "scientific-calculators.com",
"status": "DOWN",
"timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
"details": {
"http_code": 503,
"response_time": null,
"error": "Service Unavailable"
}
}'
Висновок
Моніторинг доступності — must-have для будь-якого production веб-сайту:
- 🏆 Почніть з UptimeRobot — безкоштовний, простий, надійний
- 📊 Створіть Public Status Page — прозорість для користувачів
- 🔔 Налаштуйте алерти — Email + Slack + SMS для критичних сервісів
- 📈 Відстежуйте SLA — ціль: 99.9%+ uptime
- 🎯 Response Time < 500ms — швидкість = UX
🚀 Рекомендований setup для малих проектів:
- UptimeRobot (безкоштовний) — 3-5 моніторів (головна, API, важливі сторінки)
- Email + Slack alerts — негайні сповіщення
- Public Status Page — https://stats.uptimerobot.com/yourproject
- Uptime target: 99.9% — ~43 хв downtime на місяць
- Response time target: <500ms