Инструменты пользователя

Инструменты сайта


raspberry_pi:pi_4_model_b:raspberry_pi_os:librenms:configuration:alerts:extended_icmp_monitoring

Расширенный ICMP-мониторинг в LibreNMS

В правилах LibreNMS нельзя штатными средствами запросить весь список устройств при срабатывании тревоги на одном из них, а это очень удобно для оперативного получения диагностической информации, особенно, при мониторинге Wi-Fi-устройств, т.к. зачастую, недоступными они становятся во время «шторма»1).

Задача

Нужно научить LibreNMS не только выбирать устройство, инициализировавшее тревогу, но и выбирать все устройства из той же группы вне зависимости от их статуса2). А при отсутствии таких устройств, должен возвращаться пустой ответ3).

Реализация

Если кратко резюмировать все нижеприведенные этапы, то все сводится к главному – написать собственный запрос к базе данных, который будет учитывать мои потребности. Благо в LibreNMS это возможно без танцев с бубном! Но, по порядку.

Устройства

Предполагается, что LibreNMS уже установлена и в нее добавлено некоторое количество устройств, для которых указано, как минимум, «Hostname / IP» и «Display Name».

Группа

Т.к. под мониторинг у меня попадают все устройства в LibreNMS, за исключением «устройств» для проверки доступности Интернета, логично, создать динамическую группу, откуда исключить последние.

Для этого создаем группу через «Devices» → «Manage Groups» → «New Device Group», где в качестве критерия выбираем «device_groups.id», «not equal» и, в моем случае, «9»4).

Правило

Добавляем новое правило через «Alerts» → «Alert Rules» → «Create new alert rule».

На закладке «Main» ничего интересного нет. Единственное, на что нужно обратить внимание, параметр «Delay», который, при использовании «быстрой проверки», нужно установить в «90s»5), дабы устранить подавляющее большинство ложных срабатываний – крайне актуально при мониторинге Wi-Fi-сети, особенно 4G (2.4Ghz) в загруженных локациях.

На закладке «Advanced», включаем «Override SQL» и добавляем следующий запрос:

SELECT * FROM devices WHERE devices.device_id IN ( SELECT device_group_device.device_id FROM device_group_device WHERE device_group_device.device_group_id = 10 ) AND EXISTS ( SELECT devices.status FROM devices WHERE devices.device_id = ? AND devices.status = 0 ) AND ( devices.disabled = 0 && devices.ignore = 0 ) = 1 ORDER BY devices.status ASC, devices.last_ping_timetaken DESC

Разбор

Вот код в более читабельном виде.

SELECT *
FROM
         devices
WHERE #5
         devices.device_id IN #6
         (
                SELECT #3
                       device_group_device.device_id
                FROM
                       device_group_device
                WHERE
                       device_group_device.device_group_id = 10 #2
         )
         AND EXISTS #1
         (
                SELECT
                       devices.status
                FROM
                       devices
                WHERE
                       devices.device_id  = ? #4
                       AND devices.status = 0
         )
         AND
         (
                  devices.disabled = 0 && devices.ignore = 0 #7
         )
         = 1
ORDER BY #8
         devices.status ASC,
         devices.last_ping_timetaken DESC
