На чем написан zabbix
Система мониторинга Zabbix для начинающих
Содержание:
Zabbix — это универсальный инструмент мониторинга, способный отслеживать динамику работы серверов и сетевого оборудования, быстро реагировать на внештатные ситуации и предупреждать возможные проблемы с нагрузкой. Система мониторинга Zabbix может собирать статистику в указанной рабочей среде и действовать в определенных случаях заданным образом.
В этой обзорной статье расскажем об основных принципах и ключевых инструментах, на которых построена универсальная система мониторинга Zabbix.
Обзор
Систему создал Алексей Владышев на языке Perl. Впоследствии проект подвергся серьезным изменением, которые затронули и архитектуру. Zabbix переписали на C и PHP. Открытый исходный код появился в 2001 г., а уже через три года выпустили первую стабильную версию.
Веб-интерфейс Zabbix написан на PHP. Для хранения данных используются MySQL, Oracle, PostgreSQL, SQLite или IBM DB2.
На данный момент доступна система Zabbix 4.4. Скачать ее можно на официальном сайте. Там же можно найти официальные курсы и вебинары для начинающих пользователей системы.
Далее рассмотрим, из чего состоит и как работает технология Zabbix в доступном формате «для чайников».
Архитектура Zabbix
У Zabbix есть 4 основных инструмента, с помощью которых можно мониторить определенную рабочую среду и собирать о ней полный пакет данных для оптимизации работы.
Основные возможности
Функционал включает в себя общие проверки для наиболее распространенных сервисов, в том числе СУБД, SSH, Telnet, VMware, NTP, POP, SMTP, FTP и т.д. Если стандартных настроек системы недостаточно, их можно изменить самостоятельно или же пользоваться дополнением через API.
Стандартные функции системы
Проверки
Для описания системы мониторинга Zabbix существует два ключевых понятия:
Сам Zabbix-агент способен отражать текущее состояние физического сервера, собирая совокупность данных. У него достаточно много метрик. С их помощью можно проверить загруженность ядра (Processor load), время ожидания ресурсов (CPU iowait time), объем системы подкачки (Total swap space) и многое другое.
В Zabbix существует целых 17 способов, дающих возможность собирать информацию. Указанные ниже, входят в число наиболее часто применяемых.
У проверок есть заданные шаблоны (Templates), которые упрощают создание новых. Кроме обычных операций существует возможность регулярно проверять доступность веб-сервера с помощью имитации запросов браузера.
Проверка через пользовательский параметр
Чтобы выполнить проверку через агент, нужно прописать соответствующую команду в конфигурационный файл Zabbix-агента в качестве пользовательского параметра ( UserParameter ). Сделать это можно с помощью выражения следующего вида:
Помимо самой команды, приведенный синтаксис содержит уникальный (в пределах узла сети) ключ элемента данных, который надо придумать самостоятельно и сохранить. В дальнейшем, ключ можно использовать для ссылки на команду, внесенную в пользовательский параметр, при создании элемента данных.
Пример
С помощью данной команды можно настроить агент на постоянное возвращение значения « 1 » для элемента данных с ключем « ping ».
Триггеры
У каждого триггера существует уровень серьезности угрозы, который маркируется цветом и передается звуковым оповещением в веб-интерфейсе.
Некоторые функции триггеров
Прогнозирование
Триггеры обладают еще одной важной функцией для мониторинга — прогнозированием. Она предугадывает возможные значения и время их возникновения. Прогноз составляется на основе ранее собранных данных.
Анализируя их, триггер выявляет будущие проблемы, предупреждает администратора о возникшей вероятности. Это дает возможность предотвратить пики нагрузки на оборудование или заканчивающееся место на жестком диске.
Функционал прогнозирования добавили с обновлением системы 3.0, вышедшим в феврале 2016 года.
Действие
Действие (Action) представляет собой заданную реакцию на событие (Event). Действие может устанавливаться автоматически или вручную как для одного из событий, так и для целой группы.
Параметры действий
Для событий, вызванных триггером или обнаружением, есть свои типы условий. Например, «Application» с операторами « = », « like » и « not like » значит, что триггер является частью указанного приложения. Или «Service type» с операторами « = », « »и « > » предусматривает, что обнаруженный сервис совпадает с указанным.
Операции
Пользователь может указать для событий операцию или группу операций.
Параметры операций
Низкоуровневое обнаружение
Функция Низкоуровневого обнаружения (LLD) автоматически создает элементы и триггеры, которые позволяют отслеживать системы сервера, находящимся под наблюдением. Включение функции происходит через настройку атрибутов, которую можно сделать, пройдя по пути: «Настройка» → «Шаблоны» → «Обнаружение» (вкладка в строке с шаблоном) → вкладки «Правила обнаружения»/«Фильтры».
Что можно обнаружить
Дополнительные типы
Задать собственные типы низкоуровневого обнаружения возможно с применением формата JSON. Типы проверок, для которых можно указать список портов и интервал для них:
Если хост пропадает или обнаруживается, для события можно привязать любое действие — условия и операцию для них.
Прокси
Функция буферизации через прокси используется в том случае, когда существующая инфраструктура достаточно большая, а выделенный сервер не способен нести такую нагрузку. Прокси выступает промежуточным звеном, которое собирает информацию с агентов в буфер, а после отправляет данные на сервер.
Прокси используется еще в нескольких случаях — если агенты находятся далеко друг от друга или ограничены локальной сетью. Это сказывается на доступности агентов и величине пингов.
Zabbix прокси функционирует как демон. Для его использования обязательно наличие отдельной базы данных.
Особенности веб-интерфейса
Система мониторинга Zabbix располагает удобным веб-интерфейсом, в котором сгруппированы элементы управления. Консоль предусматривает просмотр собранных данных, их настройку. Для безопасности входа и работы осуществляется автоматическое отсоединение через 30 минут пользовательского бездействия.
На главном экране всегда представлена информация о состоянии узлов сети и триггеров.
Пользователю доступны пять функциональных разделов, включая Monitoring («Мониторинг»), Inventory («Инвентарные данные»), Reports («Отчеты»), Configuration («Конфигурация») и Administration («Администрирование»).
В разделе «Конфигурации» можно найти группы хостов. По каждому элементу списка можно посмотреть более подробную информацию, например, последние события и графики данных.
Управлять шаблонами, доступными администратору, можно в соответствующем подразделе — Templates («Шаблоны»).
Версия 4.4
Узнать версию установленного Zabbix сервера можно во время запуске в файле-протоколе.
Основные нововведения в Zabbix 4.4
Заключение
Zabbix по праву считается одним из самых продвинутых инструментов для удалённого мониторинга аппаратных и программных ресурсов. Система с успехом позволяет решать задачи по отслеживанию сетевой активности и работоспособности серверов, а также предупреждать о потенциально опасных ситуациях. Благодаря встроенным механизмам анализа и прогнозирования, Zabbix может стать основой для создания полноценной стратегии эффективного использования IT-инфрастуктуры в компаниях любого масштаба.
Способности Zabbix ограничены только имеющимися в распоряжении ресурсами. VDS от Eternalhost на SSD-дисках обеспечит системе максимальное быстродействие и возможность мониторить множество узлов в сети.
Универсальная система мониторинга Zabbix — введение
В любой сети, где есть больше, чем один сервер, очень полезно бывает иметь перед глазами полную картину происходящего. В крупных сетях, где количество хостов переваливает за несколько десятков, следить за каждым в отдельности — непосильная задача для администраторов. Для облегчения задачи наблюдения применяются системы мониторинга, и я расскажу об одной из них, которой на Хабре не посвящено ни одной полноценной статьи.
И так, встречайте: Zabbix. Система состоит из нескольких частей, и при большой нагрузке и наблюдении за очень большим количеством хостов позволяет разнести эти части на несколько раздельных машин.
В рамках вводной статьи стоит рассказать о том, какая модель сети используется в Zabbix, чтобы лучше понимать, что к чему и получить представление о возможностях системы.
Основная логическая единица — Узлы сети (host), сервера, находящиеся под наблюдением. Каждому серверу присваивается описание и адрес (dns или ip, можно оба, причем с возможностью выбирать, что использовать для соединения).
Узлы объеднияются в группы, например веб-сервера или сервера баз данных. Группы служат для вывода только определенных серверов при наблюдении.
Каждый узел имеет несколько Элементов данных (items) — параметров, за которыми ведется мониторинг. К примеру, на всех серверах у меня есть параметр ping, (он получается с помощью встроенной проверки), который равняется 1, если ответ на последний ping-запрос был получен, иначе 0. А на одном из серверов у меня есть параметр «количество пользователей онлайн», который собирается самописным скриптом из базы данных сайта. Для каждого элемента данных можно указать свой период обновления, способ хранения(сам параметр или скорость его изменения), множитель, временной интервал сбора (например только в рабочее время).
Создавать элементы данных для каждого из множества серверов — сложно, поэтому можно создать узлы-шаблоны. Эти узлы тоже содержат элементы данных, но они не мониторятся напрямую. Вместо этого реальный хост связывается с одним или несколькими шаблонами, и все параметры шаблона автоматически наследуются хостом. Так, элемент ping у меня хранится именно в шаблоне, и я просто связываю все хосты с шаблоном template_ping.
Человек — не робот, и следить за тысячами параметров и думать, не выходит ли это значение за допустимые границы, просто нереально. Но и тут Zabbix предоставляет гибкие возможности по настройке условий-триггеров, которые включаются при авариях и неполадках, и система начинает моргать лампочками (на самом деле красными квадратиками) и изо всех сил пытается показать администратору, что что-то случилось. Между прочим, при включении триггера веб-интерфейс даже начинает попискивать на манер будильника, наверное, чтобы разбудить заснувших на клавиатуре наблюдателей. 🙂 Так что колонки здесь, наверное не помешают. А в упомянутом выше моем шаблоне template_ping есть и триггер, который реагирует на отсутствие пинга больше, чем на две минуты.
А если администратора нет на месте? Ничего, Zabbix достаточно самостоятелен и сможет отправить уведомление на почту, в jabber или sms с помощью gsm-модема, или даже попытаться самостоятельно поднять упавший сервис, выполнив заранее определенные действия, которые запускаются при срабатывании определенных триггеров.
Скучно сидеть и вглядываться в квадратики и бесконечно бегающие цифры? По данным любого параметра система сможет построить график изменения, причем не за предопределенные и жестко заданные временные интервалы (вспомните mrtg/rrdtool: daily, weekly, monthly, yearly), а за любой промежуток времени с максимальным разрешением. Хотите посмотреть в деталях, как изменялась нагрузка на сервер во время хабраэффекта месяц назад? Пожалуйста, график с разрешением в 30 секунд(именно таков интервал опроса по умолчанию) к вашим услугам. Хотите общую картину? Выберите интервал в месяц и посмотрите на среднюю величину, и разброс колебаний до максимума и минимума. Сравнить? Можно создавать сложные графики, отображающие на одном поле несколько параметров, и вы сразу увидите, что пиковые значения Load Average соответствуют пикам трафика.
Для отображения логической структуры сети можно создавать карты сети, отображающие именно расположение узлов сети и связей между ними. Естественно, состояние узлов (доступен или нет) отображается и на карте.
Кроме того, для более удобного обзора есть комплексные отчеты, которые позволяют на одном экране просматривать сразу несколько сущностей — графики, данные, триггеры…
Zabbix — довольно мощная и обширная система, и запасе у него есть еще полдесятка функций, которые позволяют еще больше упростить наблюдение за сетью, такие как мониторинг состояния веб-сайта с помощью автоматического выполнения сценария вроде «залогиниться, посмотреть новые сообщения и выйти», но их я еще даже не касался.
Скриншоты — с официального сайта Zabbix, и остальные можете посмотреть именно там (а их там много) — http://www.zabbix.com/screenshots.php
В ближайшем будущем — о том, как использовать Zabbix вместо Nagios и MRTG и рекомендации по миграции на Zabbix с этих двух систем и сравнение преимуществ и недостатков; о написании собственных скриптов оповещения и сбора данных, о моём личном опыте использования Zabbix в продакшне, и о чем-нибудь еще, что я узнаю в процессе дальнейшего изучения этой замечательной системы.
Zabbix
ZABBIX 1.1 alpha 6 running under GNU/Linux | ||||||||||||||||||||||||||||||||
Тип |
---|
График релизов | |
---|---|
Дата | Релиз |
Zabbix 1.0 | |
1998 | ПО Zabbix началось как внутренний проект в банке Алексеем Владышевым [1] |
7 Апреля 2001 | Zabbix 1.0alpha1 был выпущен с лицензией GPL [2] |
23 Марта 2004 | Выпущен Zabbix 1.0 [3] |
Zabbix 1.1 | |
6 Февраля 2006 | Выпущен Zabbix 1.1 [3] |
Zabbix 1.4 | |
29 Мая 2007 | Выпущен Zabbix 1.4 [3] |
Zabbix 1.6 | |
11 Сентября 2008 | Выпущен Zabbix 1.6 [3] |
Zabbix 1.8 | |
7 Декабря 2009 | Выпущен Zabbix 1.8 [3] |
Zabbix 2.0 | |
21 Мая 2012 | Выпущен Zabbix 2.0 [3] |
Структура
Обзор возможностей
Автоматическое обнаружение
Низкоуровневое обнаружение
Низкоуровневое обнаружение может быть использовано для обнаружения и для начала мониторинга файловых систем, сетевых интерфейсов. Начиная с Zabbix 2.0, поддерживаются три встроенных механизма низкоуровневого обнаружения:
Разработка плагинов для Zabbix Agent 2
На последнем Zabbix Summit 2019 вместе с выходом Zabbix 4.4 был анонсирован новый Zabbix Agent 2, ключевая фишка которого — возможность написания плагинов к нему на языке Go. И многие сразу стали спрашивать: а как же, собственно, эти плагины писать, как они устроены? Где взять документацию и примеры?
В этой статье я хочу дать ответы на эти и некоторые другие вопросы. Обо всём по порядку, но если вы из тех, кто сразу рвётся в бой, смело пропускайте вступительную часть и переходите к практике ⎝◔◞ ◔⎠
Что за новый агент, и зачем он появился?
Если вы пробовали писать плагины для первого Zabbix Agent, или хотя бы намеревались это сделать, то, наверняка, отметили, что ваши возможности весьма ограничены.
Плагин для первого агента мог запускаться в нескольких различных процессах, не давая создателю достаточного контроля над ним, чтобы реализовать, например, использование постоянных соединений, сохранение состояния между проверками, приём трапов — делать подобные вещи было либо сложно, либо вообще невозможно.
Новый агент имеет совершенно иную архитектуру. Он написан с нуля на языке Go (с некоторым переиспользованием Си кода из Zabbix Agent), что значительно упрощает написание плагинов по сравнению с созданием их на языке Си. С помощью Go-агент — предлагаю для простоты называть его так — можно решать описанные выше задачи простым и понятным образом. Несмотря на это, Go-агент обратно совместим с классическим Zabbix Agent на уровне протокола, конфигурации и метрик.
Новые возможности, появившиеся с Go-агентом:
Архитектура агента
Прежде чем написать первый плагин, давайте разберемся в общих чертах, как всё это устроено «под капотом». Сразу отмечу, что информация актуальна для Zabbix 4.4. Учитывая, что Go-агент пока имеет статус экспериментальной фичи, не исключаю, что к выходу Zabbix 5.0 что-то может поменяться.
Основные компоненты агента — это ServerConnector, ServerListener и Scheduler.
ServerConnector управляет коммуникацией с сервером (получение конфигурации/экспорт данных), конфигурацией items и кэшем исторических данных. Создаётся один коннектор на каждый активный сервер.
ServerListener принимает пассивные запросы и направляет их в Scheduler. Сейчас его функциональность ограничена только этим, но в будущем она может быть расширена.
Scheduler управляет очередью задач в соответствии с расписанием и настройками конкурентности. Агент запускает единственный Scheduler для управлением задачами (плагинами) в соответствии с расписанием, определяемым настройками item’ов.
Внутреннее устройство агента можно условно представить в разрезе двух типов проверок: активные и пассивные (вскоре ещё появятся Bulk Passive, но пока их нет). Тут важно понимать, что все они разделяют общие компоненты, а разделение на типы сделано только для упрощения восприятия.
Схемы ниже иллюстрируют взаимодействие компонентов для каждого типа. Прошу прощения за кривые картинки — не осилил PlantUML ¯\(ツ)/¯
Активные проверки
Для каждого активного сервера создаётся пара: ServerConnector и ResultCache, каждый из которых запускается в своей горутине.
Пассивные проверки
Классические пассивные проверки также используют Scheduler для управления задачами, но вместо ServerConnector’а используется ServerListener в качестве источника конфигурации item’ов. Результаты не кэшируются, а сразу отправляются в ResultWriter, отсылающий данные на сервер в ответ на запрос.
Обработка конфигурации
Получив конфигурацию items от Zabbix сервера, ServerConnector обновляет данные у себя и создает updateRequest для каждого плагина, предоставляющего соответствующие метрики. Запросы через канал передаются планировщику, который создаёт задачи и помещает их в очередь. Таким образом, они выполнятся незамедлительно в тот момент, когда у плагина не останется никаких других задач.
Планировщик и задачи
Взаимодействие агента с плагинами строится через двухуровневую очередь задач:
Задачи в рамках одной секунды выполняются в следующем порядке:
exporterTask
ExporterTask используется для активных проверок (и bulk пассивных проверок в будущем). Такая задача содержит item, который необходимо переодически опрашивать. Scheduler вызывает функцию Export интерфейса Exporter в отдельной горутине и записывает результат её выполнения в ResultWriter.
directExporterTask
directExporterTask используется для пассивных проверок и отличается от ExporterTask тем, что, в случае отсутствия результата опроса метрики (пустое значение), задача будет возвращена в очередь, и через 1 секунду планировщик попытается выполнить её повторно. Так будет повторяться до момента получения результата либо до наступления таймаута. Ещё одно отличие — directExporterTask не позволяет возвращать несколько значений.
watcherTask
WatcherTask содержит список метрик (запросов) для мониторинга. Планировщик вызывает функцию Watch интерфейса Watcher, передавая в качестве параметров список запросов.
collectorTask
Scheduler вызывает функцию Collect интерфейса Collector каждые Period() секунд.
starterTask
Планировщик вызывает функцию Start интерфейса Runner, когда плагин активирован.
stopperTask
Планировщик вызывает функцию Stop интерфейса Runner, когда плагин остановлен.
configuratorTask
Планировщик вызывает функцию Configure интерфейса Configurator, передавая ей в качестве параметров структуру с глобальными опциями агента и структуру с опциями, относящимися к конкретному плагину.
Интерфейсы
Всего доступно 5 интерфейсов: Exporter, Watcher, Collector, Runner и Configurator.
Exporter и Watcher определяют способ работы с данными: Exporter реализует pull модель, а Watcher — push.
plugin.Exporter
Exporter — это простейший интерфейс, который выполняет опрос и возвращает значение, несколько значений, ошибку или же не возвращает ничего. Он принимает предобработанный ключ, параметры ключа и контекст. Для большинства плагинов этого достаточно. Замечу, что это единственный интерфейс, позволяющий конкурентный доступ. Все остальные интерфейсы имеют эксклюзивный доступ, и ни один другой метод не может работать параллельно, пока плагин выполняет какую-либо задачу.
Будьте внимательны, если созданный плагин реализует конкурентный доступ к данным. В этом случае нужно самим обеспечить правильный доступ нескольких потоков к разделяемым данным. Для этого в вашем распоряжении есть весь арсенал языка Go: мьютексы, каналы, атомарные счетчики, sync.Map и другие примитивы синхронизации. Не забывайте использовать race-детектор, чтобы обнаружить возможные состояния гонки.
Существует лимит на количество конкурентных запросов функции Export() — максимум 100 запросов на плагин. При необходимости этот лимит можно уменьшать для каждого плагина в отдельности, используя функцию plugin.Base.SetCapacity.
Кроме того, capacity можно установить с помощью одноимённого параметра в конфигурационном файле. Например:
Plugins.
plugin.Watcher
Watcher позволяет плагину реализовать собственный процесс опроса метрик, не используя встроенный планировщик агента. Это может быть актуально для плагинов, использующих механизм trapping, которым нужен полный контроль над сбором и экспортом данных. Основной use case для интерфейса — ждать данные, и, по мере их поступления, отправлять результаты на сервер. Так, например, можно реализовать мониторинг логов или плагин, который подписывается на события от внешнего источника и ждёт, когда ему придут данные.
plugin.Collector
Collector используется в случаях, когда плагину необходимо собирать данные через регулярные интервалы времени. Он не умеет возвращать данные самостоятельно, поэтому для возврата его нужно использовать в связке с Exporter’ом.
Типичный use case для Collector — частый сбор данных и помещение их в кэш, где записи будут храниться до момента, пока их не запросит Zabbix сервер.
У Collector’а есть 2 функции:
plugin.Runner
Runner предоставляет средства для выполнения инициализации, когда плагин активирован (функция Start), и деинициализации, когда плагин не используется и остановлен (функция Stop).
Реализовав этот интерфейс, плагин может, к примеру, запускать или останавливать какой-либо фоновый поток, освобождать неиспользуемые ресурсы, закрывать соединения и т.д.
Активация и деактивация плагина происходит в зависимости от наличия или отсутствия запросов (метрик) для обработки. В случае активных проверок, когда обновляется конфигурация с сервера (Zabbix Server или Proxy), планировщик получает новые задачи. Как только появится первая задача, предназначенная на выполнение нашему плагину, он активируется. Остановка произойдет, когда в конфигурации больше не остается запросов к плагину. В случае пассивных проверок, плагин активируется в момент, когда приходит запрос от сервера, и останавливается через 24 часа после поступления последнего запроса.
plugin.Configurator
Интерфейс Configurator нужен, чтобы предоставить возможность конфигурировать плагин.
Интерфейс имеет 2 функции:
К счастью, нам не нужно делать ничего, что связано с чтением конфиг файла или его парсингом. Агент позаботится об этом за нас.
Параметры конфигурации Go-агента по большей части совместимы с Zabbix агентом за несколькими исключениями.
Типы плагинов
Плагины бывают внутренние и внешние. Плагины, которые экспортируют внутренние данные агента — это, соответственно, внутренние плагины. Они располагаются в пакете internal/agent и имеют префикс «plugin_» в названии. К примеру, так реализован плагин, отвечающий за работу с UserParameters.
Всё остальное, включая плагины, реализующие сбор стандартных метрик (таких как ЦПУ, сеть, диски, память и т.д.) — это внешние плагины. Созданные нами плагины будут работать наравне с ними и иметь такие же возможности. Располагаются внешние плагины в директории go/plugins, каждый в своём подкаталоге.
Hello, world!
Плагин — это обычный пакет Go, в котором реализован один или несколько интерфейсов, определяющих логику его поведения. Пример простейшего плагина:
Выглядит не сложнее, чем скрипт на bash или python, правда? ⎝^ω^⎠ Осталось только добавить к нему код, который будет делать какую-то полезную работу.
Давайте немного попрактикуемся и попробуем написать плагин, возвращающий прогноз погоды для города, который мы передадим ему в качестве параметра ключа.
Для этого нам нужно сделать следующее:
Для начала скачаем исходные коды Zabbix.
Создадим каталог src/go/plugins/weather и пустой файл weather.go в нём, который будет содержать наш код.
Далее, импортируем встроенный пакет «zabbix.com/pkg/plugin».
Определяем свою структуру, в которую встраиваем структуру Base из пакета plugin. Она понадобится нам в дальнейшем.
Теперь напишем код для получения и обработки данных. Всё, что нам нужно сделать, это:
Для решения такой задачи идеально подойдёт интерфейс Exporter.
Следующий шаг — зарегистрировать метрики, чтобы агент узнал о них и смаршрутизировал их обработку к нашему плагину.
Воспользуемся функцией plugin.RegisterMetrics.
Вызовем её из функции init (это произойдёт сразу при старте агента).
Одним вызовом этой функции мы могли бы зарегистрировать сразу несколько метрик, если бы они у нас были.
Кстати, на данный момент поддерживаются 3 платформы: linux, darwin и windows. В будущем, этот список, вероятно, будет расширен.
И последнее: чтобы рассказать агенту о существовании нашего плагина и подключить его при компиляции, нужно включить его в список импортов в файлы src/go/plugins/plugins_
Сборка
Если у вас ещё не установлен Go, то сейчас самое время сделать это.
Нам понадобится версия Go не ниже 1.13.
После окончания сборки можно запустить агент и проверить, как работает новый плагин. В данном случае мы передаем ему в качестве параметра “moscow” и получаем ответ.
Собирать агент нужно только один раз. При дальнейшей разработке плагина, мы можем использовать команду go run, чтобы быстро проверить работу кода.
Логирование
Если плагину требуется логирование, можно использовать функции из пакета zabbix.com/pkg/log: Tracef, Debugf, Warningf, Infof, Errf, Critf. Аналогичные функции содержит и наша структура Plugin, это обертки над функциями из пакета log. Разница лишь в том, что они добавляют префикс [
Конфигурация плагина
Go-агент позволяет конфигурировать плагины на уровне конфигурационного файла агента. Для этого существует специальный параметр Plugins. По сути, он является не параметром вида ключ-значение, как все остальные параметры агента, а специальной секцией, где можно описывать специфичные параметры для каждого плагина в отдельности. В общем случае это выглядит так: Plugins.
Реализовать передачу параметров в плагин можно, используя интерфейс Configurator. Для примера давайте добавим в наш плагин параметр Timeout, который будет определять максимальное время для HTTP запроса.
Допустим, мы хотим, чтобы Timeout имел допустимый диапазон от 1 до 30 секунд, был опциональным и по умолчанию (если не задан) равнялся бы глобальному таймауту агента.
Определим структуру, описывающую нашу конфигурацию.
Если вы обратили внимание, мы описали допустимый диапазон и признак опциональности параметра с помощью метаданных в тэге conf. Агент умеет использовать эти данные при чтении конфига.
Теперь расширим структуру Plugin и добавим туда поле для хранения конфига, и заодно — http.Client, для которого мы будем устанавливать таймаут.
Реализуем интерфейс Configurator. Как мы помним, у него 2 метода: Configure и Validate.
Вызовом функции conf.Unmarshal загружаем параметры плагина в заданную нами структуру.
Заменим вызов http.Get на p.httpClient.Get.
Наконец, мы можем добавить наш параметр в конфигурационный файл агента:
Plugins.Weather.Timeout=1
Теперь если таймаут будет превышен, плагин должен выдать ошибку.
Но что, если мы введём какое-то недопустимое значение и запустим агент? Вы можете проверить — агент просто запустится и даже не выругается. Timeout будет установлен в default, т.е. будет равен глобальному таймауту.
Предупреждение в логе появится лишь в момент первого обращения к плагину (только тогда он активируется, и будут вызваны методы Validate и Configure).
Это не совсем то поведение, которое нам нужно. Пожалуй, было бы правильнее, если бы агент падал, в случае, когда конфиг некорректен. Для этого достаточно доработать метод Validate. Он вызывается при старте агента для всех плагинов, которые его реализуют.
Теперь если мы введём ошибочное значение параметра, то уже при запуске агента получим ошибку, подобную этой: «cannot create scheduling manager: invalid plugin Weather configuration: Cannot assign configuration: invalid parameter Plugins.Weather.Timeout at line 411: value out of range».
В следующих версиях агента будет добавлена возможность реконфигурации плагинов «на лету». При получении соответствующей runtime команды будут вызываться методы Validate и Configure, и плагин будет иметь возможность реагировать на них и обновлять свои настройки. Будьте внимательны, если вы создаёте какие-то горутины прямо из Configure — вы можете столкнуться с тем, что при реконфигурации будут запускаться всё новые и новые экземпляры этих горутин. Возможно, стоит вынести их запуск и остановку в методы Start и Stop (интерфейс Runner).
Пример посложней
Мы разобрались как писать Exporter плагины. Это действительно очень просто. Давайте теперь попробуем реализовать плагин, использующий интерфейсы Collector и Runner.
Долой синтетические примеры! Напишем что-нибудь полезное. Пусть это будет плагин, поэтапно замеряющий время выполнения HTTP запроса и вычисляющий перцентили на основе собранной статистики.
Для начала реализуем метод сбора данных. Для этого воспользуемся пакетом «net/http/httptrace» (был представлен в Go 1.7).
Для вычисления перцентилей нам потребуется где-то хранить собранные данные. Для этой цели нам нужна циклическая очередь (Ring Buffer). Чтобы не усложнять наш пример, воспользуемся готовым решением — github.com/VadimIpatov/gcircularqueue. Это далеко не самая эффективная реализация, зато она позволит сохранить читаемость кода. Для вычисления перцентилей тоже воспользуемся силой Open Source и богатством экосистемы Go — я остановился на пакете github.com/montanaflynn/stats. Теперь мы можем описать структуры для хранения данных.
Для инициализации и очистки ресурсов используем методы Start и Stop интерфейса Runner.
Сбор данных реализуем при помощи интерфейса Collector.
Здесь мы в цикле бежим по списку URL (нам ещё предстоит его наполнить), для каждого из которых вызываем метод p.measureTime(url.url) и помещаем результат в буфер. Чтобы сделать точную привязку данных к времени, мы сохраняем время опроса в url.modified.
Так же мы удаляем те URL из списка, по которым давно не было обращений.
Как вы помните, Collector не умеет экспортировать данные. Нам нужен Exporter.
Обратите внимание, что мы используем мьютексы в методах Collect и Export, т.к. они используют разделяемые данные.
Результат работы плагина (вывод отформатирован для удобства):
Мониторинг мониторинга
У агента есть runtime команда metrics, которая показывает состояние всех созданных плагинов и их текущую нагрузку. Иногда это может оказаться полезным.
Использовать её очень просто:
Эту информацию можно получить и другим способом — по HTTP. Для этого в конфиге агента нужно задать параметр StatusPort=, перезапустить агент и направить браузер на адрес http:// :
Что дальше?
А дальше мы планируем активно развивать агент. Расскажу немного о функционале, который может появиться в будущем:
Мне мало!
Для тех, кто хочет глубже погрузиться в тему, я сделал подборку полезных ссылок:
Templates guidelines — здесь мы собрали лучшие практики и свои рекомендации по разработке качественных шаблонов.
An official guide to making and managing great templates — презентация с последнего Zabbix Summit на эту же тему.
Magic of the new zabbix agent — презентация Zabbix Agent 2.
Официальная документация по Zabbix Agent 2.
Больше примеров кода вы найдёте в исходных кодах Zabbix Agent 2 (наш репозиторий тут: git.zabbix.com). Здесь можно посмотреть, как реализованы стандартные проверки.
Исходный код плагина Weather.
Исходный код плагина HttpTrace.
Writing watcher Zabbix Agent2 MQTT plugin in Go — отличный пример использования Watcher интерфейса.
Если вдруг вы ещё не знакомы с языком Go, обратите внимание на «Маленькую книгу о Go» и, конечно, пройдите официальный A Tour of Go ʕ☉Ѡ☉ʔ
Zabbix Agent 2 — многообещающая платформа для расширения возможностей Zabbix по сбору данных. Написанный на мощном языке Go, новый агент дает большую свободу в создании плагинов и приоткрывает дверь в этот мир для каждого, ведь освоить эту технологию намного легче, чем C Loadable modules.
- Не могу встать утром что делать
- Меринос альпака или кашемир что лучше