В этой статье я приведу возможное решение проблемы для многих системных администраторов, которые используют систему мониторинга Zabbix. Особенно пригодится для тех, кто осуществляет мониторинг разных программ в Zabbix: системы телефонии, разные регламентные операции с БД, 1С (да, да, такие вот мы извращенцы люди с нестандартным
Как мы до этого дошли
Пользуюсь данной системой не первый год. В начале использовали для мониторинга доступности (ага, таким комбайном делали icmp-запросы и все). Сейчас используем почти весь функционал, карты, инвентаризацию, отчеты. С недавнего времени стали прикручивать мониторинг бэкапов (не только Linux-систем, но и разных Windows), мониторинг разных программ (кассовые программы в рознице), обменов, синхронизаций. И каждый раз приходилось писать скрипты, потому что многие программы не могли сами запускать zabbix_sender.exe с нужными параметрами (особенно касается 1С). Для мониторинга этих скриптов писались другие скрипты. Программа экспортирует что-то в файл, скрипт его парсит, отправляет все через zabbix_sender.
Каждый раз мне — как системному администратору — приходилось делать все скрипты. Программисты 1С же просто писали файлики, логика была вся на мне. Меня это как и любого ленивого системного администратора не устраивало.
Я всегда негодовал (особенно в начале), почему нет веб-интерфейса для отправки значений в Zabbix? А теперь все проще — ну раз нет, так напишем!
Реализация
Приступим! Создаем папку 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:
И два триггера:
Напоследок
Итого мы получили новое API для отсылки значений в Zabbix. Теперь даем ссылку программистам zabbix.domain.com/zabbix_sender/index.php?server=myhost&key=testitem&value=11, создаем нужные Шаблоны, привязываем к хостам… Ну и еще много чего делаем, но уже без zabbix_sender, а с модным web API. Программисты могут сами отслеживать успех или неудачу доставки, если все хорошо, то веб-сервер вернет страничку «OK», если нет — сообщит какого параметра нет. Ну если совсем тяжело, то Zabbix сам скажет что у него ошибка.
P.S. Хочу услышать конструктивную критику, возможно, даже есть похожие решения, но я их не нашел.
Автор: allburov