;
  1. Проверяем статус устройства (#1), инициализировавшего тревогу – «EXISTS», это основополагающее место запроса, позволяющее одновременно, и проверить статус, и, далее, выбрать все устройства из группы или вовсе вернуть пустой ответ;
  2. выбираем «id» (#3) всех устройств из созданной ранее группы, куда входят все локальные устройства;
  3. выбираем (#5) устройства, где все 3 условия для отбора истинны – устройства должны входить в определенную группу (#6), одно из этих устройств должно быть со статусом «0» (#1) и устройства не должны быть отключены (#7);
  4. далее сортируем (#8) устройства, чтобы время ответа на «ping» было по убыванию, а устройства со статусом «0», т.е. не отвечающие, были в начале списка.

:!: Номер группы (#2) нужно указать вручную, т.к. метода автоматического извлечения этой информации я пока не придумал6).

:!: Обратите внимание на заполнитель «?» (#4) – он обязателен, без него не будет работать правило! И он должен быть только один, иначе в отладке будет ошибка «SQLSTATE[HY093]: Invalid parameter number»!

Отладка

Для отладки запроса нужно открыть консоль MySQL mysql -u root -p, если надо, узнать название базы SHOW DATABASES; и подключиться к базе use librenms. Просмотр существующих таблиц – SHOW TABLES;.

Если что-то не работает, то нужно зайти в одно из устройств, нажать на троеточие справа и выбрать «Capture», затем перейти на закладку «Poller» или «Alerts», нажать «Run» и изучать… LOL

Шаблон

Теперь осталось только создать шаблон, перейдя в «Alerts» → «Alert Templates» и нажав «Create new alert template». После чего, назначить его созданному ранее правилу, выбрав в «Attach template to rules».

Template

The device "{{ $alert -> display }}" ({{ $alert -> hostname }}, id: {{ $alert -> device_id }}) is {{ $alert -> state ? 'DOWN' : 'UP' }} from {{ $alert -> timestamp }}! <br><br>
 
@if ( $alert -> state == 0 )Approx. time elapsed: {{ $alert -> elapsed }}. <br><br>
@endif
 
@if ( $alert -> faults )Diagnostic information (ping in ms (last ping/poll, m ago): <br><br>
 
@foreach ( $alert -> faults as $key => $value )
@if ( $key < 10 )0{{ $key }}@else{{ $key }}@endif) [{{ $value[ 'status' ] == 0 ? 'DN' : 'UP' }}] {{ $value[ 'display' ] }} - {{ $value[ 'last_ping_timetaken' ] == '0.00' ? '∞' : $value[ 'last_ping_timetaken' ] }} ({{ round( ( ( time() - strtotime( $value[ 'last_ping' ] ) ) / 60 ), 0 ) }}/{{ round( ( ( time() - strtotime( $value[ 'last_polled' ] ) ) / 60 ), 0 ) }}) <br>
@endforeach @endif
<br>
Rule: @if ( $alert -> name ){{ $alert -> name }}@else{{ $alert -> rule }}@endif () (id: {{ $alert -> rule_id }}, severity: {{ $alert -> severity }}). <br><br>
 
Unique-ID: {{ $alert -> uid }}.

:!: Обратите внимание на пустые скобки «()» после «@endif» – они нужны, чтобы операторы не «съедали» то, что дальше. Так же нужно делать и с «@else»…

Alert title

{{ $alert -> name }} [{{ strtoupper( $alert -> severity ) }}]

Recovery title

{{ $alert -> name }} [OK]

Тестирование

Для тестирования шаблона и просмотра доступных значений и их заполнителей, нужно авторизоваться под пользователем «librenms»

sudo su - librenms

и выполнить команду

./scripts/test-template.php -t X -d -h HOST -r Y

где «X», это номер шаблона, а «Y» – номер правила. Обе цифры можно посмотреть в первой колонке соответствующего списка – списка шаблонов или списка правил. Естественно, «HOST» должен соответствовать значению, указанному в поле «Hostname or IP» соответствующего устройства.


Дисклеймер

  • Использование материалов данной базы знаний разрешено на условиях лицензии, указанной внизу каждой страницы! При использовании материалов активная гиперссылка на соответствующую страницу данной базы знаний обязательна!
  • Автор не несет и не может нести какую либо ответственность за последствия использования материалов, размещенных в данной базе знаний. Все материалы предоставляются по принципу «как есть». Используйте их исключительно на свой страх и риск.
  • Все высказывания, мысли или идеи автора, размещенные в материалах данной базе знаний, являются исключительно его личным субъективным мнением и могут не совпадать с мнением читателей!
  • При размещении ссылок в данной базе знаний на интернет-страницы третьих лиц автор не несет ответственности за их техническую функциональность (особенно отсутствие вирусов) и содержание! При обнаружении таких ссылок, можно и желательно сообщить о них в комментариях к соответствующей статье.
1)
Этим грешат сети 4G (2.4GHz) в многоквартирных домах и больших офисных зданиях, т.к. частот мало, а устройств и помех дико много.
2)
Кроме отключенных и игнорируемых, естественно.
3)
Не уверен, что это обязательно, не проверял, но по умолчанию запросы на доступность устройств в правилах именно такие.
4)
«id» группы можно узнать в адресной строке, открыв нужную группу.
5)
Ну, а при стандартной проверке с частотой 5 минут – «330s».
6)
Основная проблема заключается в том, что устройства могут быть в нескольких группах одновременно…

Обсуждение

Ваш комментарий:
Q᠎ X J N I᠎ X V A Y N F L Y S᠎ J O
 
Последнее изменение: 2023/04/02 12:37 — Николай Солошин