Розробка системи мониторингу кількох нод
Мониторинг блокчейн-нод — це не «поставити Prometheus і спокійно спати». Blockchain-специфичні метрики принципово відрізняються від стандартних серверних: нода може бути повністю жива з точки зору процесу, але відстати на 10000 блоків від чейна і тихо віддавати застарілі дані клієнтам. Стандартний uptime-монітор цього не побачить.
Завдання ускладнюється при мультисітьовій інфраструктурі: Ethereum full node, BSC validator, Solana RPC, Cosmos validator — кожна має своє телеметрію, свої RPC-методи для перевірки стану, свої критичні метрики.
Що реально потрібно мониторити
Blockchain-специфичні метрики
Block height lag — відставання від мережі. Найважливіша метрика. Нода жива, але відстала — для RPC-сервісу це критично (клієнти отримують несвіжі дані), для validator — ризик slashing.
// Перевірка lag для EVM-сумісної ноди
async function checkBlockLag(nodeRpc: string, referenceRpc: string): Promise<number> {
const [nodeBlock, referenceBlock] = await Promise.all([
getBlockNumber(nodeRpc),
getBlockNumber(referenceRpc), // публічний ендпоінт як орієнтир
]);
return referenceBlock - nodeBlock;
}
async function getBlockNumber(rpc: string): Promise<number> {
const response = await fetch(rpc, {
method: "POST",
body: JSON.stringify({ jsonrpc: "2.0", method: "eth_blockNumber", id: 1 }),
headers: { "Content-Type": "application/json" },
signal: AbortSignal.timeout(5000),
});
const { result } = await response.json();
return parseInt(result, 16);
}
Peer count — кількість підключених пірів. Низький peer count (< 5) означає проблеми з синхронізацією та потенційно ізольовану ноду. Для Ethereum: net_peerCount. Для Cosmos: /net_info через RPC.
Sync status — нода в режимі синхронізації чи вже синхронізована. Для Ethereum: eth_syncing повертає false (синхронізована) або об'єкт з прогресом. Нода на sync не має приймати production трафік.
Mempool depth — кількість pending транзакцій. Для RPC-нод великий mempool може вказувати на проблеми з обробкою. Для Ethereum: txpool_status.
Validator-специфичні метрики (Cosmos, Ethereum PoS):
- Missed blocks / attestations — пропущені підписи ведуть до slashing
- Validator balance (ETH) — при падінні нижче порога ejection validator виключається
- Double sign risk — мониторинг спроб двійної підписи
Інфраструктурні метрики з blockchain-контекстом
Стандартні CPU/RAM/Disk метрики критичні, але інтерпретуються по-різному. Ethereum full node потребує 1–2 TB на NVMe (не HDD). Різкий ріст I/O може означати активну ресинхронізацію. Ethereum при повному навантаженню на RPC потребує 16–32 GB RAM — це норма, не утечка.
Архітектура системи мониторингу
Collector слой
Для кожного типу ноди — спеціалізований collector, який перекладає blockchain-специфичну телеметрію в уніфікований формат (Prometheus metrics).
// Collector для EVM-сумісних нод (Go)
type EVMNodeCollector struct {
nodeRPC string
referenceRPC string
nodeName string
chainID string
}
func (c *EVMNodeCollector) Describe(ch chan<- *prometheus.Desc) {
ch <- blockLagDesc
ch <- peerCountDesc
ch <- syncStatusDesc
ch <- mempoolSizeDesc
}
func (c *EVMNodeCollector) Collect(ch chan<- prometheus.Metric) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
lag, err := c.getBlockLag(ctx)
if err != nil {
ch <- prometheus.NewInvalidMetric(blockLagDesc, err)
return
}
ch <- prometheus.MustNewConstMetric(
blockLagDesc,
prometheus.GaugeValue,
float64(lag),
c.nodeName, c.chainID,
)
// ... решта метрик
}
Для Cosmos-based нод — парсинг /status, /net_info, /validators через RPC. Для Solana — JSON-RPC методи getHealth, getSlot, getVoteAccounts. Для Bitcoin — getblockchaininfo, getpeerinfo.
Готові експортери vs кастомні:
-
ethereum-exporter(відкритий) покриває базові EVM метрики -
cosmos-validator-exporter(Frens Validator) — для Cosmos екосистеми - Для нестандартних протоколів (TON, Solana з кастомними метриками) — писати exporter самостійно на Go
Агрегація та зберігання
Prometheus + VictoriaMetrics для довгострокового зберігання. VictoriaMetrics переважніше для мультисітьових операцій: краще стискає часові ряди, підтримує federated scraping з кількох Prometheus-інстансів.
# prometheus.yml — scrape config для мульти-нодового окружения
scrape_configs:
- job_name: 'ethereum-nodes'
scrape_interval: 15s
scrape_timeout: 10s
static_configs:
- targets:
- 'eth-node-1:9090'
- 'eth-node-2:9090'
- 'eth-node-3:9090'
relabel_configs:
- source_labels: [__address__]
target_label: instance
- job_name: 'cosmos-validators'
scrape_interval: 30s # Cosmos блок ~6 сек, 30 сек достатньо
static_configs:
- targets: ['cosmos-val-1:26660', 'cosmos-val-2:26660']
- job_name: 'solana-rpc'
scrape_interval: 10s # Solana ~400ms слот, потрібна частіша перевірка
static_configs:
- targets: ['solana-rpc-1:9101']
Алертинг
Grafana Alerting або AlertManager. Ключовий принцип: різна severity для різних метрик. Не все потребує негайної реакції.
| Метрика | Warning | Critical | Дія |
|---|---|---|---|
| Block lag (EVM) | > 10 блоків | > 50 блоків | Auto-restart або переключення трафіку |
| Peer count | < 10 | < 3 | Перевірка firewall/network |
| Disk space | < 20% | < 10% | Розширення чи pruning |
| Validator missed | > 1% | > 5% | Негайно (slashing ризик) |
| Memory usage | > 80% | > 95% | Перевірка утечок, перезапуск |
# alertmanager rules
groups:
- name: blockchain-nodes
rules:
- alert: ValidatorMissedBlocks
expr: rate(cosmos_validator_missed_blocks_total[5m]) > 0.05
for: 2m
labels:
severity: critical
annotations:
summary: "Validator {{ $labels.validator }} пропускає >5% блоків"
description: "Ризик slashing. Негайна дія необхідна."
- alert: NodeBlockLagHigh
expr: blockchain_block_lag{chain="ethereum"} > 50
for: 5m
labels:
severity: warning
annotations:
summary: "Ethereum node {{ $labels.instance }} відстає на {{ $value }} блоків"
Автоматичне реагування
Пасивний мониторинг недостатньо для 24/7 production. Для критичних сценаріїв — автоматичні remediation дії.
Auto-failover для RPC-нод. Load balancer (HAProxy/nginx) перевіряє health-ендпоінт ноди, при failure — автоматично виключає з rotation. Health check для blockchain-ноди має включати перевірку block lag, не тільки HTTP 200.
# Скрипт health check для HAProxy (викликається як external check)
import sys
import asyncio
from web3 import AsyncWeb3
MAX_LAG = 20 # максимально допустимий lag в блоках
async def check_node_health(node_url: str, reference_url: str) -> bool:
try:
w3_node = AsyncWeb3(AsyncWeb3.AsyncHTTPProvider(node_url, request_kwargs={"timeout": 3}))
w3_ref = AsyncWeb3(AsyncWeb3.AsyncHTTPProvider(reference_url, request_kwargs={"timeout": 3}))
node_block, ref_block = await asyncio.gather(
w3_node.eth.block_number,
w3_ref.eth.block_number,
)
return (ref_block - node_block) <= MAX_LAG
except Exception:
return False
if not asyncio.run(check_node_health(sys.argv[1], sys.argv[2])):
sys.exit(1)
Auto-restart при зависанні. Нода може зависнути без краху процесу. Watchdog: якщо block height не змінився протягом N хвилин — перезапуск service через systemd або Kubernetes restart policy.
Дашборди
Grafana дашборди за структурою: Overview (всі ноди, всі мережі, статус одним взглядом), Per-network deep dive (детальні метрики по кожній мережі), Validator performance (для staking нод, включаючи APR та slashing ризики), Infrastructure (CPU/RAM/Disk по нодам).
Для публічних RPC-сервісів — додатково: метрики запитів (RPS, latency, error rate), rate limiting статистика, топ методів за навантаженням.
Сроки розробки
| Компонент | Срок |
|---|---|
| Базові експортери (EVM + 1–2 інші мережі) | 1–2 тижні |
| Prometheus + VictoriaMetrics + Grafana setup | 3–5 днів |
| Правила алертів + PagerDuty/Telegram інтеграція | 2–3 дні |
| Auto-failover для RPC | 1 неділя |
| Дашборди + документація | 1 неділя |
Мониторинг для 3–5 мереж з базовими дашбордами та алертами — 3–4 тижні. Розширена система з auto-remediation та кастомними експортерами для нестандартних протоколів — 6–8 тижнів.







