Как подружить Zabbix с Asterisk «из коробки»

В предыдущей статье «Zabbix — расширяем макро границы» я рассказал как получать сессию авторизации и подставлять ее в локальный макрос хоста. В этой статье я расскажу как подружить Zabbix с Asterisk без внешних скриптов и ПО.

Идея «подружить» эти две системы родилась давно, причем без установки дополнительного софта и скриптов. Быстрое гугление выдавало множество вариантов решений, все сводилось к тому, что закиньте скрипты (на пыхе, баше, питоне и т. п.) на сервер, и будет вам счастье. Мне же хотелось реализовать мониторинг «из коробки» — без внешних скриптов и установки дополнительного софта на сервер с мониторингом и АТС.

Провозился я с этим в сумме 4 рабочих дня, но результат стоил того. Работа через интерфейс AMI, низкоуровневое обнаружение, триггеры, а главное, на подключение АТС и все остальные настройки теперь уходит минут 15.

В наличии заббикс 4.4, около 100 штук Астерисков 13 версии. Какие-то АТС идут с веб интерфейсом FreePBX, какие-то с голой консолью, кучей хитростей и интеграцией через диалплан.

Получаем данные из АТС

Первый и основной момент, который нужно решить — получение данных о пирах и сип регистрациях. Для этого в АТС существуют интерфейсы AGI, AMI, ARI и SSH консоль. Дополнительные модули по понятным причинам не рассматривал.

Для начала надо разобраться, что из себя представляют эти аги, ами, ари….

  • AGI — использование скриптов в диалплане. В основном используется для управления вызовами.
  • AMI — умеет отдавать всю необходимую информацию, работает через порт 5038 по аналогии с Telnet. Нам подходит!
  • ARI — современно, модно, JSONно. Много возможностей, формат данных в понятном виде для Zabbix, но для меня нет главного: нельзя контролировать сип регистрацию. Еще один минус, для пиров есть только два состояния online/offline, хотя состояний больше и их учитывать полезно при диагностике.
  • SSH — может все, но иногда его не дают из-за «соображений безопасности». Соображения могут быть разными, разбирать их не буду.

Zabbix и Telnet — мое разочарование

AMI знаю хорошо, в свое время реализовывал отслеживание потерь в разговорах с делением по удаленным офисам, управление звонками и т.п. С Telnet тоже все предельно ясно: открывай подключение, шли команды и читай ответ. Что я и сделал, но результат меня разочаровал.

Telnet у заббикса не такой как в консоле Linux, он чуть более простой и заточенный под стандартную авторизацию типа логин/пароль. Если логика авторизации другая, и нет запроса пары логин/пароль, вылетает ошибка. После тщетных попыток обойти требование авторизации полез смотреть исходники модуля Telnet.

Я понял, что пока не будет традиционного запроса логина с паролем, дальше не продвинусь. Ради интереса, выкинул из кода все, что касается авторизации, пересобрал все. Работает! Но под требования не подходит. Идем дальше…

Возвращаемся к поиску

Перечитал еще раз документацию по ARI, провел дополнительные тесты — нет тут сип регистраций. Пиры есть, разговоры есть, бриджи есть, регистраций нет. В какой-то момент даже задумался, так ли нужны нам сип регистрации?

По забавному стечению обстоятельств, в этот момент прилетает очередной запрос от пользователя, с проблемой исходящих звонков. Проблема была в подвисании сип регистрации и решалась обычной перезагрузкой модуля.

Было бы здорово по вебу обращаться к AMI: это бы решило все проблемы, подумал я. Начинаю копать в этом направлении, и буквально первая строка поиска ведет на официальную документацию Asterisk, в которой говориться, что для моих задач есть опция webenabled в файле /etc/asterisk/manager.conf, которую нужно установить в значение YES, в секции [general]

После этого, через обычный веб запрос вида http://ats:8089/mxml?action=SIPshowregistry получаем всю необходимую информацию.

Сколько работал с разного рода интеграциями Asterisk, никогда не видел, чтобы где-то упоминалась эта функция. Меня удивило, что никто не описывает этот метод взаимодействия с АТС. Даже специально полез искать информацию по данной теме: практически ничего нет или использовалось для совершенно других задач.

WEB AMI — что за зверь?

Добавление опции webenabled в файл manager.conf открывало полноценный доступ к управлению АТСкой через веб. Все команды, доступные через обычный AMI, теперь есть в вебе, можно слушать события от АТС через сокет. Принцип работы ничем не отличается от консольного AMI. После активации данной опции, к АТС можно обратиться по следующим адресам:

