Сегодня я расскажу, как с помощью системы Monq и ее инструмента low-code автоматизации можно эффективно настраивать мониторинг и управление инцидентами на примере интеграции с Zabbix. Будет описание ключевых элементов, включая создание и обработку сигналов, управление состоянием конфигурационных единиц и автоматизации процессов. А еще — полезные ссылки на бесплатную комьюнити версию и ранний доступ к облачной версии. Надеюсь, этот пост будет полезен специалистам, которые хотят оптимизировать мониторинг сложной ИТ-инфраструктуры, заодно улучшив управление инцидентами.
Начну с того, что у этой статьи есть видео-версия на YouTube. Если вам удобнее познакомиться с темой сценариев автоматизации при интеграции с Zabbix в видео-формате, велком сюда: https://youtu.be/bW-RX_vUZYg.
Что такое “сигналы” в Monq
Больше конкретики и меньше теории — поэтому этот пост о сценариях автоматизации low-code будет на примере интеграции с Zabbix. Начну с описания того, что такое «сигналы» в системе мониторинга. Сигналы — это основная сущность, которая играет важную роль в оценке состояния ИТ-окружения, расчете «здоровья» конфигурационных единиц (КЕ) и формировании отчетов SLA. Они представляют собой инциденты, полученные на основе первичных данных мониторинга. Это также метрики и события, поступающие от интеграций с внешними системами, такими как Zabbix, Prometheus, SCOM и т.д.
Упомянутые выше конфигурационные единицы (КЕ) — это элементы ИТ-инфраструктуры, включающие бизнес-сервисы, виртуальные машины или аппаратные компоненты, состояние которых необходимо контролировать (мониторить). Примером может быть информационная система, где есть операционная система, приложения и оборудование. В Monq каждая КЕ — это часть ресурсно-сервисной модели (РСМ), и она характеризуется типом, атрибутами, состоянием, владельцем, а также связями с другими КЕ и уровнем «здоровья» . Все эти элементы взаимосвязаны и помогают управлять ИТ-сервисами более эффективно.
Если кратко, то процесс работы с сигналами в Monq выглядит следующим образом
(из Zabbix мы можем получать не только алерты, но также метрики и данные о самих объектах (узлах, группах узлов), но конкретно в этом видео мы говорим именно об алертах):
Система получает первичные данные из источников мониторинга (например, алерты из Zabbix).
Алерты дедуплицируются и на их основе создаются, закрываются и обновляются инциденты внутри системы — они же сигналы.
Сигналы влияют на конфигурационные единицы, т.е. на объекты инфраструктуры или бизнес-сервисы, которые мы мониторим.
По сигналам рассчитывается здоровье КЕ (в целом здоровье КЕ зависит не только от сигналов, и это мы еще раскроем в других материалах).
Сигналы, кроме расчета здоровья КЕ, также используются для формирования различных отчетов, в т.ч. по SLA.
Таким образом, сигналы являются ключевым звеном в цепочке мониторинга и автоматизации. Именно поэтому так важно правильно настроить процесс их создания и обработки, и далее о том, как это делается.
Сценарии для расчета сигналов можно создавать вручную, используя интерфейс low-code, что значительно упрощает программирование сложной логики обработки данных без глубоких знаний программирования.
Сценарии автоматизации, как правило, создаются для обработки данных, поступающих из подключаемых источников, и поставляются вместе с интеграциями (потоками) для этих источников. Чтобы пользователям не приходилось разрабатывать такие сценарии с нуля, они включены в состав контент-паков. Автоматизация, донастраиваемая в редакторе, чаще всего используется для расширения стандартной интеграции, развернутой “из коробки”. Это позволяет упростить настройку сложных процессов, таких как мониторинг и управление ИТ-инфраструктурой.
В Monq можно как автоматически строить ресурсно-сервисные модели (РСМ), так и создавать КЕ и связи между ними в ручном режиме. Автодискаверинг и построение РСМ в системе осуществляется с помощью сценариев автоматизации, как и создание/управление сигналами. Например, это справедливо для случае аварийного события от Zabbix, когда система находит нужную конфигурационную единицу, создает или обновляет сигнал и изменяет состояние здоровья объекта.
Low-code инструментарий в Monq — это визуальный редактор, который позволяет создавать сценарии автоматизации, описывая логику преобразования данных внутри Monq без написания кода. Пример — создание сигнала на основе найденной информации в логе или алерта(ов) из Zabbix.
Пример сценария при интеграции Monq с Zabbix
В рамках нашего примера мы будем решать следующую задачу:
Необходимо создать сценарий, который будет обрабатывать события (алерты), приходящие от Zabbix, и на их основе создавать, обновлять или закрывать сигналы в Monq. При этом сигналы должны привязываться к соответствующим конфигурационным единицам и влиять на их здоровье.
Входные данные:
1. Предположим, в системе существует конфигурационная единица (КЕ), которая была создана автоматически или вручную.
2. КЕ имеет определенные параметры, в том числе:
Тип объекта (в нашем случае - хост)
Идентификатор объекта
Идентификатор потока интеграции
3. От Zabbix приходят события, содержащие информацию об алертах (аварийных ситуациях).
Требования к сценарию:
1. При получении аварийного события от Zabbix:
- Найти соответствующую КЕ в Monq,
- Создать новый сигнал или обновить существующий,
- Привязать сигнал к КЕ.
2. При получении события о нормализации (устранении аварии):
- Найти соответствующий открытый сигнал,
- Обновить информацию в нем,
- Закрыть сигнал.
Сценарий включает несколько этапов. Первое, что система делает перед тем, как выполнить всю последовательность действий, описанную в сценарии — это валидирует событие, проверяя его корректность и наличие необходимых параметров. Далее данные из события используются для фильтрации уже существующих сигналов (проводится поиск, нет ли в системе уже открытых сигналов), чтобы предотвратить дублирование или уменьшить шум. Если аварийное событие валидируется, создается новый сигнал или обновляется существующий, что позволяет избежать перегрузки инженеров техподдержки избыточными алертами.
Давайте разберем этапы создания сценария подробнее.
1. Валидация входящего события
Здесь предположим, что мы подключили Zabbix и получаем в Монк события об алертах из него. На этом этапе мы проверяем, что полученное событие соответствует нашим ожиданиям и содержит всю необходимую информацию. Это важно для предотвращения ошибок в дальнейшей обработке.
Мы проверяем следующие 2 условия:
Событие пришло по ожидаемому идентификатору потока интеграции.
Событие содержит поле "trigger" (триггер), что означает, что это событие действительно об аварии или ее устранении. На практике передаются и самые рядовые информационные события, например о добавлении хоста, что не относится к случаям аварий.
2. Извлечение необходимых данных из события
После этапа валидации из события извлекаются данные для дальнейшей обработки в сценарии. Все данные, содержащиеся в событии, могут быть задействованы в сценарии. Например, информацию о триггере, сгенерировавшем алерт, мы используем для дедупликации событий; параметр «северити» применяется для установления уровня критичности создаваемого по событию сигнала; а название узла позволяет определить, к какой конфигурационной единице будет привязан этот сигнал.
Вся информация, поступающая с событием, доступна для дальнейшей обработки, включая фильтрацию или передачу ключевых параметров из первичного события, таких как критичность. В некоторых случаях возможно использование данных события в качестве информационного, а не аварийного сигнала, например, просто названия хоста.
В Zabbix приоритет инцидентов варьируется от 1 до 5, где 5 — наивысший приоритет, в то время как в Monq критичность событий противоположна — 1 уровень означает самый высокий приоритет (Fatal). Сценарии Monq автоматически конвертируют уровни приоритета Zabbix для синхронизации с логикой системы в Monq.
3. Поиск существующих аналогичных сигналов по данному событию
Перед созданием нового сигнала мы должны проверить, нет ли уже открытых сигналов по данному триггеру. Это позволит избежать создания дубликатов.
В случае отсутствия аналогичных сигналов по триггеру ранее — создать сигнал.
Если сигнал по такому триггеру уже существует, мы просто добавим пришедшее событие к нему, и не будем создавать новый сигнал. Тем самым не будем увеличивать шум из алертов для инженеров мониторинга.
4. Создание нового сигнала или обновление существующего
В зависимости от результата поиска существующих сигналов и типа события (авария или просто информация к сведению), мы выполняем одно из следующих действий:
а) Проверяем аварийность события: если аварийное, то ищем сигнал, если нет, то отбрасываем как не интересующее.
Если сигнал не найден, то создаем сигнал и привязываем к найденной КЕ, т.е.:
- Ищем соответствующую КЕ,
- Привязываем сигнал к КЕ,Добавляем метки для поиска сигнала.
Хотя метки не обязательны, их использование позволяет легче найти нужные сигналы.
б) Если сигналы найдены и продолжают поступать ввиду того, что это длящееся аварийное событие:
Не создаем новых сигналов в системе, а все поступившие такие события привязываем к уже созданному сигналу по этому аварийному событию.
Обновляем существующий сигнал (увеличиваем счетчик событий).
5. Закрытие сигнала (при необходимости).
Если мы получили сообщение о нормализации ситуации (устранении аварии), то после привязки этого события к сигналу мы закрываем сам сигнал. Т.е. по завершении инцидента триггер закрывается, и событие о закрытии привязывается к сигналу. Таким образом, закрывается сам сигнал.
Разбор пайплайна обработки сигналов
Давайте перейдем к сценарию. Первая часть отвечает за фильтрацию и реализована при помощи функции FilterByStreamID. Мы передаем в неё модель потока и идентификатор потока. С помощью функции DynamicContains проверяем, содержит ли тело первичного события поле "trigger". На следующем этапе мы продолжаем извлекать нужные данные. Здесь используется каскадная структура: создаются локальные переменные и инициализируется значение из первичного события.
Мы всегда рекомендуем этот подход, так как он обеспечивает чистый сценарий, без сложных связей в виде “паутины” между логическими блоками автоматизации.
Кроме инициализации локальных переменных, нам необходимо привести приоритет события в Zabbix к соответствию критичности события в Monq. Это делается с помощью локальной функции ZabbixToMonqSeverity, в которой указываются входные и выходные параметры. Такая функция может быть реализована в виде простого словаря на несколько строчек.
После того как все необходимые поля собраны и переменные инициализированы, мы приступаем к третьей части нашего пайплайна — поиску и фильтрации открытых сигналов по уникальной для каждого сигнала паре меток: TriggerID и Stream ID. За фильтрацию отвечает функция FilterSignalsExpanded. В нее передаются параметры для фильтрации. Нас интересуют только открытые сигналы, поэтому одним из фильтров является статус сигнала.
Также обязательно необходимо заполнить поля создания, закрытия и длительности сигнала. Если для фильтрации они нас не интересуют, необходимо подключить заглушку ReturnNull. Это нужно для корректной работы сценария.
Ну и само собой, подключаем пин Labels, в который будут переданы наши уникальные метки. Здесь необходима небольшая конструкция, построенная от конца к началу:
Labels ожидает массив данных, поэтому подключаем к нему создание массива ArrayCreate.
Поскольку Labels имеет запрограммированную структуру, нам необходимо ее заполнить. Для этого к первому элементу массива подключаем MakeStruct.
В качестве значения здесь ожидается Dynamic (JSON). Так что используем функцию ConvertToDynamic.
ConvertToDynamic это динамичная функция, редактируемая, на вход она может принимать любые типы и структуры данных. Это нам и нужно. Двойной клик по ней открывает окно настроек, в котором нужно указать тип входящего пина. Именно сюда будут передаваться наши уникальные метки. В случае, если бы метка была одна, можно было бы ограничиться указанием ее типа и заполнить значением. Но поскольку в нашем случае фигурируют сразу 2 метки, это будет уже структура, поэтому прежде чем заполнять входящий пин в ConvertToDynamic, подготовим необходимую нам структуру:
Добавляем новую локальную структуру в левом меню, называем ее Sig_Labels_Struct и добавляем ей свойства (наши метки): streamId и triggerId.
Теперь возвращаемся к настройке ConvertToDynamic и в качестве входящего пина указываем созданную на предыдущем шаге структуру Sig_Labels_Struct.
Опять MakeStruct, подключаемый к Value ConvertToDynamic и готово, можно заполнять метки (они были положена в переменные на предыдущем этапе.
Готово, на этом поиск и фильтрация сигналов настроена.
Переходим к следующему этапу: проверке, найдены ли сигналы. За это отвечает функция ArrayAny в сочетании с бранчем (Branch). Результат фильтрации проверяется на наличие элементов.
Затем, если элементы найдены, проверяется аварийность нового события. Если оно не аварийное (например, инцидент завершен), сигнал закрывается и к нему привязывается событие о закрытии. На случай, если по одним и тем же уникальным меткам в системе образовалось несколько сигналов, закрытие реализовано с применением функции ForEach, поочередные итерации которой закроют все найденные по нашим условиям сигналы.
На этапе отладки сценария есть смысл на всех ветках сценария к завершающим функциям подключать дебаг функции SetStatus*. Они помогут отследить, на каком этапе и с какими данным сценарий остановился. Когда сценарий заработает “как задумано”, управление в дебаг-функции можно отключить.
Следующая ситуация, которую мы рассмотрим, — это когда сигналы найдены, и поступает новое аварийное событие. В случае Zabbix, это как правило подтверждающее событие и оно имеет ту же критичность, что и первое. Оно нам интересно статистически. В этом случае новый сигнал не создается. Система просто добавляет подтверждающее (confirming) событие к уже существующему сигналу и увеличивает счетчик событий, чтобы не засорять мониторинг дубликатами сигналов. Таким образом, сигнал остаётся активным и инженеры не получают лишних уведомлений.
Теперь рассмотрим сценарий, при котором сигналы не найдены (ветка False). После фильтрации, если ни один сигнал не был найден, система проверяет, является ли текущее событие аварийным. Если событие не аварийное, оно игнорируется. Если аварийное - будет создан сигнал (позже), но сначала нужно найти конфигурационную единицу, к которой этот сигнал будет привязан и здоровье которой будет снижать.
Поиск и фильтрацию КЕ можно выполнять множеством способов. Во всех фильтрациях главное - понимать основной принцип фильтрации: система по умолчанию возвращает все элементы, из которых отфильтровываются только нужные, поэтому у них обязательно должен быть какой-то отличительный признак. Для сигналов это были метки. Для КЕ это могут быть атрибуты или тоже метки.
В рассматриваемом примере все КЕ, относящиеся к Zabbix, имеют набор меток:
- streamId (id потока событий)
- objectType (host или group), и
- objectId (уникальный id хоста или группы из Zabbix)
Вот по ним и будем искать нужную КЕ. Мы, кстати говоря, на втором этапе в переменные как раз закладывали эти данные из сырого события Zabbix. Тут-то их и используем. Снова конструкция из MakeStruct→ConvertToDynamic (как и при поиске сигналов).
Заблаговременно создаем новую локальную структуру CI_Labels_Struct со свойствами objectid, objectType и streamid и задаем эту структуру в ConvertToDynamic. На этом этапе мы используем новую функцию в Monq, которая позволяет создавать локальные структуры на основе JSON-данных. Это очень удобно при работе с вложенными объектами данных, так как структура создается автоматически.
Независимо от успешности поиска КЕ, задаем переменную Exist_CI_IDS. Если КЕ нашлись — сюда запишутся их ID и при создании сигнала выполнится привязка. Если КЕ найдены не были (например их вообще не существует), переменная останется пустой, это не оказывает влияния на дальнейший процесс. Сигнал будет создан в любом случае.
На финальном этапе сценария создается новый сигнал. Мы указываем все необходимые параметры: имя, критичность, ID КЕ, владелец сигнала и самое главное — метки (помним: по ним мы потом будем искать этот сигнал, чтобы его закрыть).
Остальные параметры опциональные, но их использование поможет сделать сигнал более информативным и понятным для инженеров.
Мы разобрали базовый сценарий для работы с сигналами, который включает все рекомендации, которые мы предлагаем нашим пользователям при работе с базовой нагрузкой.
На нашем канале YouTube доступно следующее видео, где мы рассмотрим более сложные сценарии для высоконагруженных сред, в которых события могут поступать десятками в секунду. Там мы покажем, как снизить нагрузку на базу данных, минимизировать задержки при обработке данных, и как гарантировать, что аварийные события поступают в систему своевременно, без потерь сообщений и задержек.
Заключение
Движок low-code автоматизации в Monq предоставляет гибкость и возможность настраивать от простых цепочек до продвинутых пайплайнов учитывающих всевозможные условия и вариации обработки данных в сценариях автоматизации. Сценарии могут включать фильтрацию, поиск и создание сигналов, а также связь с внешними интеграциями, такими как Zabbix, через потоки данных. В системе предусмотрены готовые решения для типовых задач, но при необходимости можно создавать собственные сценарии, адаптированные под уникальные требования бизнеса.
В сценариях предусмотрена возможность использования блоков для оптимизации работы системы в условиях высокой нагрузки. Эти блоки помогают уменьшить количество обращений к базе данных, что позволяет избежать потерь сообщений и задержек в получении аварийных событий. В сценариях также используются специальные статусы, чтобы инженеры могли отслеживать успешное или неуспешное выполнение каждого этапа и быстро находить возможные ошибки.
Используя возможности сценариев и автоматизации, Monq позволяет минимизировать ручной труд, повысить эффективность мониторинга и обеспечить надежность работы ИТ-инфраструктуры.
Если вы захотите больше узнать о Monq. то приглашаем скачать комьюнити-версию продукта и попробовать построить мониторинг вашей системы для оценки качества продукта, в том числе попробовать новую облачную версию Monq OnCall.
Если возникнут вопросы по low-code автоматизации сценариев мониторинга — добро пожаловать в комьюнити чат.