У меня есть лента syslog в формате csv, которую syslog-ng принимает с помощью csv-parser и записывает на диск.
Насколько я понимаю, использование csv-parser должно давать syslog-ng контекст входящих данных и то, какое значение что означает. Я хотел бы использовать этот контекст, чтобы заставить syslog-ng применять фильтры на основе этой логики.
Например, я бы хотел, чтобы событие регистрировалось на диске только в том случае, если один из столбцов CSV соответствует определенному значению.
Csv-парсердокументациякажется, это предполагает, что это возможно.
Моя конфигурация выглядит примерно так:
parser p_my_app {
csv-parser(
columns("MY_APP.COLOUR","MY_APP.SIZE","MY_APP.SERIAL_NUMBER")
delimiters(",")
flags(escape-double-char)
);
};
source s_my_app {
syslog(ip(0.0.0.0) port(6514)
transport("tcp")
);
};
filter f_my_app {
match("123456" value("MY_APP.SERIAL_NUMBER") );
};
destination d_my_app {
file("/var/log/my_app.log"
create_dirs(yes)
);
};
log {
source(s_my_app);
filter(f_my_app);
parser(p_my_app);
destination(d_my_app);
};
Однако, похоже, что как бы я ни старался, совпадений не происходит. Вот отладочный вывод sylog-ng с этой конфигурацией:
Incoming log entry; line='<14>1 2017-01-18T17:46:38+11:00 hostname - - - red,large,123456
'
Filter rule evaluation begins; rule='f_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:16:18'
Filter node evaluation result; result='not-match'
Filter rule evaluation result; result='not-match', rule='f_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:16:18'
Я (надеюсь?) упускаю что-то действительно очевидное, но я не могу найти никаких полных примеров в сети после нескольких часов гугления, только выдержки, которые, похоже, никогда не работают. Может ли кто-нибудь увидеть, что я делаю неправильно и/или предоставить полный рабочий пример?
решение1
Ну, как это всегда бывает, я трачу неделю на решение проблемы, сдаюсь, решаю обратиться за помощью, а затем через час сам нахожу решение.
Моя проблема была в порядке пунктов в log()
заявлении. В частности, parser()
строкаДОЛЖЕНбыть до filter()
заявления.
Действительно,документация(который я, должно быть, прочитал раз 10 и пропустил) гласит, что:
Примечание Порядок фильтров, правил перезаписи и парсеров в операторе журнала важен, поскольку они обрабатываются последовательно.
Итак, рабочий код будет использовать:
log {
source(s_my_app);
parser(p_my_app);
filter(f_my_app);
destination(d_my_app);
};
Также следует отметить еще один момент: match()
на самом деле это должно быть регулярное выражение, поэтому для большей ясности я также обновил фильтр следующим образом:
filter f_my_app {
match("123456" value("MY_APP.SERIAL_NUMBER") type("string"));
};
Теперь syslog-ng сообщает:
Incoming log entry; line='<14>1 2017-01-18T17:46:38+11:00 hostname - - - red,large,123456
'
Message parsing complete; result='1', rule='p_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:14:2'
Filter rule evaluation begins; rule='f_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:16:18'
Filter node evaluation result; result='match'
Filter rule evaluation result; result='match', rule='f_my_app', location='/etc/syslog-ng/conf.d/my-app.conf:16:18'