zabbix_sender over HTTP

в 14:45, , рубрики: api, open source, php, zabbix, велосипеды

В этой статье я приведу возможное решение проблемы для многих системных администраторов, которые используют систему мониторинга Zabbix. Особенно пригодится для тех, кто осуществляет мониторинг разных программ в Zabbix: системы телефонии, разные регламентные операции с БД, 1С (да, да, такие вот мы извращенцы люди с нестандартным мышлением, что мониторим 1С в Zabbix). Сам мучался делая Powershell-скрипты, использую для отсылки zabbix_sender.exe. Страшные были времена.

Как мы до этого дошли

Пользуюсь данной системой не первый год. В начале использовали для мониторинга доступности (ага, таким комбайном делали icmp-запросы и все). Сейчас используем почти весь функционал, карты, инвентаризацию, отчеты. С недавнего времени стали прикручивать мониторинг бэкапов (не только Linux-систем, но и разных Windows), мониторинг разных программ (кассовые программы в рознице), обменов, синхронизаций. И каждый раз приходилось писать скрипты, потому что многие программы не могли сами запускать zabbix_sender.exe с нужными параметрами (особенно касается 1С). Для мониторинга этих скриптов писались другие скрипты. Программа экспортирует что-то в файл, скрипт его парсит, отправляет все через zabbix_sender.

Каждый раз мне — как системному администратору — приходилось делать все скрипты. Программисты 1С же просто писали файлики, логика была вся на мне. Меня это как и любого ленивого системного администратора не устраивало.
Я всегда негодовал (особенно в начале), почему нет веб-интерфейса для отправки значений в Zabbix? А теперь все проще — ну раз нет, так напишем!

Реализация

Оправдания, извинения

Сразу скажу, я не PHP-программист, поэтому у толковых программистов код может вызвать кровотечения из области глаз. Также не стоит данное решение подвергать большой нагрузке, для каждого значения запускается отдельный экземпляр zabbix_sender, если нужно отправить сразу много значений — возможно стоит поискать в API и устанавливать одну сессию, без разрыва. Таким способом мы получаем примерно 200 параметров за минуту, пока полет отличный!

Приступим! Создаем папку zabbix_sender на сервер zabbix (у меня папка /var/www/zabbix, не забываем про root-права):

mkdir /var/www/zabbix/zabbix_sender
chown www-data:www-data /var/www/zabbix/zabbix_sender

Создаем файл index.php, содержание в

спойлере