https://ats:8089/manager — веб страница с простым интерфейсом, для тестов и ручной отправки запросов. Все ответы форматируются в читабельный HTML вид. Для мониторинга не очень подходит.
https://ats:8089/rawman — только текстовый вывод, формат аналогичен консольному AMI
https://ats:8089/mxml — только текстовый вывод, в формате XML. Нам подходит!

Тут я было подумал: «Вот оно – решение! Сейчас все будет готово! Изи-пизи лемон сквизи», но радоваться было пока рано. Для получения нужной нам информации достаточно использовать GET запрос с нужными действием action, который в ответ возвращает xml со списком всех регистраций и их состоянием. Это все здорово, но нужна авторизация с запоминанием сессии из cookie. Когда тестируешь в браузере, не задумываешься об этом процессе.

Процесс авторизации

В начале мы обращаемся на адрес http://ats:8089/mxml?action=loginusername=zabbixsecret=zabbix, в ответ нам сервер присылает куку с сессией авторизации. Вот так выглядит HTTP запрос:

Для работы там нужно mansession_id , т.е. сама кука авторизации.
Контент нужно лишь проверить наличие ответа «Authentication accepted». Дальше, при всех обращениях к серверу АТС нам необходимо будет добавлять в запрос куку авторизации.

Как получать куку авторизации и использовать в других запросах читайте тут: «Zabbix — расширяем макро границы»

Для создания элементов отслеживания в заббиксе буду использовать авто обнаружение.

Авто обнаружение

Для авто обнаружения регистраций и отслеживания состояний пиров необходимо обращаться к адресу: https://ats:8089/mxml?action=SIPshowregistry или https://ats:8089/mxml?action=SIPpeers

В ответ АТС возвращает нам XML ответ:

В ответе много мусора, по этому в препроцессинге мы его фильтруем по шаблону XPath: //response/generic[@host]
Дальше начинается самое интересное. Чтобы работать с обнаружением и динамически создавать элементы, нужно чтобы ответ был в JSON формате. XML при авто обнаружениях не поддерживается.

Для преобразования XML в JSON пришлось немного поиграться с авто заменой, для чего я сделал скрипт на JS

Интересный момент, в ответе АТС все параметры обрамляются одинарными кавычками, а после применения шаблона //response/generic[@host] они заменяются на двойные.

Для создания элементов используем переменные из XML ответа ( теперь JSON )​.

SIP Registry

Для сип регистраций используем три переменные: username, host, port. Меня устраивало название элемента 111111@login.mtt.ru:5060, ситуаций когда нужно использовать все пять переменных я не нашел.

Главный элемент, который получает информацию о всех регистрациях, Asterisk — AMI SIPshowregistry. Раз в минуту он обращается GET запросом к https://ats:8089/mxml?action=SIPshowregistry, после чего данные XML ответа передаются всем зависимым элементам для анализа. Элемент по каждой регистрации создаю зависимыми от него. Это удобно, т. к. актуальную информацию мы получаем за один запрос, а не для каждого отдельно. У данной реализации есть существенный минус — нагрузка на процессор.

При тестировании до 100 зависимых элементов, нагрузку не заметил, но при 1700 элементов, это давало заметную 15 секундную нагрузку на процессор. Имейте это ввиду, если у вас большое количество зависимых элементов.

Как вариант для «размазывания» нагрузки или установки разной частоты опроса элемента, можно вынести логику обработки в каждый элемент отдельно.

Полученную информацию я не храню в главном элементе. Во-первых, не вижу в этом необходимости, а во-вторых, если ответ больше 64К, то заббикс его обрезает.

Поскольку для зависимого элемента у нас используется полный XML ответ, нам нужно в препроцессинге получить значение данного элемента. Через XPath это делается так:
string(//response/generic[@event=«RegistryEntry»][@username="<#SIP_REGISTRY_USERNAME>"][@host="<#SIP_REGISTRY_HOST>"][@port="<#SIP_REGISTRY_PORT>"]/@state)
Для статусов регистраций не стал использовать текстовые статусы, а перевел их в числовой вид с помощью JavaScript:

SIP Peers

По аналогии с сип регистрациями, есть главный элемент Asterisk — AMI SIPshowregistry, к которому добавляются зависимые.

Здесь создается два зависимых элемента:

  • Статус пира в текстовом виде
  • Время отклика устройства — если статус ОК, то пишется время ответа устройства, иначе «-1»

Для второго элемента использовал JavaScript, чтобы отделить время отклика от статуса пира, поскольку хранятся они вместе:

Заключение

Решение «из коробки» может быть сложным и не сразу понятным. Возрастает гибкость и переносимость между разными системами

Всем приятной и легкой интеграции! Шаблон и инструкция по настройке на GitHub.


Источник: habr.com