В этой статье я приведу возможное решение проблемы для многих системных администраторов, которые используют систему мониторинга Zabbix. Особенно пригодится для тех, кто осуществляет мониторинг разных программ в Zabbix: системы телефонии, разные регламентные операции с БД, 1С (да, да, такие вот мы извращенцы люди с нестандартным мышлением, что мониторим 1С в Zabbix). Сам мучался делая Powershell-скрипты, использую для отсылки zabbix_sender.exe. Страшные были времена.
Пользуюсь данной системой не первый год. В начале использовали для мониторинга доступности (ага, таким комбайном делали icmp-запросы и все). Сейчас используем почти весь функционал, карты, инвентаризацию, отчеты. С недавнего времени стали прикручивать мониторинг бэкапов (не только Linux-систем, но и разных Windows), мониторинг разных программ (кассовые программы в рознице), обменов, синхронизаций. И каждый раз приходилось писать скрипты, потому что многие программы не могли сами запускать zabbix_sender.exe с нужными параметрами (особенно касается 1С).Для мониторинга этих скриптов писались другие скрипты. Программа экспортирует что-то в файл, скрипт его парсит, отправляет все через zabbix_sender.
Каждый раз мне — как системному администратору — приходилось делать все скрипты. Программисты 1С же просто писали файлики, логика была вся на мне. Меня этокак и любого ленивого системного администратора не устраивало.
Я всегда негодовал (особенно в начале), почему нет веб-интерфейса для отправки значений в Zabbix? А теперь все проще — ну раз нет, так напишем!
Приступим! Создаем папку zabbix_sender на сервер zabbix (у меня папка /var/www/zabbix, не забываем про root-права):
Создаем файл index.php, содержание в
Чтобы отослать значение. вам достаточно написать в браузере (или в программе, которая умеет делать 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)
Нет какого-либо GET-параметр
Где $ip_address — с какого IP-адреса послали значение, остальные параметры думаю понятные.
Смотреть на ошибки после того как мониторинг не сработал — плохо, поэтому мы будем мониторить мониторинг.
Для этого добавляем в zabbix_agentd.conf:
Перезапускаем агента. Чтобы логи очищались раз в день (и ошибка висела только один день), проверяем чтобы был файл /etc/logrotate.d/apache2 с содержанием:
В хосте Zabbix Server добавляем два item:


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


Итого мы получили новое API для отсылки значений в Zabbix. Теперь даем ссылку программистам zabbix.domain.com/zabbix_sender/index.php?server=myhost&key=testitem&value=11, создаем нужные Шаблоны, привязываем к хостам… Ну и еще много чего делаем, но уже без zabbix_sender, а с модным web API. Программисты могут сами отслеживать успех или неудачу доставки, если все хорошо, то веб-сервер вернет страничку «OK», если нет — сообщит какого параметра нет. Ну если совсем тяжело, то Zabbix сам скажет что у него ошибка.
P.S. Хочу услышать конструктивную критику, возможно, даже есть похожие решения, но я их не нашел.
Как мы до этого дошли
Пользуюсь данной системой не первый год. В начале использовали для мониторинга доступности (ага, таким комбайном делали icmp-запросы и все). Сейчас используем почти весь функционал, карты, инвентаризацию, отчеты. С недавнего времени стали прикручивать мониторинг бэкапов (не только Linux-систем, но и разных Windows), мониторинг разных программ (кассовые программы в рознице), обменов, синхронизаций. И каждый раз приходилось писать скрипты, потому что многие программы не могли сами запускать zabbix_sender.exe с нужными параметрами (особенно касается 1С).
Каждый раз мне — как системному администратору — приходилось делать все скрипты. Программисты 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 EMPTY\n"; 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 EMPTY\n"; 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 EMPTY\n"; error_log($error_msg,3,"/var/log/apache2/zabbix_sender.log"); exit; } $exec_str="/usr/local/bin/zabbix_sender -z $zabbix_server_address -p 10051 -s ".escapeshellarg($server)." -k ". escapeshellarg($key)." -o ". escapeshellarg($value); exec($exec_str,$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:


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


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