我有一个 csv 格式的 syslog 源,它由 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'