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

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


raspberry_pi:pi_4_model_b:raspberry_pi_os:syslog-ng:mikrotik:librenms

Сбор логов MikroTik для LibreNMS с syslog-ng

По умолчанию, логи MikroTik передаются в LibreNMS не совсем корректно:

  • во-первых, и в основных, отсутствует «Program»1), хотя в логах самого MikroTik'а название службы указывается в первой позиции массива топиков;
  • во-вторых, не корректно2) работает парсинг его сообщений, т.е. разбор строк, что, в свою очередь, сдвигает строки и получается белиберда.

Поэтому я решил заморочиться и научить syslog-ng правильно разбирать эти сообщения.

Используемые версии

  • RouterOS 6.49.2;
  • Raspberry Pi OS 11 (bullseye):
    • syslog-ng 3.28.1;
    • LibreNMS 23.2.0.

Логи MikroTik в LibreNMS

Связанные статьи

При отсутствии желания, или при отсутствии LibreNMS, или в каком еще случае, логи MikroTik можно собирать и просматривать гораздо проще, используя только syslog-ng и LogAnalyzer:

Ну, а для гурманов, вэлком ниже! LOL

Настройка MikroTik

Главное на MikroTik'е в «System» → «Logging»:

  1. на закладке «Actions» нужно отключить или не включать отправку сообщений в стиле «BSD Syslog»;
  2. на закладке «Rules» для всех правил логирования, пересылающих сообщения, указать префикс «mk_log»!

Все остальное вопросов вызывать не должно.

syslog.rsc
/system logging action
add name=Syslog remote=192.168.0.5 target=remote
/system logging
add action=Syslog prefix=mk_log topics=info
add action=Syslog prefix=mk_log topics=critical
add action=Syslog prefix=mk_log topics=error
add action=Syslog prefix=mk_log topics=warning

Конфигурация syslog-ng

Для начала, нужно открыть пустой файл конфигурации

sudo nano /etc/syslog-ng/conf.d/librenms.conf

и добавить следующую конфигурацию3), сохранить и закрыть

librenms.conf
# Written by Nikolay Soloshin (nikolay@soloshin.su) for syslog-ng 3.28.1 on Raspberry Pi OS 11 (bullseye) @ 2023.03
 
#Options
options {
  create-dirs( yes );
};
 
#Sources
source s_my_udp {
  network(
    transport( udp )
    flags( no-parse )
  );
};
 
#Filters
filter f_my_mikrotik {
  message( "mk_log" ) and
  match( '(\w*)\,([\w,]+)\s([\w:.-]*)\s(.*)'
    type( pcre )
    flags( store-matches )
    value( "MESSAGE" )
  );
};
 
#Rewriters
rewrite r_my_mikrotik {
  set( "6", value( "t_severity" ) condition( match( "info", value( "2" ) ) ) );
  set( "4", value( "t_severity" ) condition( match( "warning", value( "2" ) ) ) );
  set( "3", value( "t_severity" ) condition( match( "error", value( "2" ) ) ) );
  set( "2", value( "t_severity" ) condition( match( "critical", value( "2" ) ) ) );
  set-severity( "${t_severity}" );
  set( "${1}", value( "PROGRAM" ) );
  set( "${4}", value( "MESSAGE" ) );
};
 
#Templates
template t_my_librenms {
  template( "$HOST||$FACILITY||$PRIORITY||$LEVEL||$TAG||$R_YEAR-$R_MONTH-$R_DAY $R_HOUR:$R_MIN:$R_SEC||$MSG||$PROGRAM\n" );
  template-escape( yes );
};
 
#Destanations
destination d_my_librenms {
  program( "/opt/librenms/syslog.php"
    template( t_my_librenms )
  );
#  file( "/var/log/syslog-ng/debug.log" 
#    template( t_my_librenms )
#  );
};
destination d_my_general {
  file( "/var/log/syslog-ng/remote.log" );
};
 
#Log paths
log {
  source( s_my_udp );
  junction {
    channel {
      filter( f_my_mikrotik ); 
      rewrite{
        set-facility( "22" );
      };
      rewrite( r_my_mikrotik );
      destination( d_my_librenms );
      flags( final );
    };
    channel {
      parser {
        syslog-parser();
      };
      destination( d_my_general );
      flags( final );
    };
  };
};
 
# With love from Vladivostok.

