LINUX.ORG.RU

RSYSLOG regexp

 , ,


0

1

Добрый день, коллеги. Всех с наступающим праздником ДСА2018!!!

Помогите распарсить строку штатными стредствами regexp в rsyslog. Есть логи маршрутизатора которые валятся на rsyslog вот примерно такого вида: BLOCKSMKNETS forward: in:ether6 - Local TORF out:VLAN55 RT_INET, src-mac 5c:9a:d8:65:99:b7, proto TCP (SYN), 192.168.0.141:62632->192.168.6.18:65535, len 52

Средствами логгера надо отделить зерна от плевел и положить в БД. Например из части «in:ether6» надо убрать «in:», с помощью конструкции:

(?<=(in:))[a-x0-9]+

Тут получилось https://regex101.com/r/aznNLN/1

А тут не получается https://www.rsyslog.com/regex/

К сожалению на последнем сервисе нет возможности сохраниться поэтому покажу часть конфига rsyslog: $template msgmake3,"msgmake3 %timereported:::date-mysql% %msg:R,ERE,0,BLANK:(?<=(in:))[a-x0-9]+--end%\n" ... :msg, contains, "BLOCKSMKNETS" /var/log/remote/smtp.log;msgmake3 На выходе получаем: msgmake3 20180726163813 **NO MATCH** **BAD REGULAR EXPRESSION**

В чем может быть дело? кто еще страдает такой фигней, как разбор логов на лету?

Lookaround не работает

Обратил внимание что при добавлении regexp конструкций типа Lookbehind, начинают валится **BAD REGULAR EXPRESSION**. Может есть другие варианты фильтрации?

sergio_sd ()
Ответ на: комментарий от anonymous

Да, там используется реализация POSIX (ERE, BRE), например, из glibc https://github.com/rsyslog/rsyslog/blob/master/runtime/regexp.c

pcre filtering пока значится в rsyslog в Upcoming Features. https://www.rsyslog.com/doc/features.html

А вообще регекспы — не самый быстрый способ парсить логи. Много записей идет в секунду/минуту?

Pravorskyi ★★ ()
Ответ на: комментарий от Pravorskyi

А вообще регекспы — не самый быстрый способ парсить логи.

Простые (настоящие) регулярные выражения, которые компилятся в конечные автоматы - быстрые.

Много записей идет в секунду/минуту?

Не ко мне вопрос.

anonymous ()
Ответ на: комментарий от Pravorskyi

Да, похоже так. Только тут дело даже не в rsyslog получается, GNU ERE не поддерживает эти функции.

Вот тут табличка есть. https://www.regular-expressions.info/refadv.html

Сколько записей в секунду не могу сказать, пока не известно сколько будет источников и какие именно логи буду собирать(пока планирую отлупы на фаерволе mikrotik и на некоторые TCP SYNы ), но думаю со временем потребности выростут.

На прежнем работе я собирал логи с маршуртизаторов zyxel, далее обрабатывал perl`овым скриптом текстовые логи и бухал это все в БД раз в 1 минуту по крону. Опять же не замерял сколько там было, так примерно база данных на года выросла до 19гб включая индексы. И это при том что zyxel информацию по оконченным соединениям, то есть не по каждому пакету а по завершении сеанса.

sergio_sd ()

rsyslog не поддерживает pcre, как уже написали, а ERE и BRE довольно ограничены и, честно говоря, после использования regexp в правилах rsyslog эти правила становятся малочитаемы.

Делаем проще. На любом знакомом языке программирования ищешь простейшую реализацию syslog сервера - на python она довольно простая. И уже внутри него обрабатываешь входящие строки как хочешь - хоть regexp, хоть ручной построчный пасринг, результат записываешь в нужный файл либо уже обработанный снова отсылаешь в rsyslog (который сам запишет). Запускаешь его демоном на соседнем порту, а в rsyslog добавляешь правило с action(type=«omfwd» target=«127.0.0.1» port="..." protocol=«udp»).

pod ★★ ()
Ответ на: комментарий от pod

Спасибо за рекомендаю, но это сложное решение...для меня. Нет опыта такого.

Что если допиливать под конкретный тип данных уже в БД, например с помощью триггеров SQL? то есть первую подготовку текста выполняет rsyslog с помощью regexp, далее SQL.

Что более затратно для ресурсов системы?

Еще как вариант перенаправлять строку rsyslog`ом в egrep например, а далее вывод обратно в rsyslog через | logger, а уж потом в БД без всякой доработки :) изврат?

sergio_sd ()

В общем получилось отделить все кроме портов от адреса вот такая строка шаблона вышла:

$template msgmake2,"msgmake2 %timereported:::date-mysql%
%msg:F,32:2% %msg:F,32,4:4,12% %msg:F,32,5:7,12% 
%msg:R,ERE,0,DFLT,0:([0-9]+\.){3}[0-9]+[:]?([0-9]+)?--end%
%msg:R,ERE,0,DFLT,1:([0-9]+\.){3}[0-9]+[:]?([0-9]+)?--end%
%msg:R,ERE,0,DFLT:([0-f]+:){5}[0-f]+--end%
%msg:R,ERE,0,DFLT:\b[A-X]{3,4}\b--end% 
%msg:R,ERE,0,DFLT:[a-x]+--end% \n"

На выходе получаем:

msgmake2 20180727172335 BLOCKSMKNETS ether6 VLAN55 192.168.0.234:3990 192.168.6.11:65535 00:15:17:31:b8:d7 TCP forward
msgmake2 20180727172338 BLOCKSMKNETS ether6 VLAN55 192.168.0.176 192.168.6.16 1c:1b:0d:2c:0f:21 ICMP forward

Далее попробую триггером SQL отделить IP:PORT.

sergio_sd ()