Мониторинг транков Asterisk с помощью низкоуровнего обнаружения Zabbix

в 3:59, , рубрики: asterisk, ip-телефония, linux, php, zabbix, мониторинг сервера, метки: , , ,

Предисловие

В прошлом году компания, в которой я работаю, стала активно переходить на IP-телефонию. Для этих целей был использован дистрибутив FreePBX. Опыта работы с телефонией практически не было, поэтому проблем было много. Всего у нас используется 2 сервера FreePBX, примерно по 30 транков на каждом. Некоторые транки ведут себя не очень хорошо и порой теряют регистрацию. Поэтому возникла необходимость мониторить состояние регистрации, чтобы узнавать о неработающей телефонии раньше пользователей.
Для мониторинга IT-инфраструктуры мы уже давно используем Zabbix. Заводить элементы данных на каждый транк (т.е. около 60) — задача нудная, утомительная и неинтересная. Кроме того, надо постоянно следить за списком транков в мониторинге и актуализировать его. Поэтому, решено было использовать одну из самых интересных особенностей этой системы мониторинга — низкоуровневое обнаружение. Итак, что было сделано.

Настройка сервера Zabbix

Создание шаблона Zabbix

В веб-панели Zabbix заходим в Настроки->Шаблоны, и создаем пустой шаблон. Назовем его, например, Asterisk Trunks Discovery. Заходим в редактирование шаблона, и переходим в раздел «Обнаружение». Там создаем 2 правила обнаружения, одно с ключом asterisk.discovery[ips] — оно будет мониторить IP-адреса провайдеров телефонии, второе с ключом asterisk.discovery[trunks] — оно будет мониторить регистрацию. Ключи эти придуманы, можно использовать какие угодно, главное чтобы не пересекались со встроенными ключами ZAbbix.

image

Создание прототипов элементов данных

Для каждого правила обнаружения нужно создать прототипы элементов данных, который собственно и будут собирать данные о каждом транке. Для правила asterisk.discovery[trunks] мы используем элемент данных с ключом asterisk.registry[{#TRUNKNAME}]. Имя ключа, опять таки не важно, важен только его параметр #TRUNKNAME. Все остальное видно на картинке.

image

Для правила asterisk.discovery[ips] мы использовали элементы данных из стандартного шаболона для пинга, заменив имя хоста на макрос {#TRUNKIP}. На картинке все наглядно видно.

image

Осталось только присоединить шаблон к нужным серверам. На этом, с настройкой Zabbix закончим.

Настройка серверов Asterisk

Создаем папку для скриптов /usr/scripts. Копируем в нее скрипт для обнаружения транков trunk_disc.php и скрипт для мониторинга транков reg_mon.php (да-да, они на php, да и кривенькие, т.к. набросаны на скорую руку, а доделать потом руки так и не дошли). Сами скрипты:

Скрипт trunk_disc.php

#!/usr/bin/php
<?php
error_reporting(1);
exec("sudo asterisk -rx 'sip show registry'", $tr_list);
foreach($tr_list as $line) {
        $ar_line = null;
        $ar_line[] = trim(substr($line, 0, 40));
        $ar_line[] = trim(substr($line, 47, 19));
        $ar_line = array_diff($ar_line, array(''));
        $ar_line = array_combine(array(0,1), $ar_line);
        $trunks[] = $ar_line['1'];
        $ip = explode(":", $ar_line['0']);
        if (!in_array($ip['0'], $ips)) {
                $ips[] = $ip['0'];
        }
}
$trunks[0] = '';
$ips[0] = '';
$trunks = array_diff($trunks, array(''));
$ips = array_diff($ips, array(''));

function getJson($items, $name) {
        $first = 1;
        print "{n";
        print "t"data":[nn";
        foreach ($items as $item) {

                if (!$first) {
                        print "t,n" ;
                        $first = 0;
                }
                print "t{n";
                print "tt"{#$name}":"$item"n";
                print "t},n";
        }
        print "nt]n";
        print "}n";
}
if ($argv[1] == 'trunks') {
        getJson($trunks, "TRUNKNAME");
}
elseif ($argv[1] == 'ips') {
        getJson($ips, "TRUNKIP");
}
else {
        print "error";
}

Скрипт reg_mon.php

#!/usr/bin/php
<?php
error_reporting(0);
$find = "*".$argv[1]."*";
exec("sudo asterisk -rx 'sip show registry'", $tr_list);
$filter = preg_grep($find, $tr_list);

foreach($filter as $line) {
        if (preg_match("*Registered*", $line) & preg_match($find, $line)) {
                exit('1');
        }
        else {
                exit('0');
        }
}
exit('0')

В файле конфигурации агента Zabbix добавляем:

UserParameter=asterisk.registry[*],/usr/scripts/reg_mon.php $1
UserParameter=asterisk.discovery[*], /usr/scripts/trunk_disc.php $1

И перезапускаем агент Zabbixa.

Проверка

Для проверки работы логинимся в в консоль Zabbix-сервера. Запускаем команду zabbix_get -s <asterisk server ip> -k asterisk.discovery[trunks]
Вывод должен быть примерно таким

{
        "data":[

        {
                "{#TRUNKNAME}":"trunk1"
        },
        {
                "{#TRUNKNAME}":"trunk2"
        },
        {
                "{#TRUNKNAME}":"trunk3"
        },
        {
                "{#TRUNKNAME}":"trunk4"
        },
        {
                "{#TRUNKNAME}":"trunk5"
        },
        {
                "{#TRUNKNAME}":"trunk5"
        },
...

Здесь имена своиз транков я сменил на trunk1,trunk2 и т.д. Далее запускаем zabbix_get -s <asterisk server ip> -k asterisk.discovery[ips]
Вывод примерно такой:

{
        "data":[

        {
                "{#TRUNKIP}":"213.141.252.17"
        },
        {
                "{#TRUNKIP}":"188.187.255.6"
        },
        {
                "{#TRUNKIP}":"sip.pctel.ru"
        },
...

Здесь я даже адреса менять не буду. И напоследок, проверяем мониторинг регистрации zabbix_get -s <asterisk server ip> -k asterisk.registry[trunk1] Для зарегистрированного транка выведет 1, для незарегистрированного 0. Пожалуй, на этом настройку можно считать оконченной. Теперь можно открыть веб-интерфейс Zabbix и насладиться результатом.

Заключение

Я в первый раз пишу статью на Хабре, поэтому надеюсь на некоторую снисходительность. Думаю, эта статья будет полезна в основном для начинающих администраторов, т.к. истинных гуру Zabbix таким не удивишь. Кроме того, она пригодится тем, кому лень изобретать велосипед и нужен готовый рецепт. Благодарю за внимание.

Автор: rootofevil

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js