Алерти для критичних помилок у Solana-додатках відрізняються від загального моніторингу тим, що мають спрацьовувати виключно на події, які вимагають негайної реакції інженера. Нижче — покрокова інструкція з класифікації таких подій, маршрутизації сповіщень, налаштування порогів та усунення хибних спрацьовувань.
Типи алертів: транзакційні відмови, падіння індексатора
Перш ніж конфігурувати алерти, треба чітко розділити події на дві категорії: ті, що свідчать про проблему з вашим сервісом, і ті, що є наслідком дій користувача або стану кластера.
Транзакційні відмови
Не кожна відмова транзакції є критичною. Алерт має спрацьовувати лише тоді, коли відмова вказує на дефект вашої програми або інфраструктури.
- InstructionError з кодами, що не повинні виникати в нормальному потоці. Наприклад, InstructionError::InvalidAccountData у логіці, де акаунт ініціалізується вашим сервісом і ви контролюєте його стан. Навпаки, InsufficientFunds або InvalidAccountOwner від сторонніх користувачів — це очікувані відмови, які не потребують алерту.
- Зростання частоти відмов конкретного типу. Якщо певний InstructionError починає з'являтися з частотою, що перевищує базовий рівень для вашого трафіку, це сигнал про регресію.
- Відмови внутрішніх CPI-викликів (Cross-Program Invocation). Якщо ваша програма викликає іншу програму через CPI і той виклик систематично завершується помилкою, це критична подія, оскільки ви не контролюєте цільову програму, але залежите від неї.
- Таймаути підписання та префлайт-відмови (preflight failures), що перевищують норму. Разові префлайт-відмови бувають через тимчасове перевантаження кластера. Систематичні — вказують на проблему з підключенням до RPC-вузла або некоректне формування транзакцій.
Джерело даних: логи вашого бекенду після десеріалізації відповідей від RPC, або метрики, які ваш сервіс експортує після обробки кожної транзакції.
Падіння індексатора
Якщо ваш стек включає індексатор (наприклад, власний сервіс на базі gRPC-підписки до вузла або рішення на кшталт Helius/Yellowstone), його недоступність означає втрату даних або зупинку бізнес-логіки.
- Повна зупинка процесу. Моніторинг через systemd або інший process manager: алерт, якщо процес не відповідає на health-check або відсутній у таблиці процесів.
- Відставання за слотом (slot lag). Індексатор має відстежувати поточний слот кластера. Якщо різниця перевищує допустиме значення, індексатор фактично не обробляє нові блоки. Порогове значення залежить від вашого use-case: для торгових сервісів це може бути 10–20 слотів, для аналітичних — значно більше.
- Помилки підключення до gRPC/WebSocket. Розрив підписки з валідатором або RPC-вузлом. Алерт має спрацьовувати після повторних невдалих спроб реконекту протягом визначеного інтервалу.
- Вичерпання ресурсів. OOM-killer, перевищення лімітів файлових дескрипторів, зростання черги повідомлень понад контрольовану межу.
Канали сповіщень: Slack, Telegram, PagerDuty
Кожен канал має свою роль. Головне правило: один тип алерту — один основний канал, дублювання лише для критичних рівнів.
Slack
Підходить для алертів середньої критичності та для командного контексту, де потрібне швидке обговорення.
- Використовуйте окремий канал (наприклад, #alerts-solana-prod), не змішуйте з загальними робочими каналами.
- У повідомленні обов'язково містіть: тип помилки, час, кількість випадків за вікно, посилання на дашборд із деталізованими логами.
- Налаштуйте webhook через Incoming Webhooks або використовуйте інтеграцію з вашою системою моніторингу (Prometheus Alertmanager, Grafana Alerts тощо).
Обмеження: Slack не гарантує доставку в реальному часі, сповіщення можна пропустити поза робочими годинами. Тому для критичних алертів Slack має бути додатковим, а не єдиним каналом.
Telegram
Зручний для мобільних інженерів, особливо якщо команда розподілена між часовими зонами.
- Створіть окремий бот і групу для алертів. Не використовуйте особисті чати — це ускладнює ротацию чергування (on-call).
- Форматуйте повідомлення з використанням Markdown або HTML, що підтримує Telegram: виділяйте тип помилки та сервіс.
- Увімкніть сповіщення без звуку для некритичних рівнів та зі звуком — для критичних.
Обмеження: Telegram API має ліміти на частоту повідомлень (приблизно 1 повідомлення на секунду в одну групу). При масових спрацьовуваннях використовуйте локальну чергу або агрегацію на стороні системи моніторингу.
PagerDuty
Обов'язковий канал для алертів найвищого критичного рівня, де потрібна гарантована доставка та ескалація.
- Створіть окремий сервіс для Solana-продакшену з чітко визначеною політикою ескалації: перший інженер отримує сповіщення негайно, якщо не відповідає протягом N хвилин — ескалація на другого, потім на техліда.
- Використовуйте різні severity-рівні: critical — для повної зупинки сервісу або втрати даних, error — для деградації, warning — не відправляти в PagerDuty взагалі, направляти в Slack або Telegram.
- Інтегруйте через REST API або через нативну підтримку в Alertmanager.
Маршрутизація за замовчуванням: транзакційні відмови з високою частотою та падіння індексатора — PagerDuty + Slack. Помірне зростання відмов — Slack. Інформаційні події — лише логування та дашборд.
Налаштування порогів та інтервалів
Пороги не можуть бути універсальними — вони залежать від вашого трафіку та архітектури. Нижче наведено підхід до їх визначення, а не фіксовані значення.
Вікно спостереження та інтервал оцінки
Розділіть два параметри: вікно спостереження (за який період рахується метрика) та інтервал оцінки ( як часто система перевіряє умову). Наприклад: вікно — 5 хвилин, інтервал — 1 хвилина. Це означає, що кожну хвилину система перевіряє, чи перевищила кількість помилок за останні 5 хвилин заданий поріг.
Для Solana-сервісів рекомендується вікно від 2 до 10 хвилин залежно від типу помилки. Транзакційні відмови оцінюйте на коротших вікнах (2–3 хвилини), відставання індексатора — на довших (5–10 хвилин), оскільки короткочасне відставання може бути нормальним під час фіналізації епохи.
Визначення порогових значень
- Зберіть базову лінію (baseline). Зафіксуйте типову частоту кожного типу помилок протягом стабільного періоду (щонайменше 24 години, краще — тиждень).
- Визначте допустиме відхилення. Зазвичай це 2–3 стандартні відхилення від середнього або фіксований множник (наприклад, 5x від базової частоти).
- Встановіть абсолютний мінімум для критичних подій. Деякі події не мають базової лінії, бо в нормі не трапляються взагалі (наприклад, OOM індексатора). Для них поріг = 1 випадок.
- Перевірте пороги на історичних інцидентах. Прогоніть конфігурацію алертів по логах попередніх інцидентів і переконайтеся, що алерт спрацював би вчасно, але не раніше, ніж це було б доречно.
Приклади логіки порогів
- Транзакційні відмови (критичний тип): більше ніж X відмов за 5 хвилин, де X обчислюється як 5x від базової лінії, але не менше 10.
- Відставання індексатора: slot lag більше ніж Y слотів протягом 3 послідовних перевірок з інтервалом 1 хвилина. Значення Y визначається вашим SLA на свіжість даних.
- Розрив gRPC-підключення: 3 невдалі спроби реконекту послідовно без успішного відновлення.
Уникнення хибних спрацьовувань
Хибні спрацьовування (false positives) — головна причина, чому інженери ігнорують алерти. Кожен хибний алерт знижує довіру до всієї системи сповіщень.
Фільтрація очікуваних помилок
Не всі InstructionError однакові. Створіть білий список помилок, які є частиною нормального потоку:
- InsufficientFunds — користувач не має достатньо SOL для комісії.
- InvalidAccountOwner — користувач передав чужий акаунт.
- Custom помилки вашої програми, що відповідають бізнес-логіці (наприклад, "альready claimed", "not eligible").
Ці помилки мають потрапляти лише в метрики та дашборди для аналізу, але не тригерити алерти.
Дедуплікація та агрегація
Одна і та сама проблема не повинна генерувати окреме сповіщення кожну хвилину.
- Групування за суттю. Наприклад, всі відмови з однаковим InstructionError::Code за 5-хвилинне вікно — одне сповіщення з лічильником.
- Cooldown-період. Після спрацьовування алерту не відправляти повторне сповіщення на ту саму подію протягом визначеного часу (наприклад, 15 хвилин), навіть якщо умова залишається істинною. Замість цього оновлювати існуюче сповіщення або виводити статус у дашборд.
Облік стану кластера
Solana-кластер періодично experiencing деградацію: під час фіналізації епохи, під час масштабних спам-атак або планових оновлень. Алерти вашого сервісу не повинні спрацьовувати на проблеми, що є загальнокластерними.
- Використовуйте зовнішній сигнал стану кластера. Наприклад, відстежуйте метрики skip rate або delinquent validators через публічні API. Якщо кластер деградований, пригнічуйте (suppress) алерти нижчого рівня або додавайте контекстне повідомлення.
- Корелюйте відмови з відповідями RPC. Якщо RPC повертає помилку перевантаження, ваша транзакційна відмова є наслідком, а не причиною.
Режим обслуговування
Під час планових релізів, міграцій або тестування алерти мають бути тимчасово вимкнені або переведені в silent-режим. Реалізуйте це через:
- Мітку (label) у системі моніторингу, яку встановлюють перед роботою та знімають після.
- Правило inhibit у Alertmanager: якщо активна мітка maintenance, алерти з severity нижче critical не відправляються.
Після завершення обслуговування обов'язково перевірте, що мітку знято. Залишена мітка maintenance — поширена помилка, через яку пропускають реальні інциденти.
Перевірка та підтримка конфігурації
Алерти — не інфраструктура "налаштував і забув". Регулярно (не рідше ніж раз на місяць) переглядайте:
- Чи актуальні пороги після зміни трафіку або архітектури.
- Чи є алерти, що не спрацьовували жодного разу за останні 90 днів — можливо, вони непотрібні або поріг завищений.
- Чи є алерти, що спрацьовують регулярно без реальних інцидентів — їх треба переглянути або видалити.
Кожен спрацьований алерт має мати постмортем або хоча б коротке пояснення причини. Якщо алерт спрацював хибно — зафіксуйте це і скоригуйте конфігурацію. Без цього циклу зворотного зв'язку система алертів деградує з часом.