Продолжим разбираться с mattermost в части интеграции с внешними сервисами.


Часть вторая. Интеграция с Zabbix


Во второй части повествования о интеграции mattermost, речь пойдет про отправку сообщений об авариях из zabbix в mattermost. В результате поисков в сети был взят за основу вот
этот скрипт. Код написан на Perl, поэтому может потребоваться доустановка перловых-пакетов. Прежде чем приступить к описанию кода (он несколько изменён по сравнению с исходным) сперва, как водится, произведём некоторые настройки.


Mattermost


Для использования механизма приёма сообщений от сторонних сервисов, требуется добавить запись входящих "хуков". Идём в настройки "Integrations"->"Incoming webhooks" и добавляем запись:


image


После, скопируем подчёркнутую ссылку для вставки в скрипт.


image


Zabbix


В интерфейсе управления zabbix через меню "Администрирование"->"Способы оповещения" добавим новый способ оповещения:


image


Где в параметрах скрипта следует указать:


  1. {ALERT.SENDTO}
  2. Ссылку на mattermost вэбхук (которую скопировали ранее)
  3. Имя пользователя в mattermost от которого будут приходить сообщения
  4. Ссылка на аватарку (файл должен быть доступен по http)
  5. {ALERT.MESSAGE}

Затем, в настройках пользователя, добавим новый способ оповещения:


image


Где в поле "Отправить на" надо указать название канала в mattermost, куда будут сыпаться сообщения, в нашем случае это "it" (стоит заметить, что используется системное название канала). Это значение будет подставлено вместо макроса {ALERT.SENDTO}, который фигурирует в параметрах вновь созданного способа оповещения. {ALERT.MESSAGE} — это, собственно, будет само сообщение.


Исходный скрипт подвергся некоторым изменениям, это связано с тем, что используемая версия zabbix сообщение отдаёт не в json (может быть это где-то настраивается). Потому код пришлось поменять. Код снабжён комментариями и сложностей в понимании вызвать не должен.
На сервере, где установлен Zabbix, создаём файл /usr/lib/zabbix/alertscripts/zabbixMatterBot.pl (у меня Debian и zabbix установлен из официального репозитория) следующего содержания:


 #!/usr/bin/perl
 # https://github.com/drewbeer/zabbix-mattermost-alertscript DrewBeer
 # passes data in and curls it out via json to mattermost webhooks as attachments.
 # you can use this as you wish, free as in beer, life is that way.
 # minify your json before you set it in zabbix, it will make your life easier

 use warnings;
 use strict;
 use JSON;
 use Data::Dumper;

 # включаем режим отладки, /tmp/zabbix-mattermost.log
 my $debug = 0;
 my $logFH;
 my $zabbixData = ();

 # debug log the incoming data
 if ($debug) {
   open($logFH, '>>', '/var/log/zabbix/zabbix-mattermost.log');
   my $dump = Dumper(@ARGV);
   print $logFH "args:\n$dump\n";
 }

 # получаем данные с zabbix
 # соответственно - название канала, ссылку на mattermost, имя бота,
 # сылку на иконку, и сообщение
 my ($channel, $hook, $botName, $iconUrl, $body) = @ARGV;

 $zabbixData = $body;

 # создаем сообщение
 my $payload;

 $payload = processInternal($zabbixData);

 # Отладка
 if ($debug) {
   print $logFH "final payload: $payload\n";
 }

 # отправляем сообщение
 if ($payload) {
   sendPayload($payload);
 }
 exit;

 # процедура отправки сообщения
 # используется curl
 sub sendPayload {
   my($payload) = @_;
   my $cmd = qq( curl -s -i -X POST --data-urlencode '$payload' $hook > /dev/null);
   if ($debug) {
     $cmd = qq( curl -i -X POST --data-urlencode '$payload' $hook );
   }
   my $cmdOutput = `$cmd`;

   # final debug
   if ($debug) {
     print $logFH "curl:\n$cmd \n$cmdOutput\n";
   }
 }
 # разбираем сообщение от zabbix
 # и подготавливаем json-ответ
 sub processInternal {
   my $data = shift;
   my $attach = ();

   # заполняем требуемые поля
   $attach->{'channel'} = $channel;
   $attach->{'username'} = $botName;
   $attach->{'icon_url'} = $iconUrl;
   $attach->{'response_type'} = 'comment';
   $attach->{'text'} = $data;

   if ($debug) {
     my $body = Dumper $attach;
     print $logFH "object:\n$body\n";
   }
   my $jsonBody = encode_json $attach;

   # экранируем все кавычки
   my $jsonPayload = qq(payload=$jsonBody);
   # возвращаем готовый ответ
   return $jsonPayload;
 }

Теперь либо ждём срабатывание триггера, либо моделируем аварию в zabbix и получаем сообщение


image


Вот и вся интеграция.

Комментарии (11)


  1. denaspireone
    05.03.2019 08:53

    А картинку каждый раз слать обязательно?


    1. svk28 Автор
      05.03.2019 08:58

      В каком смысле?


      1. denaspireone
        05.03.2019 09:01

        hsto.org/getpro/habr/post_images/09f/026/6ea/09f0266ea72089784ac0e304db4bd91b.png

        Предпоследний параметр — вы передаете ссылку на картинку в Mattermost или шлете её?


        1. svk28 Автор
          05.03.2019 09:05

          Ссылку


  1. DRVTiny
    05.03.2019 11:06
    -1

    Для Perl есть десятки http-клиентов превосходного качества, а вы зачем-то команду curl зовёте. Понимаю, что код не Ваш, но я бы этот момент 100% просто сходу переписал (ну и, честно говоря, ещё и весь остальной код тоже).
    А за статью спасибо!


  1. divanikus
    05.03.2019 14:04

    Более наглядно и симпатично будет смотреться, если добавите аттачу цвет (поле color) в зависимости от серьезности проблемы, например что-то такое (ruby)

    color = case severity
    when /Information/
      "#7499FF"
    when /Warning/
      "#FFC859"
    when /Average/
      "#FFA059"
    when /High/
      "#E97659"
    when /Disaster/
      "#E45959"
    else
      "#97AAB3"
    end
    
    if status == "OK"
      color = "good"
    end
    


    1. svk28 Автор
      05.03.2019 14:40

      Это было в первой версии скрипта. Но толком не работало в части именно маттермоста, потому выкинул из кода, а разбираться дальше было некогда.


      1. divanikus
        05.03.2019 15:48

        Ну не знаю, у меня работает норм. Хоть с Mattermost, хоть со Slack


        1. svk28 Автор
          05.03.2019 16:10

          А можно увидеть запрос целиком? В каком виде отдается маттермосту?


          1. divanikus
            05.03.2019 17:28

            {
              "icon_url": "<zabbix_icon_url>",
              "attachments": [{
                "color": "#FFA059",
                "author_name": "<hostname>",
                "author_link": "<zabbix_url>history.php?action=showgraph&itemids[]=<itemid>",
                "title": "PROMBLEM: <trigger_name>",
                "text": "*Severity*: Average",
                "fields": [{
                    "title": "Metric",
                    "value": "<metric_name>",
                    "short": true
                 }, {
                    "title": "Value",
                    "value": "<metric_value>",
                    "short": true
                 }]
              }],
              "channel": "<alert_channel>",
              "username": "Zabbix"
            }
            


            Однако когда алертов много, задалбываешься их листать. Сейчас пытаюсь сделать группировку алертов в сообщении, если интересно, может выложу потом на гитхаб.


            1. svk28 Автор
              05.03.2019 18:38

              Спасибо, попробую.