Моніторинговий агент: проста штука чи ні?

Зараз існує досить багато систем для зберігання і обробки метрик (timeseries db), але ситуація з агентами (софтом, який збирає метрики) складніше. Не так давно з'явився telegraf, але все одно вибір не великий.
При цьому практично всі хмарні сервіси моніторингу розробляють свої агенти і ми не виняток. Мотивація досить проста — є багато специфічних вимог, які слабо вписуються в архітектуру існуючих рішень.
Основні наші специфічні вимоги:
  • надійність доставки метрик в хмару
  • непроста логіка плагінів: вони взаємодіють один з одним
  • діагностика: ми повинні вміти розуміти, чому агент не може зібрати ті чи інші метрики
  • агент повинен споживати якомога менше ресурсів клієнтського сервера
Під катом розповім кілька аспектів розробки агента для збору метрик.
Доставка метрик в хмару будь-якою ціною
Система моніторингу повинна працювати завжди, а особливо в разі проблем в інфраструктурі клієнта. Ми почали з того, що всі метрики в першу чергу записуються на диск сервера, на якому вони були зібрані (ми називаємо це spool). Після цього агент відразу намагається відправити пачку метрик в колектор і в разі успіху видаляє цю пачку з диска. Spool обмежений за розміром (500 мегабайт за замовчуванням), якщо він переповнюється ми починаємо видаляти самі "старі" метрики.
У цьому підході відразу ж знайшлася помилка, ми не зможемо працювати, якщо диск на сервері заповнений. Для цієї ситуації ми намагаємося відразу відправити метрики, якщо на диск записати не вдалося. Цілком логіку відправки вирішили не міняти, так як ми хочемо мінімізувати час знаходження метрик тільки в пам'яті агента.
Якщо пачку метрик надіслати не вдалося, агент повторює спробу. Проблема в тому, що пачки метрик можуть бути досить великі і однозначно вибрати таймаут досить складно. Якщо зробимо його великим, можемо отримати затримку в доставці метрик з-за одного "залип" запиту. У разі ж маленького таймауту великі пачки метрик перестануть лізти. Дробити великі пачки на дрібні ми не можемо з ряду причин.
Ми вирішили не використовувати загальний таймаут на запит до колектора. Ми задаємо таймаут на встановлення tcp з'єднання і tls handshake, а "жвавість" з'єднання перевіряє TCP keepalive. Цей механізм доступний практично на всіх сучасних OS, а там де його немає (у нас є клієнти з FreeBSD 8.x наприклад:) нам доводиться ставити великий таймаут на весь запит.
У цього механізму є 3 налаштування (всі тимчасові проміжки задаються в секундах, для сервісів, які чутливі до затримок це не дуже підійде):
  • Keepalive time — через який час після отримання останнього пакету з даними в з'єднанні починати відправляти проби
  • Keepalive probes — кількість невдалих спроб, після яких вважаємо з'єднання мертвим
  • Keepalive interval — інтервал між пробами
Значення за замовчуванням мало придатні на практиці:
$ sysctl -a |grep tcp_keepalive
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75

Ці парамерты можна перевизначити для будь-якого з'єднання, наша мета — якомога раніше визначити проблемне з'єднання та закрити його. Наприклад, такі налаштування time=1, probes=3, interval=1 дозволяють відловити проблемне з'єднання за 4 секунди.
Коли зв'язок агента з колектором зникає повністю, ми нічого зробити не можемо. Але досить часто ми зустрічали ситуацію, коли зв'язок є, але не працює DNS сервер, що використовується сервером. Ми вирішили у разі помилки DNS пробувати отрезолвить домен колектора через google public DNS.
Плагіни
Ми дуже багато уваги приділяємо автоопределению на серверах сервісів клієнтів, це дозволяє клієнтам швидше впроваджувати наш моніторинг і допомагає нічого не забути налаштувати. Для цього більшості плагінів потрібен список процесів, причому він потрібен не один раз при старті агента, а постійно, щоб підхоплювати нові сервіси. Ми отримуємо список процесів один раз за інтервал, використовуємо його для отримання метрик по процесам і відправляємо в ті плагіни, яким він потрібен для інших завдань.
Так само плагін може запускати інші плагіни або додаткові инстансы самого себе. Наприклад, у нас є плагін nginx, він раз у хвилину виходить список процесів, для кожного запущеного nginx він:
  • визначає місцезнаходження його конфига
  • читає конфіг і всі вкладені конфіги
  • знаходить всі директиви log_format і access_log
  • на основі log_format формує регулярний вираз для парсингу лода
  • для кожного access_log запускає примірник плагіна logparser, який починає парсити лог
