在实际使用中会使用logstath来采集日志文件,基础的采集是按单行来进行的每一行都是一个event,而在实际工作中经常会出现一个日志event分布在多行中,比如java的错误堆栈,必须将多行日志联合起来进行分析。
下面先介绍下我在工作中遇到的情形:
2017-08-02 10:42:21,176 INFO smg.message.cdnws||||cd /data/Video && rsync -avrtuz -R ./2017/08/02/5901193475b440cf2ed0a2ec26116cdb.mp4.m3u8 chinacache@rsync4.upload.wscdns.com::chinacache_video --password-file=/etc/rsync_ws.passwd||||{"command":"[/usr/local/microservice/rsyncCommand.sh, cd /data/Video, rsync -avrtuz -R ./2017/08/02/5901193475b440cf2ed0a2ec26116cdb.mp4.m3u8 chinacache@rsync4.upload.wscdns.com::chinacache_video --password-file=/etc/rsync_ws.passwd]", "errorMessage":"null", "infoMessage":"
sending incremental file list
2017/08/02/5901193475b440cf2ed0a2ec26116cdb.mp4.m3u8
sent 279 bytes received 30 bytes 88.29 bytes/sec
total size is 108 speedup is 0.35
", "exitValue":"0", "startTime":"1501641738840", "endTime":"1501641741176"}
这个多行日志是需要采集的目标。结构应该是 时间 + 日志级别 + 具体内容。
下面先介绍用到的插件:
input file 及codec multiline 插件
使用这两个插件可以坐到从日志文件中读取多行日志进行匹配,比如java的报错堆栈会解析成一个结构。
file插件官网地址
codec multiline插件官网地址
首先先使用input file插件将日志读进来。
./bin/logstash -e '
input{
file{
path=>"/home/testfiles/command_service_amq.log" //日志文件地址
start_position=>"beginning" //在第一次读文件时是否从第一行进行读取 默认为end
}
}
output{stdout{}}'
这样读进来的日志会按照单行进行采集,效果非常不好,所以开始使用multiline插件。
通过分析发现多行的匹配规则为只要不是以时间为开头的日志都归为上一行。so!!!这么写:
./bin/logstash -e '
input{
file{
path=>"/home/testfiles/command_service_amq.log" //日志文件地址
start_position=>"beginning" //在第一次读文件时是否从第一行进行读取 默认为end
codec => multiline {
pattern => "^%{TIMESTAMP_ISO8601:timestamp}" //正则匹配,以iso8601时间为开始
negate => true //如果没匹配则取消正则,没理解,反正true跟false都试试
what => "previous" //和上一行组成同一event
}
}
}
output{stdout{}}'
pattern中使用grok正则进行匹配。
参考地址在这。
现在会发现多行会变成一个event输出了,但是其中会出现冗余信息,比如logstath会在event中添加时间信息。
下一节讲讲如何进行filter过滤,有问题之处烦请在留言中指出,非常感谢。