多行日志合并问题
先来描述下碰到的问题哈:
从服务日志来看,由于 打印的时候,日志会有换行的情况,那么filebeat会把一行一行的日志写入到kafka中,这样的话,有换行的日志就没办法连在一起,对查找日志来说不方便。
而且,由于logstash中我们设置了过滤规则,因此匹配不到规则的 一行日志就会被忽略到,导致日志显示不全
INFO20221117.112041.606341 TID:d0ca49fe66297bc6 [middlewares/http_logger.go/Mylogger line:41] Start Request proto=HTTP/1.1|method=POST|ip=172.16.2.28|uri=/recommma/v1/triggering|queryString=|header=map[Accept:[*/*] Accept-Encoding:[gzip, deflate, br] Connection:[keep-alive] Content-Length:[110] Content-Type:[application/json] Postman-Token:[43420baad5f4df] User-Agent:[PostmanRuntime/7.29.2]]|body= {^M
"productId": 521,^M
"entityTyp": 1,^M
"engineId": "zzz-33334",^M
"uids": ["12","13","14"]^M
}
再描述下 我们这边ELK架构:
解决的话,2个方式:
方法1:修改filebeat配置
需要修改filebeat.yml 配置,具体的配置应该是 你配置的每个输入,
举例:
- type: filestream
id: recommend-manage
paths:
- /usr/local/code/recommend-manage/logs/*
rotation.external.strategy.copytruncate:
suffix_regex: \.\d{8}$
dateformat: -20060102
fields:
service_name: recommend-manage
parsers:
- multiline:
type: pattern
pattern: '[\S]*.*([0-9]{8}\.[0-9]{6}\.*[0-9]{0,6})+.*'
negate: true
match: after
parsers:
- multiline:
type: pattern 使用正则表达式
pattern: ‘[\S].([0-9]{8}.[0-9]{6}.[0-9]{0,6})+.’ 正则表达式规则(根据需要自己修改)
negate: true 匹配正则表达式
match: after 把下一行不符合匹配规则的内容进行合并
还有些 其他参数,可以参考官方文档
优点: 从日志源头就合并好了数据,这样无论是 filebeat 增加字段,或者 logstash中过滤规则,都不会对此造成影响
缺点: 每个input 日志都需要单独配置(目前我还没有找到可以全局配置的)
参考:
- https://www.elastic.co/guide/en/beats/filebeat/8.5/filebeat-input-filestream.html#filebeat-input-filestream-common-options
方法2:修改logstash配置
需要修改logstash配置文件
举例:
filter {
......
multiline {
pattern => "[\S]*.*([0-9]{8}\.[0-9]{6}\.*[0-9]{0,6})+.* " ## 匹配一定包含有日期格式的内容
negate => true ## 正则匹配成功
what => "previous" ## 对下一个匹配出现前的内容进行合并
}
}
优点:: 只需要在logstash配置1处就行,方便
缺点:: 一但filebeat上报日志时,增加了特殊字段,那么这里合并时,也会把内容都写进去,无法过滤掉filebeat中增加的字段内容
参考:
- https://www.codenong.com/cs106014866/
- https://blog.51cto.com/morrowind/2115129
- https://www.elastic.co/guide/en/logstash/7.15/plugins-codecs-multiline.html