Давайте обсудим мониторинг
Вот уже четвертый год я занимаюсь организацией того, что принято называть Observability. Набранный за это время опыт я обличаю в текст, делюсь им с вами в виде размышления-рекомендации и выношу на суд общественности. Здесь практически не будет технических деталей — статья намеренно написана таким образом, дабы изложенное можно было положить на практически любой стек технологий. Дело в том, что инструменты врываются в тренды и покидают их с невероятной скоростью, посему их выбор остается за вами. Давайте обсудим мониторинг.
О мониторинге в контексте метрик
Если спросить среднестатистического технаря-инженера, с чем у него ассоциируется мониторинг, то скорее всего вам ответят — «метрики приложения», и подразумеваться будет их сбор и некоторая визуализация. Причем, о изнанке этого процесса, как показал мой опыт, многие даже не задумываются — в понимании большинства «оно просто показывается в Grafana/Kibana/Zabbix/подставьте нужное».
Ответ этот, замечу, всё же не полный, поскольку одними лишь метриками всё не ограничивается. Точнее даже так: мониторинг — это не только о том, чтобы метрики собрать и вывести на дашборд. И вот с этого момента давайте поподробнее.
Из чего же сделан мониторинг?
Со временем, я для себя вывел следующие аспекты:
Сбор метрик из различных источников — приложения, показатели хоста, «железной» части площадки; различия в pull и push моделях пока не затрагиваем, об этом чуть позже
Запись и дальнейшее их (метрик) хранение в базе данных с учетом особенностей самой БД и использования собранных данных
Визуализация метрик, которая должна балансировать между возможностями выбранного технологического стека, удобством использования дашборд и «хотелками» тех, кому с этим всем предстоит работать
Отслеживание показаний метрик по заданным правилам и отправка алертов
В случае продвинутого мониторинга сюда можно добавить еще один пункт — выявление аномалий и проактивное информирование о деградации наблюдаемой системы на основе ML.
О сборе метрик
Итак, вы решили создать систему мониторинга. Первым шагом предлагаю задуматься о том какие метрики собирать:
Показатели хост-системы и окружающего «железа» — утилизация ресурсов CPU, RAM, нагрузка на дисковые и сетевые устройства, статистика по процессам, информация о состоянии платформы оркестровки и так далее; всех их объединяет один признак — такие метрики относятся к самому низкому доступному вам уровню инфраструктуры, с которой вы работаете.
Например, если вы предоставляете сервис для хостинга виртуальных машин, вам понадобится мониторить сервера виртуализации;, а если выкатываете свой продукт на площадку клиента, это наверняка будут виртуальные машины и/или K8s-кластерПоказатели обслуживаемых приложений — здесь появляется слой метрик, которые можно связать с процессами, в корректности и стабильности работы которых вы напрямую заинтересованы; ими могут быть гипервизор, ваш софт для клиента, некоторые системные процессы.
На этом уровне появляется возможность (а часто необходимость) устанавливать однозначную связку «инфраструктура-приложение». В самом простом виде она может выглядеть так — вы мониторите состояние процесса «запущен/не запущен», к этой метрике привязываете теги с именами хоста и приложения, по сумме которых можно будет однозначно определить, к чему именно эта метрика относитсяПоказатели бизнес-процессов — сюда относится информация, на основе которой можно делать выводы о работоспособности бизнес-функций.
В качестве примера возьмем операцию списания денег с лицевого счета пользователя — допустим, для успешного выполнения операции необходимо, чтобы был доступен личный кабинет (веб-сервер), сервис постановки задач в очередь, брокер асинхронных сообщений, платежный шлюз и база данных. Чтобы быть уверенным, что операция может быть выполнена, вам понадобится следить за состоянием всей цепочки, хотя бы в самом простом виде — работают ли все приложения в нейРезультаты смок-тестов — по сути, расширение предыдущего уровня; это показатели периодически выполняемых фейковых бизнес-операций, по которым можно будет поймать проблему
Pull VS Push
Предмет жарких споров в тематических каналах и форумах с извечным вопросом — что же лучше?
Push-модель — это когда у вас есть классическая БД, в которую активно пишут агенты. Отличается большим объёмом точек конфигурирования (как правило, по количеству агентов мониторинга), но в то же время дает возможность базе заниматься своей основной задачей — хранить метрики и управлять их жизненным циклом, пассивно ожидая, пока в неё что-нибудь положат.
Pull-модель — насколько мне известно, относительно новый подход, набравший популярность с приходом в нашу жизнь платформ для оркестровки контейнеров. В этом случае, сам сервер мониторинга ходит по пассивным экспортерам и забирает у них метрики. Плюс — единая точка конфигурирования, сам сервер, которому надо рассказать, что и откуда забирать. ИМХО, он же и главный минус — в случае отвала сети вы теряете показатели за время её простоя. Отлично показывает себя в эфемерных средах вроде K8s, когда количество сущностей, которые необходимо мониторить, изменяется с течением времени. За их пределами уже не столь удобен — для получения метрик от хостов вам понадобятся агенты-экспортеры.
Выбор модели остается за вами — исходите из ваших потребностей и задач.
О хранении
Здесь буду немногословен — на текущий момент придумано немало TSDB (Time-Series DataBase), заточенных именно под временные ряды. Вам остается только выбрать то, что по соотношению «доступный функционал — производительность — удобство и возможности языка запросов» покажется максимально приемлемым.
Мой личный фаворит — VictoriaMetrics, рекомендую ознакомиться.
О визуализации
Подобно тому, как метрики делились уровни, аналогично разделяется и визуализация:
Уровень площадки — самый высокий уровень визуализации, с которого, после получения алерта, пользователю мониторинга стоит начинать работать. Дашборд (ы) здесь представляют собой набор логически разделенных индикаторов «всё хорошо/что-то сломалось».
Например, каждая панель показывает состояние какой-либо группы приложений — Nginx`ы, Apache`и, Службы виртуализации; при наличии проблемы с любой из сущностей группы панель переходит из состояния «всё хорошо» в состояние «что-то сломалось», привлекая вниманиеУровень группы — следующий уровень, к которому переходит пользователь; должен быть доступен по drilldown-ссылке с предыдущего дашборда. Если ранее мы подсветили, с какой группой возникла проблема, здесь мы должны ответить на вопрос «с каким именно объектом группы?».
Продолжая начатый выше пример, здесь отображаются все Nginx на вашей площадке, по которым выведены ключевые показатели — состояния процессов, состояния соединений с БД, количество ошибок и так далее. Тут не стоит сильно вдаваться в детали, пяти-шести панелей на объект наблюдений будет достаточноУровень объекта — конечная точка движения нашего пользователя в большинстве случаев.
На этом уровне детально визуализируются метрики конкретного приложения/процесса/другого подвергнутого принудительному мониторингу объекта. Здесь пользователь должен найти для себя ответ на такой вопрос — «что же именно сломалось?». Начиная с этого уровня, переходы между дашбордами должны наследовать контекст — если пользователь на уровне группы кликнул по панели процесса nginx_01 хоста proxy.local, метрики именно этого приложения на этом хосте и должны отображатьсяУровень фрагмента объекта — формально, продолжение предыдущего уровня, но введен вот зачем: если какая-либо часть нашего объекта имеет слишком много метрик и достойна того, чтобы рассматриваться отдельно, под неё заводится персональный дашборд.
Например, у нашего Nginx есть апстримы со своими метриками; дабы не усложнять уровень объекта и не перегружать его, мы заводим под апстрим персональный дашборд, а на предыдущем оставляем только кликабельные индикаторы с состоянием апстрима «онлайн/частично онлайн/оффлайн». И вновь, переходы должны наследовать контекст, чтобы облегчить пользователю навигациюУровень инфраструктуры — самый низкий уровень визуализации и отправная точка в сборе метрик.
Тут отображаются показатели хост-системы и окружающего «железа». Хорошим ходом будет разбить на разные дашборды метрики разных частей — состояние CPU, RAM, дисков и т.д., организовав возможность горизонтального перехода между ними. Переход же на этот уровень можно создать с двух предыдущих, снова с учётом ранее установленного контекста; если пользователь смотрел на метрики приложения на хосте proxy.local, этого хоста метрики и должны отображаться
Подводя итог написанному выше, у нас получается такая диаграмма уровней, демонстрирующая путь пользователя:
Пользователь мониторинга двигается сверху вниз, разбирая инцидентОбщие рекомендации:
Делайте ваши дашборды шаблонными, с возможностью установки контекста через переменные. Мысль достаточно очевидная, согласен, но, тем не менее, мне приходилось встречать хардкод хостов и приложений, порождающий ворох из копий одних и тех же дашборд, что выливалось в неподдерживаемый хаос
Также, стоит выносить в переменные различные потенциально изменяемые вещи — имя базы данных с метриками, вручную составленные словари «число-значение» и т.п.
Добавляйте описание к всем панелям. Если отображаемая на панели информация кажется хоть немного неочевидной, не поленитесь дать ей описание — буквально одно-два предложения сильно облегчат работу пользователей и помогут вам же, когда возникнет необходимость вернуться к работе с дашбордом
В качестве средства визуализации сейчас лидирует небезызвестная Grafana, в которой есть функционал переменных, внутренних и внешних ссылок c шаблонизацией, комментариев к панелям и еще всякое-всякое.
О алертинге
Алертинг, пожалуй, самая значимая часть системы мониторинга. На мой взгляд, при идеальном алертинге визуализация метрик и вовсе не нужна — хорошее, годное сообщение сообщает ровно столько информации, сколько нужно для начала работ по восстановлению.
К сожалению, или к счастью, в мире нет ничего идеального, но можно попробовать к этому приблизиться. Итак, хороший алерт можно приготовить из таких ингредиентов:
Полнота сообщения — в теле алерта должна содержаться информация о том, что именно произошло и за какой период времени.
Пример: «Средняя нагрузка на CPU превышает 90% в течение последних пяти минут»; пользователь, получивший такое сообщение, видит информацию, во-первых, о событии, во-вторых, о его длительности на момент получения, что позволяет сходу примерно оценить масштабы бедствия.
Здесь стоит уточнить, что метрика обычно оценивается за некоторый период, из которого выводится максимальное/среднее/минимальное/иное другое значение, а не её мгновенный показатель — это позволяет сгладить (или же выделить — зависит от того, что именно вам нужно) всплески и временнУю задержку в доставке метрик до базы данныхУточняющие метаданные — алерт должен сопровождаться набором тегов/лейблов, раскрывающих контекст события; это могут быть имя хоста, приложения, идентификатор uri веб-сервера и т.п.
Штамп времени первого срабатывания — тут всё просто, в алерте жизненно необходима метка времени, чтобы при получении нотификации можно было понять, новый ли алерт у вас сработал, или это всё еще горит старый
Ссылка на систему управления алертами/систему визуализации метрик, на ваш выбор — она нужна для получателя, чтобы он смог сразу перейти в мониторинг, а не тратил время на судорожный поиск закладки в браузере
С самим алертом, вроде, разобрались, теперь немного о процессе нотификации:
Не допускайте спама со стороны системы управления алертами. Когда вашего получателя заваливает письмами/СМСками/сообщениями от бота, рано или поздно он перестанет предавать им хоть какое-то значение и пропустит критичную нотификацию. Хорошим тоном будет настроить рассылку таким образом, чтобы по уже «горящим» алертам повторные уведомления отправлялись спустя какое-то время
Выделите ключевые метаданные и группируйте алерты по ним; тогда вместо, например, семи сообщений по одному объекту, ваш пользователь получит одно, в которое будут вложены остальные. Это также позволяет снизить количество нотификаций (помним про предыдущий пункт)
Предусмотрите возможность для себя и/или пользователя временно отключать некоторые алерты, например, на время технических работ
Если ваша система это позволяет, настройте иерархию алертов с автоматическим подавлением нижестоящих. Если у вас из сети выпал сервер, нет необходимости дополнительно слать письма о том, что приложения на нем стали недоступны, это и так очевидно из первого
Разделите алерты по группам — инженерам пусть приходят технические алерты, а бизнесу бизнесовые. Условной коммерческой дирекции не интересно, что у вас упал Nginx (им это ни о чем не скажет), для них куда важнее знать, что цепочка выполнения бизнес-функции «покупка товара» развалилась и компания несет потенциальные убытки
Рекомендую пощупать AlertManager — приложение из стека Prometheus, в котором есть все описанные выше возможности. Лично для меня он стал той самой «серебряной пулей», решившей сразу вагон и маленькую тележку проблем. Веб-хуки и API для интеграций входят в комплект.
Вместо заключения
В первую очередь, выражаю благодарность тем, кто прочитал до конца; надеюсь, что статья показалась вам интересной и полезной.
Это первый текст из трех запланированных — дальше я бы хотел затронуть тему логирования и его синергии с мониторингом, после чего, возможно, перейти к некоторым техническим деталям (уже не только сухим текстом). Если вам было бы интересно об этом почитать, пожалуйста, напишите в комментариях. Попробуем разобрать и обсудить сначала общий подход к сбору и централизованному хранению журналов, их роль в оценке состояния наблюдаемой площадки, а также затронем вопрос — «можно ли отрывать логи от метрик?».