О проблемах отправки XMPP сообщений из Zabbix слагают легенды ещё с давних времён.
Однажды и меня посетила мысль об отправке jabber-уведомлений из Zabbix.
В статье хотелось бы рассмотреть костыльный и очень костыльный способы реализации данной функциональности.
Традиционно, пользователи Zabbix решали эту проблему используя сторонний alert скрипт.
Этот способ я отношу к очень костыльному, но всё же приведу свой скрипт для отправки уведомлений.
Думаю, что оправданность способа избегает сомнений только в случае, когда требуется расширенный функционал, например когда параметры Jabber сервера хочется динамически брать из базы данных или внести немного экзотики в процесс отправки уведомлений.
Для написания скрипта был расчехлён и заряжен perl.
На том сервере уже давненько не обновлялось ПО, поэтому сначала мне пришлось собрать для perl более свежую версию SSL:
cpan install IO::Socket::SSL
И затем установить модуль работы с Jabber -- Net::XMPP:
cpan install Net::XMPP
И, собственно, сам скрипт:
#!/usr/local/bin/perl -W
use strict;
use utf8;
use Net::XMPP;
exit 2 if@ARGV!=3;
my%h;@h{qw(to subject body)}=@ARGV;
map{utf8::decode($h{$_})}('subject','body');
my$j=new Net::XMPP::Client();
$j->SetCallBacks('onauth',sub{$j->PresenceSend;$j->MessageSend(%h);
$j->Disconnect();}); $j->Execute(
hostname => 'zhmylove.ru',
port => 5222,
tls => 0,
username => 'username',
password => 'password',
resource => 'perl',
);
В конце скрипта необходимо задать параметры подключения к Jabber серверу - имя хоста, порт, использование TLS, имя пользователя, пароль и ресурс.
Далее кладём скрипт в правильное место и разрешаем ему чтение/выполнение. Обращаю внимание, что в скрипте в открытом виде указан пароль от учётной записи, поэтому с правами надо быть аккуратнее:
vi /usr/local/etc/zabbix24/zabbix/alertscripts/xmpp.pl
chown zabbix:zabbix /usr/local/etc/zabbix24/zabbix/alertscripts/xmpp.pl
chmod 700 /usr/local/etc/zabbix24/zabbix/alertscripts/xmpp.pl
Отлично, теперь идём в веб-морду Zabbix.
Administration -> Media types -> Create media type
Name: XMPP
Type: Script
Script: xmpp.pl
И далее как обычно настраиваем уведомления для пользователей используя новый media type, не забывая попутно добавить соответствующие контакты пользователям.
Подробно описывать процесс не стану, он интуитивно понятен.
Лишь намекну, что первое делается в Configuration -> Actions, а второе в Administration -> Users.
Супер, ну а теперь приведу решение, которое мне кажется более элегантным.
Дело в том, что в Zabbix уже есть поддержка Jabber "искаропки".
Однако, как я писал ранее, пользователи этого поделия действительно слагают легенды о его невозможности отправлять сообщения.
Небольшой дебаг, который я провёл в ходе попыток решения этой проблемы показал, что между Zabbix и libiksemel возникает некоторое недопонимание на стадии подключения к серверу, если сервер не отвечает мгновенно. Поэтому некоторые пользователи сделали предположение, что Jabber в Zabbix работает только если сервер установлен на той же системе, что и Zabbix. В моём случае, сервер работает на той же системе, но несколько задумчив, поэтому само оно, как ожидалось, не заработало.
В итоге, изыскания, чтение скудной документации на libiksemel и банальный дебаг привели к написанию небольшого патча:
diff -ruN zabbix-2.4.6.orig/src/libs/zbxmedia/jabber.c zabbix-2.4.6/src/libs/zbxmedia/jabber.c
--- zabbix-2.4.6.orig/src/libs/zbxmedia/jabber.c 2015-11-07 15:55:17.457772547 +0300
+++ zabbix-2.4.6/src/libs/zbxmedia/jabber.c 2015-11-07 15:57:02.966764520 +0300
@@ -526,8 +526,12 @@
break;
}
- if (0 == --timeout)
+ if (0 == --timeout) {
+ if (JABBER_AUTHORIZED == jsess->status)
+ jsess->status = JABBER_READY;
+
break;
+ }
}
После пересборки zabbix24 с изменённой библиотекой работы с Jabber, встроенный media type работает исправно.
Настройка интуитивно понятна, см. намёк выше.
Засим, пожалуй, всё.