Якщо додається/видаляється якийсь лог або змінюється формат, налаштування logparser змінюються, відсутні запускаються екземпляри, а зайві зупиняються.
Logparser може приймати на вхід не один файл, а glob. Але так як ми хочемо парсити логи паралельно, glob періодично розкривається і запускається потрібну кількість екземплярів цього ж плагіна.
Нещодавно з'явилося ще одне досить заморочене місце — сніффер трафіку, поки з ним взаємодіє тільки плагін mongodb, але плануємо розширювати:
  • плагін mongodb за списком процесів знаходить запущену монгу на сервері
  • повідомляє снифферу, що він хоче отримувати пакети по конкретному TCP порту
  • отримує пакети від сніфер, додатково парсити tcp payload і вважає різні метрики
В результаті у нас вийшли не зовсім плагіни в звичному розумінні, а просто деякі модулі, які між собою можуть взаємодіяти. Подібні сценарії було б дуже складно вбудувати в якесь готове рішення.
Діагностика агента
Підтримка перших клієнтів для нас виявилася пеклом, доводилося довго листуватися, просити клієнта запускати на сервері різні команди і надсилати нам висновок. Щоб не червоніти перед клієнтами і прискорити час пошуку проблем, ми привели в порядок лог агента і почали доставляти його до нас у хмару в режимі реального часу.
Лог допомагає швидко відловити більшість проблем, але спілкування з клієнтами повністю не замінює. Найпоширеніші проблеми пов'язані з тим, що сервіси автоматом не знаходяться. Більшість клієнтів використовують досить стандартні конфіги, формати логів ітд, у них все працює як годинник. Але як правило в компаніях, де працюють досвідчені адміністратори — можливості софта використовуються на повну і з'являються кейси, про яких ми навіть не підозрювали.
Наприклад, нещодавно ми дізналися про можливості конфігурування постгреса через ALTER SYSTEM SET, яка породжує окремий конфіг postgresql.auto.conf, переопределяющий різні значення основного конфига.
У нас створюється відчуття, що з часом наш агент перетворюється в скарбничку знань про те, як бувають влаштовані різні проекти:)
Оптимізація продуктивності
Ми постійно стежимо за споживанням ресурсів нашим агентом. У нас є кілька плагінів, які можуть істотно навантажити сервер: logparser, statsd, sniffer. Для таких випадків ми намагаємося робити різні бенчмарки, часто профілюємо код на наших стендах.
Агент ми пишемо на golang, а у нього в комплекті є профайлер, який можна включати під навантаженням. Ми вирішили цим скористатися і навчили агента періодично випльовувати в лог cpu профайл за хвилину, це дозволяє зрозуміти, як веде себе агент під клієнтської навантаженням.
Так як ми знімає споживання ресурсів абсолютно всіма процесами на сервері, клієнти можуть завжди бачити, скільки споживає наш агент. Наприклад, на одному з клієнтських фронтенд серверів агент парсити лог приблизно з 3.5 k rps:


По випадковості поруч з нашим агентом тестується nginx-amlify, який парсити той же лог:)
Разом
  • моніторинговий агент не така проста штука, як здається (у нас йде близько половини часу на розробку і підтримку агента)
  • для нас все ускладнюється тим, що всі клієнти різні і по-різному налаштовують свою інфраструктуру
  • озирнувшись назад, нам зрозуміло, що ми не змогли б реалізувати свої побажання на чомусь готовому
  • продовжуємо будувати свій велосипед:)
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.