В конце нужно перечитать конфигурацию

syslog-ng-ctl reload

Если появились какие-то ошибки, то тут описаны методы их обнаружения.

Комментарии

И так, краткие комментарии к конфигурации выше.

#Options

В этом блоке, в принципе, и так все понятно.

#Source

В блоке источников он только один на порту 514/UDP и поднят флаг «no-parse», запрещающий автоматический анализ поступающих сообщений.

#Filters

В этом блоке мы отлавливаем сообщения, в которых содержится метка «mk_log» и заодно разбираем входящее сообщение по группам, используя выражение ReEx. Т.к. поднят флаг «store-matches» все захваченные группы сохраняются и далее доступны по ${0} и ${1}…${255}, как и любой другой макрос. Протестировать использованное выражение можно здесь.

#Rewriters

Собственно, самое сердце этой затеи. Здесь мы ищем переданный MikroTik'ом, в виде топика, уровень («Level», «Severity») – «Info», «Warning», «Error» или «Critical» – и, заменяя его на цифровое значение, сохраняем во временной переменной «t_severity», а потом уже переносим в системный макрос, используя функцию «set-severity()».

:!: Но тут у меня возник некий диссонанс – вообще, «Priority» = «Facility» * 8 + «Severity», но почему-то syslog-ng отдает ${LEVEL}4) и ${PRIORITY}, как одно и то же! А в LibreNMS фильтрация возможна только по столбцу «Priority», поэтому выводить реальный «Priority» в виде цифр, к примеру, «172» (21*8+4), идиотизму подобно… Поэтому в интерфейсе LibreNMS всегда «Level» == «Priority».

Далее, исправляем значения макросов «${PROGRAM}» и «${MESSAGE}», на захваченные ранее.

#Templates

Шаблон стандартный, рекомендованный авторами LibreNMS.

#Destanations

Направлений два – одно, для тех сообщений, которые содержат метку «mk_log», через специальный скрипт в LibreNMS, а второе, для всех остальных сообщений, в файл.

#Log paths

Ну, и на последок, собираем все вышеописанное вместе.

Тут два канала в «junction»5). По одному каналу, обрабатываются сообщения от MikroTik'а, а по второму – все остальные.

В первом канале:

  1. используется фильтр «f_my_mikrotik»;
  2. устанавливается произвольный «facility»6);
  3. выполняется правило перезаписи «r_my_mikrotik»;
  4. устанавливается направление;
  5. флагом «final» завершается обработка.

Во втором канале:

  1. используется стандартный парсер;
  2. устанавливается направление.

Вообще, «junction» в данном контексте использовать бессмысленно, т.к. не используется его функционал, позволяющий временно разделить поток сообщений, по разному их обработать и свести опять в один. Можно было ограничиться просто двумя «channel» – кажется, так то же бы работало. Но сделал так, на будущее.


Дисклеймер

  • Использование материалов данной базы знаний разрешено на условиях лицензии, указанной внизу каждой страницы! При использовании материалов активная гиперссылка на соответствующую страницу данной базы знаний обязательна!
  • Автор не несет и не может нести какую либо ответственность за последствия использования материалов, размещенных в данной базе знаний. Все материалы предоставляются по принципу «как есть». Используйте их исключительно на свой страх и риск.
  • Все высказывания, мысли или идеи автора, размещенные в материалах данной базе знаний, являются исключительно его личным субъективным мнением и могут не совпадать с мнением читателей!
  • При размещении ссылок в данной базе знаний на интернет-страницы третьих лиц автор не несет ответственности за их техническую функциональность (особенно отсутствие вирусов) и содержание! При обнаружении таких ссылок, можно и желательно сообщить о них в комментариях к соответствующей статье.
1)
Который хочется использовать для фильтрации в LibreNMS, т.к. функционал там не богатый…
2)
Точнее «не всегда», что зависит от настроек в самом MikroTik'е.
3)
См. комментарии ниже.
4)
Хотя должно подразумеваться ${SEVERITY}… или как?!
5)
Не уверен, как правильно перевести смысл… «узел»… может «соединение» точнее?.. или как-то еще…
6)
Т.к. MirtoTik в этой конфигурации его сам не передает.

Обсуждение

Ваш комментарий:
D M X S W E K᠎ V G​ P B Y X T E T
 
Последнее изменение: 2023/03/22 10:54 — Николай Солошин