Найгірша система оповіщень — це людина, яка вам платить. Вона приходить запізно, неповна та емоційно забарвлена.
«Ваш сайт не працює» — це не симптом. Це звинувачення.
Працювати в продакшні без моніторингу — все одно що летіти без приладів і називати це «гнучкістю».
Ви можете протриматися довго, поки раптом не зіштовхнетеся з моментом, коли вже не зможете, і тоді відкривається істинне значення «mean time to innocence».
Що насправді означає «немає моніторингу» (і чому так трапляється)
«Немає моніторингу» рідко означає буквально нічого. Зазвичай це означає відсутність моніторингу, який допомагає під час інциденту.
Можуть бути дашборди, на які ніхто не дивиться, логи, які ніхто не вміє запитувати, та сторінка статусу, яку оновлюють криками через кімнату.
На практиці «немає моніторингу» — це один із таких режимів відмов:
- Немає зовнішнього сигналу: ніхто не перевіряє сервіс зовні, тому внутрішній успіх вводить в оману.
- Немає маршрутизації оповіщень: метрики є, але ніхто не отримує пейджі, або алерти йдуть у поштову скриньку, яка померла у 2019.
- Немає «золотих сигналів»: збираєте CPU і RAM, але не збираєте latency, error rate, saturation або traffic.
- Немає кореляції: є метрики, логи і трейси, але вони не мають спільних ідентифікаторів, синхронного часу або потрібного збереження.
- Немає власника: «команда платформи» — це лист електронної пошти, а не команда; SRE — це «той, хто більше за всіх знає».
- Немає бюджетів: найпевніший моніторинг — «ми додамо потім», і це одночасно найдоріжчий варіант.
Причина цього рідко в незнанні. Це інтереси й стимули. Випуск фічі помітний. Запобігання аваріям — непомітне.
Поки одного дня це не стане надзвичайно помітним.
Ось сувора правда: якщо ви не можете відповісти на питання «чи працює?» за менше ніж 60 секунд, у вас немає моніторингу.
У вас є відчуття.
Факти та історія, що пояснюють сучасний хаос
Observability не з’явився тому, що інженери люблять графіки. Він з’явився тому, що продакшн постійно підпалював себе, і люди втомилися.
Кілька конкретних контекстних пунктів, які мають значення:
- SNMP (кінець 1980-х) зробив можливим опитування мережевого обладнання у масштабі, але також нормалізував думку «опитування = моніторинг», навіть коли проблема в додатках.
- Епоха Nagios (2000-ті) популяризувала перевірки «чи вгору?» і патерни пейджингу при падінні; чудово для хостів, посередньо — для розподілених систем.
- Книга Google SRE (середина 2010-х) вивела SLO і error budget у мейнстрим операцій, змістивши сприйняття надійності як продуктову властивість, а не хобі.
- Мікросервіси (2010-ті) примножили режими відмов: один запит користувача тепер зачіпає 10–100 компонентів, і «логи на боксі» стали археологією.
- Бази часових рядів та дешеве сховище зробили можливим зберігання високороздільних метрик, але також породили анти-патерн «збираємо все і нічого не розуміємо».
- Оркестрація контейнерів перетворила «сервер упав» на «под пересаджений», що добре, поки пересадка не ховає crash loop тижнями.
- Великі хмарні відмови навчали компанії, що «хмара — це чийсь інший комп’ютер» також означає «чиясь інша зона відмов». Інструментація все ще потрібна.
- Сучасна культура інцидентів рухається від пошуку винних до системного мислення — принаймні в компаніях, що хочуть зберегти інженерів довше, ніж одну ротацію on-call.
Одну перефразовану ідею, бо вона залишається правдивою через десятиліття: «Сподівання — не стратегія.»
— парафраз ідеї, яку приписують ген. Gordon R. Sullivan, яка часто повторюється в операційній культурі інженерії.
Технічна реальність «клієнт — ваш пейджер»
Коли клієнт каже, що ви впали, вже істинними є три речі:
- Ви втратили час: інцидент почався раніше, ніж повідомлення. Ваш таймер MTTR вже тікає.
- Ви втратили точність: симптоми клієнта фільтруються через браузери, мережі та людське тлумачення.
- Ви втратили довіру: вони виявили вашу несправність раніше за вас, і це не найкращий момент для бренду.
Операційна проблема не лише в виявленні. Вона в тріажі.
Моніторинг — це не просто «графіки». Це здатність швидко відповісти на послідовність питань про продакшн:
- Сервіс впав зовсім чи тільки сповільнився?
- Проблема глобальна чи регіональна, у одного орендаря чи у всіх?
- Чи почалося це після деплою, зміни конфігурації чи спайку навантаження?
- Чи вузьке місце — CPU, пам’ять, диск, мережа, затримка залежності чи блокування?
- Чи це поступове деградування (витік) або раптова подія (креш)?
- Чи ми не погіршуємо ситуацію ретраями, автоскейлінгом або петлями фейловера?
Без моніторингу ви робите «форензіку продакшну» під тиском: SSH на хости, tail логів, здогадки, рестарти, надія.
Це іноді працює, переважно коли проблему тривіально вирішує перезапуск. Це не масштабується і часто породжує другий інцидент.
Жарт №1: Працювати без моніторингу — це як їхати вночі з вимкненими фарами, бо «дорога на парковці виглядає нормально».
Чому «ми помітимо швидко» майже завжди неправильно
Команди вважають, що користувачі швидко повідомлять про відмови. Іноді так. Іноді ні.
Найтихіші збої часто найшкідливіші:
- Часткові відмови: один API-ендпоінт падає, один регіон недоступний або один сегмент клієнтів постраждав.
- Повільні відмови: latency поступово зростає, поки клієнти не йдуть, а не скаржаться.
- Помилки коректності даних: відповіді швидкі, але неправильні. Скарг немає; є аудити.
- Збої фонових завдань: білінг, пошта, експорти, ETL. Ніхто не дивиться, поки не настане кінець місяця.
Моніторинг — це не лише про аптайм. Це про коректність, продуктивність і ємність.
Це про те, щоб знати, що система робить правильну справу, з потрібною швидкістю, для потрібних людей.
Плейбук швидкої діагностики: перші/другі/треті перевірки
Це плейбук «клієнт каже, що ми впали». Мета — не бути хитрим; мета — бути швидким, повторюваним і важким для припущення помилки.
Ви шукаєте вузьке місце і радіус ураження.
Перше: підтвердіть симптом зовні
- Перевірте публічний ендпоінт з двох мереж (ваша корпоративна мережа і мобільний хотспот), щоб виключити локальні DNS/VPN проблеми.
- Збережіть HTTP-статус, latency і request ID, якщо доступно.
- Вирішіть: це повне падіння (connection refused/timeouts) чи часткове (500-ки/повільно)?
Друге: визначте радіус ураження
- Це один регіон/зона? Один клієнт/тенант? Один ендпоінт?
- Перевірте компоненти на краю: DNS, load balancer, ingress, CDN, термін дії сертифіката.
- Вирішіть: це проблема маршрутизації трафіку чи проблема ємності додатку?
Третє: ізолюйте категорію вузького місця
- Обчислення: CPU завантажено, load високий, run queue велика.
- Пам’ять: OOM kills, swap storms, збільшення RSS.
- Диск: заповнені файлові системи, високий iowait, стрибки латентності, деградація RAID/ZFS пулу.
- Мережа: втрата пакетів, виснаження conntrack, неправильна маршрутизація, зависання TLS handshake.
- Залежності: DB насичена, кеш недоступний, upstream API повільний, затримки DNS.
Четверте: зупиніть кровотечу безпечно
- Відкотіть останній деплой/конфіг, якщо він збігається з початком проблеми.
- Зменьшіть навантаження або обмежте його (повернути 429/503) замість того, щоб «плавитися».
- Масштабуйте лише якщо впевнені, що не підсилюєте проблему залежності.
- Вирішіть: пом’якшуємо зараз, діагностуємо після стабілізації.
П’яте: збережіть докази
- Зробіть снапшоти логів, зафіксуйте стан процесів, запишіть часові мітки.
- Переконайтеся, що системні годинники в порядку; зсув часу руйнує кореляцію.
- Вирішіть: що нам потрібно для постмортему, перед тим як «рестарт все пофіксує».
Практичні завдання: команди, вивід і рішення
Нижче — конкретні завдання, які можна виконати під час інциденту. Кожне має: команду, типовий вивід, що це означає і яке рішення прийняти.
Обирайте ті, що підходять для вашого стеку; не прикидвайтеся Linux-майстром, якщо ви на керованих сервісах. Але вивчіть форму сигналів.
Завдання 1: Підтвердіть, що DNS повертає те, що ви очікуєте
cr0x@server:~$ dig +short api.example.com
203.0.113.10
Що це означає: Ви отримали A-запис. Якщо він порожній, повертає несподіваний IP або змінюється між запитами, у вас можуть бути проблеми з propagation або split-horizon.
Рішення: Якщо DNS неправильний, припиніть тикати додаток. Виправте маршрутизацію (запис, TTL, зону, health checks) або обійдіть її відомим робочим IP для налагодження.
Завдання 2: Перевірте TLS та handshake зовні
cr0x@server:~$ echo | openssl s_client -servername api.example.com -connect api.example.com:443 2>/dev/null | openssl x509 -noout -dates
notBefore=Jan 10 00:00:00 2026 GMT
notAfter=Apr 10 23:59:59 2026 GMT
Що це означає: Якщо це не підключається або показує прострочений сертифікат, ваша «аварія» може бути пов’язана з невдалою ротацією сертифікатів.
Рішення: Якщо сертифікат прострочений або ланцюжок зламаний, пріоритезуйте виправлення сертифікатів над налагодженням аплікації; масштабування не виправить криптографію.
Завдання 3: Виміряйте поведінку ендпоінта (статус + latency)
cr0x@server:~$ curl -sS -o /dev/null -w "code=%{http_code} total=%{time_total} connect=%{time_connect} ttfb=%{time_starttransfer}\n" https://api.example.com/health
code=503 total=2.413 connect=0.012 ttfb=2.390
Що це означає: Швидке встановлення з’єднання, повільний TTFB означає, що сервер прийняв з’єднання, але не зміг швидко відповісти — проблема в аплікації або в залежності, а не в чистій мережі.
Рішення: Розглядайте як «м’яке падіння» і зосередьтеся на насиченні або таймаутах залежностей, а не на DNS або фаєрволі.
Завдання 4: Визначте, чи перевантажений хост (CPU/run queue)
cr0x@server:~$ uptime
14:02:11 up 36 days, 3:18, 2 users, load average: 38.12, 35.77, 29.05
Що це означає: Load average значно вище кількості CPU вказує на багато runnable або заблокованих задач. «Заблоковані» часто означає I/O wait, а не CPU.
Рішення: Негайно перевірте iowait і використання ресурсів по процесах; не додавайте CPU в надії, що це вирішить проблему.
Завдання 5: Подивіться CPU, iowait і насичення швидко
cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.5.0 (app-01) 02/02/2026 _x86_64_ (16 CPU)
02:02:15 PM all %usr %sys %iowait %idle
02:02:16 PM all 12.3 6.1 62.4 19.2
02:02:17 PM all 10.9 5.7 64.0 19.4
02:02:18 PM all 11.1 5.9 63.2 19.8
Що це означає: Високий %iowait означає, що CPU простає, але чекає диск. Проблема — латентність сховища або насичення диску.
Рішення: Не масштабуйте кількість інстансів як перший крок; знайдіть, що б’є по диску (логи, DB, swap, компакти) і пом’якшіть.
Завдання 6: Знайдіть найбільших споживачів CPU і пам’яті
cr0x@server:~$ ps -eo pid,comm,%cpu,%mem,rss --sort=-%cpu | head
PID COMMAND %CPU %MEM RSS
7321 java 380 12.4 2068420
914 nginx 45 0.6 98120
5210 node 33 2.1 349812
Що це означає: Один Java-процес, що сильно використовує кілька ядер, вказує на обчислювально інтенсивну роботу або runaway-цикл.
Рішення: Якщо CPU-завантаження корелює з трафіком, розгляньте load shedding, зменшення конкуренції або відкат. Якщо несподівано — зробіть стек-трейси перед рестартом.
Завдання 7: Перевірте OOM kills (мовчазна смерть сервісу)
cr0x@server:~$ dmesg -T | tail -n 8
[Mon Feb 2 13:58:41 2026] Out of memory: Killed process 5210 (node) total-vm:4123456kB, anon-rss:1765432kB, file-rss:0kB, shmem-rss:0kB
[Mon Feb 2 13:58:41 2026] oom_reaper: reaped process 5210 (node), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
Що це означає: Ядро вбило процес. Ваш сервіс може «рандомно» перезапускатися, флапати або зникати.
Рішення: Пом’якшіть, зменшивши використання пам’яті, налаштувавши ліміти, додавши RAM або виправивши витік. Також додайте алерти на OOM-події; вони не витончені, але їх ігнорували.
Завдання 8: Перевірте місце на диску (класична нудна відмова)
cr0x@server:~$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/nvme0n1p2 200G 200G 0 100% /
Що це означає: Диск повний. Очікуйте дивних побічних ефектів: невдалі записи, завислі процеси, ризик корупції БД, збої логування, проблеми менеджера пакетів.
Рішення: Вивільніть місце безпечно: видаліть старі логи, зробіть ротацію, перемістіть артефакти, розширте диск. Потім виправте корінну причину (політика збереження, runaway-логи, надвеликі core dumps).
Завдання 9: Знайдіть, що зараз їсть диск
cr0x@server:~$ sudo du -xhd1 /var | sort -h
120M /var/cache
2.1G /var/lib
38G /var/log
Що це означає: /var/log займає багато місця. Часто це «ми увімкнули debug-логування» інцидент.
Рішення: Зробіть ротацію/транканцію найбільших файлів, потім встановіть розумні рівні логування і ротацію. Якщо потрібні debug-логи, відправляйте їх за межі машини з політикою збереження.
Завдання 10: Перевірте латентність диска і насичення (там ховаються відмови)
cr0x@server:~$ iostat -xz 1 3
Linux 6.5.0 (app-01) 02/02/2026 _x86_64_ (16 CPU)
avg-cpu: %user %system %iowait %idle
11.2 5.8 63.7 19.3
Device r/s w/s rkB/s wkB/s await svctm %util
nvme0n1 12.0 850.0 512.0 98432.0 48.3 1.2 99.8
Що це означає: %util близько 100% і високий await означають, що пристрій насичений; записи ставляться в чергу і все сповільнюється.
Рішення: Визначте процес, що пише (checkpoint бази даних, потік логів, job резервного копіювання). Тротлінгуйте його, перемістіть або масштабуйтесь по сховищу. Не прикидайтеся, що це «тільки CPU».
Завдання 11: Перевірте статус сервісу під systemd
cr0x@server:~$ systemctl status nginx --no-pager
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
Active: active (running) since Mon 2026-02-02 13:40:07 UTC; 21min ago
Що це означає: Процес запущений. Це не означає, що сервіс працює правильно; він може бути заблокований або повертати помилки.
Рішення: Якщо «active», але користувачі падають, перевірте upstream health, кількість підключень і логи. Не зупиняйтесь на цьому і не оголошуйте перемогу.
Завдання 12: Перевірте останні логи на очевидні помилки
cr0x@server:~$ journalctl -u nginx -S "-15 min" --no-pager | tail -n 8
Feb 02 13:55:10 app-01 nginx[914]: connect() failed (111: Connection refused) while connecting to upstream, client: 198.51.100.33, server: api.example.com, request: "GET /v1/orders HTTP/2.0", upstream: "http://127.0.0.1:8080/v1/orders"
Що це означає: Nginx не може дістатися до upstream-додатку на 127.0.0.1:8080. Ймовірно, це краш аплікації, помилка прив’язки або локальний фаєрвол.
Рішення: Дослідіть upstream-сервіс: чи слухає порт, чи є crash loop, OOM або проблема конфігурації. Nginx тут лише месенджер.
Завдання 13: Підтвердіть, що порт слухає (і ким)
cr0x@server:~$ ss -lntp | grep ':8080'
LISTEN 0 4096 127.0.0.1:8080 0.0.0.0:* users:(("java",pid=7321,fd=123))
Що це означає: Порт відкритий і належить Java-процесу. Якщо ніхто не слухає — upstream-помилка пояснена.
Рішення: Якщо порт не слухає — перевірте логи крашу і конфіг. Якщо слухає — підозрюйте, що аплікація в завислому стані або чекає залежності; пробуйте локальні запити.
Завдання 14: Локальний health check в обхід load balancer
cr0x@server:~$ curl -sS -o /dev/null -w "code=%{http_code} total=%{time_total}\n" http://127.0.0.1:8080/health
code=500 total=0.083
Що це означає: Аплікація швидко відповідає, але повертає 500: внутрішня помилка, невірна конфігурація, зламана залежність або incomplete startup.
Рішення: Шукайте стек-трейси і відмови залежностей; не витрачайте час на мережеве налагодження.
Завдання 15: Перевірте підключення до БД швидко (приклад PostgreSQL)
cr0x@server:~$ psql -h db-01 -U app -d appdb -c "select now(), count(*) from pg_stat_activity;"
now | count
-------------------------------+-------
2026-02-02 14:02:44.221+00 | 198
Що це означає: БД доступна і має 198 активних з’єднань. Якщо це близько до ліміту з’єднань — ви на межі самоствореної аварії.
Рішення: Якщо з’єднань багато, увімкніть pooling, зменшіть конкуренцію або вбийте runaway-запити. Якщо недоступна — вважайте БД первинним інцидентом.
Завдання 16: Виявіть contention на блокуваннях (приклад PostgreSQL)
cr0x@server:~$ psql -h db-01 -U app -d appdb -c "select wait_event_type, wait_event, count(*) from pg_stat_activity where state='active' group by 1,2 order by 3 desc;"
wait_event_type | wait_event | count
-----------------+---------------------+-------
Lock | transactionid | 62
Client | ClientRead | 21
Що це означає: Багато сесій чекають на блокування — база заблокована, а не «повільна». Ваш додаток шикується в чергу через contention.
Рішення: Знайдіть блокуючий запит і вирішіть його (термінувати сесію, відкотити деплой, змінити індекси/транзакції). Масштабування аплікаційних серверів лише збільшить тиск.
Завдання 17: Перевірте помилки мережі на рівні ядра
cr0x@server:~$ netstat -s | egrep -i 'listen|overflow|dropped' | head
124 times the listen queue of a socket overflowed
124 SYNs to LISTEN sockets dropped
Що це означає: Сервер відкидає вхідні з’єднання. Клієнти бачать це як «рандомні таймаути».
Рішення: Збільшіть backlog, налаштуйте accept-черги, зменште роботу на запит або масштабуйте горизонтально. Також переконайтеся, що аплікація в змозі обслуговувати навантаження.
Завдання 18: Перевірка цілісності сховища (приклад ZFS)
cr0x@server:~$ sudo zpool status
pool: tank
state: DEGRADED
status: One or more devices has experienced an unrecoverable error.
scan: scrub repaired 0B in 01:12:33 with 0 errors on Mon Feb 2 01:10:02 2026
config:
NAME STATE READ WRITE CKSUM
tank DEGRADED 0 0 0
mirror-0 DEGRADED 0 0 0
sda ONLINE 0 0 0
sdb FAULTED 9 12 0 too many errors
errors: No known data errors
Що це означає: Ваш пул деградований. Може падати продуктивність, може йти resilver, і ще одна відмова диска може спричинити втрату даних.
Рішення: Замініть пошкоджений диск, сплануйте вплив resilver, і подумайте про обмеження інтенсивних робіт. І додавайте моніторинг стану пулу вчора.
Завдання 19: Перевірте, чи йде свопінг (мовчазний вбивця латентності)
cr0x@server:~$ free -m
total used free shared buff/cache available
Mem: 64000 61200 300 210 2500 900
Swap: 16000 15850 150
Що це означає: Swap майже заповнений; система ймовірно треше. Латентність стає випадковою, iowait зростає, і все виглядає привидно.
Рішення: Негайно зменшіть тиск на пам’ять (рестартуйте витікальні воркери, додайте RAM, налаштуйте кеши). Довгостроково — встановіть ліміти, підійміть розміри і алерти на використання swap.
Жарт №2: Якщо вашим єдиним алертом є лист від клієнта, вітаю — ви побудували розподілену систему моніторингу на людській тривозі.
Три міні-історії з корпоративного життя (анонімізовані і правдоподібні)
Міні-історія 1: Інцидент через неправильне припущення
Середнього розміру SaaS-компанія мала один сервіс «API» за load balancer. У них були хост-метрики: CPU, пам’ять і диск.
У них не було синтетичних перевірок і алертів по rate помилок. Ротація on-call складалася з двох розробників і одного інфра-спеціаліста, який також відповідав за бекапи.
Одного понеділка клієнт повідомив, що завантаження файлів не працює. Команда припустила «проблему зі сховищем», бо в головах uploads і storage були пов’язані.
Вони SSH-нули на ап-хости, перевірили використання диску (нормально), перевірили сторінку статусу об’єктного сховища (green) і перезапустили upload workers, щоб «очистити» ситуацію.
Це зробило все гірше, бо рестарти обірвали in-flight завантаження і викликали ретраї клієнтів.
Насправді проблема була в зсуві часу на одному вузлі після міграції гіпервізора. TLS-handshake іноді падав, бо вузол вірив, що він у майбутньому.
Load balancer продовжував відправляти частину трафіку на цей вузол. CPU, пам’ять, диск виглядали нормально. Сервіс був «вгору».
З боку браузера клієнта це виглядало як рулетка.
Фікс був простий: відновити NTP, злитийити вузол, потім знову ввести його у пул. Урок не лише «NTP важливий» (це так).
Урок у тому, що ментальна модель команди була занадто вузькою: вони вважали, що кожна відмова проявиться як насичення ресурсів.
Без метрик успіху на рівні запитів і зовнішніх перевірок вони були сліпі щодо помилок коректності.
Після цього вони додали дві речі: синтетичну перевірку завантаження щохвилини і алерт по помилках TLS handshake на краю.
Не сотню дашбордів. Два сигнали, які відповідали болю користувача.
Міні-історія 2: Оптимізація, яка зіграла злий жарт
Інша компанія через тиск витрат вирішила «оптимізувати» логування. Вони перейшли від відправки аплікаційних логів за межі до локальних логів з батч-шейпером.
Ідея була приваблива: менше мережевих викликів, нижчі витрати на інгест і «ми можемо відправляти оптом».
Під час піку трафіку батч-шейпер не встигав. Логи накопичувалися локально. Диск заповнювався повільно, а потім раптово.
Коли диск досяг 100%, база почала провалювати checkpoints і аплікація почала кидати помилки, які вона не могла записати у власні логи.
Команда не бачила помилок, бо помилки були заховані за самою проблемою диска, що їх спричиняла.
Клієнти скаржилися на таймаути. Команда масштабувала API-тайр, що збільшило трафік записів і обсяг логів, що ще швидше заповнило диски.
Класична позитивна петля: «масштабуй, щоб виправити» стала «масштабуй, щоб прискорити».
Постмортем був жорстким: локальний буферинг без жорстких квот — це denial-of-service, який ви собі запланували.
Правильна оптимізація включала б резервування диска, обмеження швидкості логів і backpressure (кидати debug-повідомлення першими, а не базу).
Вони врешті впровадили ліміти обсягу логів на сервіс і зберегли мінімальний потік помилок у реальному часі.
Міні-історія 3: Нудна, але правильна практика, що врятувала день
Команда внутрішньої платформи велику корпорацію обслуговувала сервіс, суміжний з платежами. Вони не були гламурними. Вони часто говорили «ні».
Їхній моніторинг теж був нудним: синтетичні перевірки, алерти по rate помилок, перцентилі latency і таймаути залежностей. У них були runbook-и.
У четверній деплой ввів тонкий витік підключень до downstream БД. Підключення накопичувалися повільно.
Оскільки у них був дашборд пулу підключень і алерт на «насичення пулу», on-call отримав пейдж до того, як клієнти щось помітили.
Алерт не казав «щось дивне». Він казав «DB pool на 90% і зростає».
Реакція була так само нудною: вони відкотили негайно, потім перевірили, що пул опустів, і знову задеплоїли з фіксом за feature flag.
Вони також запровадили rate-limit для найбільш постраждалого ендпоінта, щоб зменшити тиск під час валідації.
Клієнти так і не написали тікет. Бізнес не організував war room. Команді не дали похвали, що є найвищою похвалою у reliability engineering.
Їхня практика не була геніальною; вона була дисциплінованою: алерти, що відповідають впливу на користувача, і повноваження для відкату без комітету.
Поширені помилки: симптом → причина → виправлення
Коли у вас немає моніторингу, ви потрапляєте в передбачувані пастки. Ось найпоширеніші, з формулюванням, що дозволяє діяти під час інциденту.
1) «Сервіс запущений», але користувачі отримують помилки
- Симптом:
systemctl statusкаже active; клієнти бачать 500/503. - Причина: Відмова залежності, виснаження thread pool або аплікація повертає помилки, поки процес живий.
- Виправлення: Додайте health checks, що валідуюють залежності; алерт на rate помилок і latency, а не на існування процесу.
2) Випадкові таймаути, що «зникають» після рестарту
- Симптом: Таймаути під навантаженням; рестарт допомагає коротко.
- Причина: Витік ресурсів (підключення, дескриптори файлів, пам’ять) або обмеження ядра (listen backlog, conntrack).
- Виправлення: Алертуйте на використання FD, кількість підключень і падіння в мережі; встановіть ліміти і додайте pooling.
3) Скаржиться лише один клієнт
- Симптом: «У нас впало, у інших — ні.»
- Причина: Проблема з даними конкретного тенанта, гео-маршрутизацією, дисбаланс шардів або відмінності в політиці аутентифікації.
- Виправлення: Додайте per-tenant/per-region метрики успіху і трасування; впровадьте канарейні синтетичні перевірки з кількох регіонів.
4) Все повільно, CPU низький
- Симптом: Низький CPU, висока latency.
- Причина: iowait диска, contention на блокуваннях або затримки upstream-залежностей.
- Виправлення: Відстежуйте iowait і disk await; алерт на latency залежностей; додайте моніторинг блокувань бази даних.
5) Масштабування робить гірше
- Симптом: Додаєте інстанси, rate помилок зростає.
- Причина: Thundering herd / retry storm або насичення спільної залежності (DB, кеш, файловий система).
- Виправлення: Реалізуйте експоненціальний бекоф з jitter, circuit breakers і per-endpoint rate limits; алерт на насичення залежностей.
6) Аварія «починається», коли клієнти її помічають
- Симптом: Немає внутрішньої часової мітки; невизначений час початку інциденту.
- Причина: Відсутність зовнішнього синтетичного моніторингу, відсутність timeline подій (deploy markers), мала ретенція логів.
- Виправлення: Додайте синтетичні перевірки і анотації деплойів; зберігайте логи/метрики достатньо довго, щоб бачити тренди (не лише останні 15 хвилин).
7) Health checks проходять, а реальний трафік падає
- Симптом: /health повертає 200; /checkout падає.
- Причина: Мілкі health checks, які не перевіряють реальні залежності або шляхи.
- Виправлення: Додайте шаровані перевірки: liveness (процес), readiness (залежності) і синтетичні транзакції (реальний шлях користувача).
Чеклісти / покроковий план
Покроково: від «нічого» до «клієнти — не ваш пейджер»
- Визначте, що означає «падає» для ваших користувачів. Оберіть одну-дві користувацькі траєкторії (логін, оформлення замовлення, API-запит) і вимірюйте їх.
- Додайте зовнішні синтетичні перевірки. Запускайте їх щонайменше з двох мереж/регіонів. Алертуйте на падіння і регрес по latency.
- Прийміть «золоті сигнали» для кожного сервісу. Traffic, errors, latency, saturation. Якщо ви не можете їх назвати — ви не зможете по них алертити.
- Інструментуйте request ID. Кожен запит має correlation ID на краю, а логи містять його наскрізь.
- Створіть мінімальну сторінку on-call. Одна сторінка, не десять: поточний статус, останній деплой, rate помилок, p95 latency, стан залежностей.
- Алертуйте на симптоми, а не на причини. «Сплеск 500-ок» — це симптом. «CPU 70%» — це дрібниця.
- Встановіть відповідальність. Кожен алерт має команду і runbook. Якщо за це ніхто не відповідає, він розсилає пейджі всім і нічого не вирішує.
- Визначте ретенцію і квоти. Логи заповнюють диски. Метрики витрачають бюджети. Вирішіть, яка ретенція вам потрібна для налагодження трендів і регресій.
- Синхронізація часу і годинники. NTP/chrony повсюди. Якщо час неправильний — спостережуваність — вигадка.
- Практикуйте відкат. Зробіть відкат рутинною дією, а не сакральним ритуалом, що потребує схвалень, поки продакшн горить.
- Пишіть постмортеми, що змінюють системи. Якщо action item — «бути обережнішими», ви написали щоденник, а не інженерний артефакт.
- Переглядайте алерти щомісяця. Вбивайте шумні алерти. Додавайте відсутні. Моніторинг — живий процес, а не одноразовий проєкт.
Чекліст інциденту: коли клієнт повідомляє про відмову
- Підтвердіть зовні (код статусу, latency, текст помилки).
- Зафіксуйте час, регіон клієнта, ендпоінт, request ID якщо можливо.
- Перевірте останній деплой/зміну конфігурації.
- Перевірте край: DNS, TLS, стан load balancer, термін дії сертифіката.
- Перевірте аплікацію: error-логи, підключення до залежностей, насичення (CPU/mem/disk/network).
- Мітити: відкат, зниження навантаження, відключення неважливих фіч.
- Збережіть докази: логи, снапшоти систем, top-вивід, інформацію про блокування БД.
- Комунікація: один власник, один канал, чітке повідомлення для клієнтів.
Чекліст «збудувати правильно»: мінімальний життєздатний моніторинг (MVM)
- Зовнішні синтетики: один «реальний» ендпоінт, один «health» ендпоінт.
- Метрики сервісу: rate запитів, rate помилок, p95 latency, saturation (глибина черги, thread pool, підключення до БД).
- Метрики залежностей: latency БД, hit rate кешу, таймаути upstream.
- Хост-метрики: використання диску, iowait, тиск пам’яті, падіння пакетів.
- Події: маркери деплою, зміни конфігурацій, події масштабування.
- Гігієна алертів: пейджити лише при впливі на користувача; все інше — тікет або дашборд.
Питання та відповіді
1) Чи нормально «без моніторингу», якщо додаток малий?
Маленькі додатки виходять з ладу маленькими способами, а потім ростуть. Моніторинг — не про розмір; він про час діагностики.
Навіть одна VM виграє від алертів на повний диск і базової синтетичної перевірки.
2) Який перший сигнал моніторингу варто додати?
Зовнішня синтетична перевірка найважливішої користувацької траєкторії з вимірюванням latency і статус-коду.
Якщо вона падає — ви пейджите. Якщо повільнішає — ви розбираєтеся до того, як вона впаде.
3) Чому графіки CPU і пам’яті видаються марними під час відмов?
Бо багато відмов пов’язані з залежностями і насиченням в інших місцях: латентність диска, contention на блокуваннях або мережеві збої.
Графіки хоста потрібні, але недостатні; вони — життєві показники, а не діагностика.
4) Як уникнути втоми від алертів?
Пейджте тільки за симптомами, що впливають на користувача, і за діями, які можна виконати. Все інше — тікет або дашборд.
Якщо алерт не веде до рішення — це шум у формі відповідальності.
5) Чи потрібне розподілене трасування, щоб бути «реальним» SRE?
Ні. Потрібна ясність. Трейсинг допомагає в мікросервісах, але ви можете багато чого зробити з request ID, алертами на rate помилок і метриками latency залежностей.
Додавайте трасування, коли кореляція стає вузьким місцем.
6) Який мінімальний набір дашбордів, що реально допомагає?
Один дашборд на критичний сервіс: traffic, errors, p95/p99 latency, saturation і топ-залежності.
Плюс один «edge» дашборд: DNS/TLS/LB-стан і синтетичні перевірки.
7) Як обробляти «часткові відмови», коли лише деякі користувачі скаржаться?
Сегментуйте сигнали: по регіонах, по тенантах, по ендпоінтах і по версії збірки.
Часткові відмови трапляються, коли ваші агреговані метрики приховують істину.
8) Чи повинні health checks опитувати базу даних?
Readiness checks повинні перевіряти критичні залежності, включно з базою, але обережно: вони мають бути легкими і обмеженими за частотою.
Використовуйте простий запит або перевірку з’єднання, а не повну транзакцію.
9) Що робити, якщо ми не можемо встановлювати агенти через політику безпеки?
Ви все ще можете робити багато речей за допомогою black-box моніторингу (синтетики), метрик на рівні додатка і централізованої відправки логів через затверджені колектори.
Політика безпеки має змінювати архітектуру, а не ліквідувати видимість.
10) Як переконати керівництво профінансувати моніторинг?
Не продавайте «observability». Продавайте зменшення витрат на відмови і швидше розв’язання інцидентів.
Покажіть недавній таймлайн інциденту і підкресліть, скільки часу втрачено на здогадки. Зробіть марні витрати видимими.
Висновок: наступні кроки, які можна зробити цього тижня
Якщо ви дізналися про збій від клієнта, ставтеся до цього як до дефекту продакшну, а не як до поганого дня.
Виправлення — це не гарніший дашборд. Це побудова системи, яка швидко і стабільно говорить вам правду.
Виконайте ці кроки в порядку:
- Додайте одну зовнішню синтетичну перевірку, яка вимірює статус-код і latency для реального ендпоінта.
- Створіть один пейджинг-алерт на rate помилок (не на CPU) і направте його на реальний on-call розклад.
- Інструментуйте request ID і переконайтеся, що логи їх містять наскрізь.
- Алертуйте на повний диск, OOM kills і таймаути залежностей — бо це «мовчазні вбивці», які першими знаходять клієнти.
- Напишіть короткий runbook для трьох найпоширеніших випадків, що ви бачили (заповнення диска, насичення БД, crash loops).
Потім робіть нудну роботу: підтримуйте це. Моніторинг, який не доглядають, стає декоративним.
А декоративний моніторинг — це просто дороге повторення того, як ви дізналися про збій від клієнта — знову.