Docker环境下syslog-ng多行日志转单行配置求助
syslog-ng多行日志合并为单行配置求助
问题描述
我在Docker容器中运行syslog-ng,当前收到的日志以多行形式呈现,需求是将这些多行日志合并为单行后交由telegraf解析,但无法配置出正确的多行转单行规则,特此求助。
日志示例
- Oct 25 13:00:00 10.249.27.20 CISE_Passed_Authentications 0027652254 3 0 2022-10-25 13:00:00.256 -03:00 2811881475 5203 NOTICE Device-Administration: Session Authorization succeeded, ConfigVersionId=761, Device IP Address=10.100.150.161,Step=22037, ... Oct 25 13:00:00 10.249.27.20 CISE_Passed_Authentications 0027652254 3 1 Step=15036, Step=15048, Step=15048, Step=15048, Step=15048, Step=15017, Step=22081, Step=22080, Step=13034, SelectedAuthenticationIdentityStores=Internal Users, AuthenticationStatus=AuthenticationPassed, .... Oct 25 13:00:00 10.249.27.20 CISE_Passed_Authentications 0027652254 3 2 Location=Location#All Locations, Device Type=Device Type#All Device Types, IPSEC=IPSEC#Is IPSEC Device,... Oct 25 13:00:00 10.249.27.20 CISE_Passed_Authentications 0027652255 3 0 2022-10-25 13:00:00.261 -03:00 2811881488 5202 NOTICE Device-Administration: Command Authorization succeeded, ....
当前配置代码
目标端配置(d_file)
destination d_file { file( "/var/log/syslog_${HOST}_${YEAR}_${MONTH}_${DAY}_${HOUR}.log" owner("50000") group("root") perm(0777) ); };
数据源配置(s_test_multiline)
source s_test_multiline { file("/var/log/tmp/logs.log" multi-line-mode(regexp) multi-line-prefix("[0-9]{10} \d{1} \d \d{4}-\d{2}-\d{2}\s*?") flags(no-parse)); };
测试目标端配置(d_test_multiline)
destination d_test_multiline { file("/var/log/tmp/logs_tacacs.log" owner("50000") group("root") perm(0777) template("${MESSAGE}\n") flags(no-multi-line) #template("${LEGACY_MSGHDR} ${MESSAGE}\n") ); };
解决方案
核心问题是multi-line-prefix的正则表达式完全不匹配日志的起始行格式,导致syslog-ng无法识别新日志条目和续行的边界。
1. 修正数据源的多行匹配规则
根据日志特征,同一条日志的多行共享唯一ID,且起始行序号为0(格式为3 0)。将起始行的正则作为multi-line-prefix,让syslog-ng识别这类行是新日志的开始,后续行自动合并:
source s_test_multiline { file("/var/log/tmp/logs.log" multi-line-mode(regexp) # 匹配以月份缩写开头、包含序号0的起始行 multi-line-prefix("^[A-Z][a-z]{2} \d{1,2} \d{2}:\d{2}:\d{2} \d+\.\d+\.\d+\.\d+ \w+ \d+ \d+ 0 ") flags(no-parse) ); };
如果需要更精准匹配,也可以用包含日志核心标识的正则:
multi-line-prefix("^[A-Z][a-z]{2} \d{1,2} \d{2}:\d{2}:\d{2} \d+\.\d+\.\d+\.\d+ \w+ \d+ \d+ \d+ \d{4}-\d{2}-\d{2}.*NOTICE Device-Administration:")
2. 调整目标端模板,确保单行输出
在d_test_multiline中,用模板替换换行符为空格,确保合并后的日志是单行:
destination d_test_multiline { file("/var/log/tmp/logs_tacacs.log" owner("50000") group("root") perm(0777) # 替换换行符为空格,合并为单行 template("${replace(MESSAGE, '\n', ' ')}\n") flags(no-multi-line) ); };
3. 验证配置
修改配置后,在Docker容器内执行syslog-ng -s重载配置,查看输出文件/var/log/tmp/logs_tacacs.log,确认多行日志已合并为单行。
内容的提问来源于stack exchange,提问作者Jonathan Stampella
相关产品推荐
相关产品推荐

