Местонахождение устройства в панели проблем Zabbix 3.4

На стартовой странице веб-интерфейса Zabbix по умолчанию отображается список актуальных проблем. Самая важная информация в этом списке - это время начала проблемы, узел сети, срабтавший триггер и длительность проблемы, но нет никакой информации о местоположении устройства. Если у вас небольшая сеть, расположенная не более чем по нескольким десяткам адресов, то хорошая система именования устройств может решить проблему поиска местонахождения устройства. Если же количество адресов, по которым находятся устройства, достигает нескольких тысяч, то правильное именование устройств становится трудной задачей.

В Zabbix'е к каждому устройству можно прикрепить так называемые «инвентарные данные», среди которых есть поле адреса. Было бы неплохо показывать это поле в списке проблем, чтобы можно было без лишних телодвижений определить адрес устройства. К сожалению, Zabbix не предоставляет для этого штатных средств. Но к счастью, это можно сделать, внеся в исходный текст веб-интерфейса Zabbix небольшую правку.

Интересующий нас виджет находится в файле frontends/php/app/views/monitoring.widget.problems.view.php

Этот виджет фигурирует в списке маршрутов в файле frontends/php/include/classes/mvc/CRouter.php:

'widget.problems.view'  => ['CControllerWidgetProblemsView',    'layout.widget',                'monitoring.widget.problems.view'],

Класс CControllerWidgetProblemsView описан в файле frontends/php/app/controllers/CControllerWidgetProblemsView.php. Именно в этом классе готовятся данные, которые потом будут использованы в виджете для отображения. Данные об узлах, связанных с триггерами, в этом классе формируется при помощи функции getTriggersHostsList.

Определение функции getTriggersHostsList находится в файле frontends/php/include/triggers.inc.php, для получения списка узлов с триггерами используется метод API host.get:

$db_hosts = $hostids
    ? API::Host()->get([
        'output' => ['hostid', 'name', 'status', 'maintenanceid', 'maintenance_status', 'maintenance_type'],
        'selectGraphs' => API_OUTPUT_COUNT,
        'selectScreens' => API_OUTPUT_COUNT,
        'hostids' => array_keys($hostids),
        'preservekeys' => true
    ])
    : [];

Внесём правку, которая добавит в этот список строку местоположения устройства из его инвентарных данных:

Index: zabbix-3.4.12-1+buster/frontends/php/include/triggers.inc.php
===================================================================
--- zabbix-3.4.12-1+buster.orig/frontends/php/include/triggers.inc.php
+++ zabbix-3.4.12-1+buster/frontends/php/include/triggers.inc.php
@@ -2170,6 +2170,7 @@ function getTriggersHostsList(array $tri
                        'output' => ['hostid', 'name', 'status', 'maintenanceid', 'maintenance_status', 'maintenance_type'],
                        'selectGraphs' => API_OUTPUT_COUNT,
                        'selectScreens' => API_OUTPUT_COUNT,
+                       'selectInventory' => ['location'],
                        'hostids' => array_keys($hostids),
                        'preservekeys' => true
                ])

Теперь эти данные нужно отобразить в виджете. Внесём соответствующую правку в файл frontends/php/app/views/monitoring.widget.problems.view.php:

Index: zabbix-3.4.12-1+buster/frontends/php/app/views/monitoring.widget.problems.view.php
===================================================================
--- zabbix-3.4.12-1+buster.orig/frontends/php/app/views/monitoring.widget.problems.view.php
+++ zabbix-3.4.12-1+buster/frontends/php/app/views/monitoring.widget.problems.view.php
@@ -54,6 +54,7 @@ $table = (new CTableInfo())
                $show_recovery_data ? _('Status') : null,
                _('Info'),
                ($data['sortfield'] === 'host') ? [_('Host'), $sort_div] : _('Host'),
+               ($data['sortfield'] === 'location') ? [_('Location'), $sort_div] : _('Location'),
                [
                        ($data['sortfield'] === 'problem') ? [_('Problem'), $sort_div] : _('Problem'),
                        ' • ',
@@ -198,11 +199,19 @@ foreach ($data['data']['problems'] as $e
                ];
        }
 
+       $trigger_hosts = array_values($data['data']['triggers_hosts'][$trigger['triggerid']]);
+       $locations = array();
+       foreach($trigger_hosts as $host)
+       {
+               $locations[] = $host['inventory']['location'];
+       }
+
        $table->addRow(array_merge($row, [
                $show_recovery_data ? $cell_r_clock : null,
                $show_recovery_data ? $cell_status : null,
                makeInformationList($info_icons),
                $triggers_hosts[$trigger['triggerid']],
+               join(', ', $locations),
                $description,
                (new CCol(
                        ($problem['r_eventid'] != 0)

Как видно, в правке:

  1. в таблицу был добавлен заголовок новой колонки Location,
  2. по каждому из триггеров формируется строка со списком адресов узлов, на значения элементов данных из которых опирается этот триггер,
  3. строки с адресами через запятую с пробелом склеиваются в одну строку,
  4. полученная строка добавляется в строку таблицы, в колонку Location.

Готовую заплатку можно взять по ссылке zabbix3_4_12_frontend_location.patch.

Написать автору