Grok无法正确匹配多行日志条目?求问题排查与解决方法
解决多行日志Grok匹配异常的问题
我来帮你排查一下问题,你遇到的情况主要是Filebeat多行配置错误加上Logstash Grok模式没有适配合并后的多行日志导致的,咱们一步步来解决:
1. 修复Filebeat的多行合并配置
你当前的multiline.pattern写错了,多了一个冒号,导致无法正确识别日志的起始行,进而多行合并失败,Logstash收到的还是零散的单行日志,这是核心问题之一。
把filebeat.yml里的多行配置改成这样:
multiline.pattern: ^[0-9]{2}:[0-9]{2}:[0-9]{2} multiline.negate: true multiline.match: after
multiline.pattern: ^[0-9]{2}:[0-9]{2}:[0-9]{2}:匹配以HH:mm:ss格式时间开头的行,作为一条日志的起始行negate: true:表示不匹配这个pattern的行(也就是那些不以时间开头的行)需要合并到上一行match: after:把这些非起始行追加到上一行的末尾,完成多行日志的合并
2. 调整Logstash的Grok模式
当Filebeat正确合并多行后,整个日志会作为一个完整的message字段传到Logstash。你原来的Grok模式只能匹配单行内容,而且没有处理换行,所以只会捕获最后一行。
需要给Grok模式加上(?s)修饰符(单行模式,让.可以匹配换行符),这样GREEDYDATA就能捕获所有后续的多行内容:
grok { match => [ "message" , "(?s)%{TIME:time}.*%{NUMBER:loglevel}:\s%{GREEDYDATA:message_processed}" ] }
3. 可选:将换行替换为空格(实现预期格式)
如果想把合并后日志里的换行换成空格,得到你想要的无换行格式,可以在Grok之后添加一个mutate过滤器:
mutate { gsub => [ "message_processed", "\n", " " ] }
为什么之前的(?m)无效?
你提到尝试过(?m)标记,它是多行模式,作用是让^和$匹配每行的开头/结尾,但你需要的是让.能匹配换行符,所以应该用单行模式(?s),这就是之前标记无效的原因。
按照上面的步骤调整后,就能得到你预期的message_processed内容了。
内容的提问来源于stack exchange,提问作者Atombob
相关产品推荐
相关产品推荐