<?php
function get_client_ip() {
    $ipaddress = '';
    if (getenv('HTTP_CLIENT_IP'))
        $ipaddress = getenv('HTTP_CLIENT_IP');
    else if(getenv('HTTP_X_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_X_FORWARDED_FOR');
    else if(getenv('HTTP_X_FORWARDED'))
        $ipaddress = getenv('HTTP_X_FORWARDED');
    else if(getenv('HTTP_FORWARDED_FOR'))
        $ipaddress = getenv('HTTP_FORWARDED_FOR');
    else if(getenv('HTTP_FORWARDED'))
       $ipaddress = getenv('HTTP_FORWARDED');
    else if(getenv('REMOTE_ADDR'))
        $ipaddress = getenv('REMOTE_ADDR');
    else
        $ipaddress = 'UNKNOWN';
    return $ipaddress;
}


//header("Content-type: text/xml; charset=windows-1251");
$server=$_GET['server'];
$key=$_GET['key'];
$value=$_GET['value'];
$zabbix_server_address="zabbix.domain.com";

if (empty($server)){
        echo "parametr SERVER is EMPTY";
        $ip_address=get_client_ip();
        $error_msg= date('Y-m-d H:i:s') . " - ZABBIX_SENDER[warning] - FROM: $ip_address; HTTP_PARAM: server=$server, key=$key, value=$value; ERROR: parametr SERVER is EMPTYn";
        error_log($error_msg,3,"/var/log/apache2/zabbix_sender.log");
        exit;
}

if (empty($key)){
        echo "parametr KEY is EMPTY";
        $ip_address=get_client_ip();
        $error_msg= date('Y-m-d H:i:s') . " - ZABBIX_SENDER[warning] - FROM: $ip_address; HTTP_PARAM: server=$server, key=$key, value=$value; ERROR: parametr KEY is EMPTYn";
        error_log($error_msg,3,"/var/log/apache2/zabbix_sender.log");
        exit;
}

if ($value==""){
        echo "parametr value is EMPTY";
        $ip_address=get_client_ip();
        $error_msg= date('Y-m-d H:i:s') . " - ZABBIX_SENDER[warning] - FROM: $ip_address; HTTP_PARAM: server=$server, key=$key, value=$value; ERROR: parametr VALUE is EMPTYn";
        error_log($error_msg,3,"/var/log/apache2/zabbix_sender.log");
        exit;
}

exec("/usr/local/bin/zabbix_sender -z $zabbix_server_address -p 10051 -s $server -k $key -o $value",$out, $err);
if ($err==0){
        echo "OK";
}
else {
        //print to html
        echo "ERROR:";
        echo "</br>";
        echo "server=$server, key=$key, value=$value";
        echo "</br>";
        var_dump($out);
        echo "</br>";
        var_dump($err);

        //Log error
        $ip_address=get_client_ip();
        $error_msg= date('Y-m-d H:i:s') . " - ZABBIX_SENDER[error] - FROM: $ip_address; HTTP_PARAM: server=$server, key=$key, value=$value; ERROR: zabbix_sender: $out[0]n";
        error_log($error_msg,3,"/var/log/apache2/zabbix_sender.log");

}

Чтобы отослать значение. вам достаточно написать в браузере (или в программе, которая умеет делать HTTP GET-запрос) запрос вида zabbix.domain.com/zabbix_sender/index.php?server=myhost&key=testitem&value=11. Где server — хост в заббиксе (регистрозависимое имя!), key/value — название и значение item.

Подробнее или для интересующихся

Функция get_client_ip берет IP-адрес клиента, который послал (будем писать в лог для дебага при ошибках).

Всего две возможные ошибки. Ошибка при выполнении zabbix_sender, пишем в лог (который находится в /var/www/apache2/zabbix_sender.log)

ZABBIX_SENDER[error] - FROM: $ip_address; HTTP_PARAM: server=$server, key=$key, value=$value; ERROR: zabbix_sender

Нет какого-либо GET-параметр

ZABBIX_SENDER[warning] - FROM: $ip_address; HTTP_PARAM: server=$server, key=$key, value=$value; ERROR: parametr KEY is EMPTY

Где $ip_address — с какого IP-адреса послали значение, остальные параметры думаю понятные.

Мониторим систему мониторинга

Смотреть на ошибки после того как мониторинг не сработал — плохо, поэтому мы будем мониторить мониторинг.
Для этого добавляем в zabbix_agentd.conf:

UserParameter=zabbix_sender_web_status_error, grep -q 'ZABBIX_SENDER[error]' /var/log/apache2/zabbix_sender.log; echo $?;
UserParameter=zabbix_sender_web_status_warning, grep -q 'ZABBIX_SENDER[warning]' /var/log/apache2/zabbix_sender.log; echo $?;

Перезапускаем агента. Чтобы логи очищались раз в день (и ошибка висела только один день), проверяем чтобы был файл /etc/logrotate.d/apache2 с содержанием:

/var/log/apache2/*.log {
        daily
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 644 www-data www-data
        sharedscripts
        postrotate
                /etc/init.d/apache2 reload > /dev/null
        endscript
}

В хосте Zabbix Server добавляем два item:

image
image

И два триггера:

zabbix_sender over HTTP - 3
zabbix_sender over HTTP - 4

Напоследок

Итого мы получили новое API для отсылки значений в Zabbix. Теперь даем ссылку программистам zabbix.domain.com/zabbix_sender/index.php?server=myhost&key=testitem&value=11, создаем нужные Шаблоны, привязываем к хостам… Ну и еще много чего делаем, но уже без zabbix_sender, а с модным web API. Программисты могут сами отслеживать успех или неудачу доставки, если все хорошо, то веб-сервер вернет страничку «OK», если нет — сообщит какого параметра нет. Ну если совсем тяжело, то Zabbix сам скажет что у него ошибка.

P.S. Хочу услышать конструктивную критику, возможно, даже есть похожие решения, но я их не нашел.

Автор: allburov

Источник

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


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