1、关于codec
开始时Logstash是一个input | filter | output的数据流,只支持纯文本形式输入,然后再进入过滤器处理。但是logstash从1.3.0版开始引入Codec,因此logstash的就成了input | decode | filter | encode | output的数据流。通过codec,logstash就可以和其他自定义数据格式的运维产品集成,比如fluent、graphite等,以及使用json等通用数据格式的其他产品。
2、json codec插件
json插件主要用于解析json格式的数据,便于后续在kibana上分析各个字段,我们使用最简单的logstash来演示一下实际效果,
[root@centos7 conf.d]# cat test.conf
input {
file {
path => "/var/log/test.log"
start_position => "end"
}
}
output {
file {
path => "/my-test.log"
}
}
这是一个从本地文件输入,并输出到本地文件的配置。然后我们追加内容到/var/log/test.log中,
echo '{"name": "hello"}' >> /var/log/test.log
查看输出内容,
{"host":"0.0.0.0","message":"{\"name\": \"hello\"}","@version":"1","@timestamp":"2020-04-30T13:06:34.344Z","path":"/var/log/test.log"}
可见,我们追加的内容作为message的值,并输出该事件。
如果我们在input使用json是什么效果呢,
[root@centos7 conf.d]# cat test.conf
input {
file {
path => "/var/log/test.log"
start_position => "end"
codec => "json"
}
}
output {
file {
path => "/my-test.log"
}
}
这次增加codec配置,同时需要重启logstash进程以便加载最新配置,
systemctl restart logstash
此时同样追加内容到测试日志文件中,并查看此时的输出文件,
{"@timestamp":"2020-04-30T13:05:29.102Z","host":"0.0.0.0","@version":"1","path":"/var/log/test.log","name":"hello"}
可见,我们的输入被解析为json数据,相当于在日志时间中增加了对应的字段。
但是如果输入的内容不是json格式,则会增加一个_jsonparsefailure的tag字段,同时将输入内容存放到message字段中,如下,
{"@timestamp":"2020-04-30T13:12:45.616Z","@version":"1","host":"0.0.0.0","tags":["_jsonparsefailure"],"message":"{\"name\",\"hello\"}","path":"/var/log/test.log"}
3、multiline codec插件
从名字上我们也可以看出multiline适用于多行日志处理,合并多行日志为一个事件,比如堆栈信息。总的来说,multiline插件通过匹配特定模式,同时通过设置确定与前一行或者后一行合并。
比如我们要将以下日志合并成一个事件,也就是合并为一行,
Apr 30 10:19:37 centos7 kernel: e820: BIOS-provided physical RAM map:
Apr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
Apr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
Apr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
Apr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x0000000000100000-0x00000000bffdbfff] usable
Apr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x00000000bffdc000-0x00000000bfffffff] reserved
我们可以如下配置,
[root@centos7 conf.d]# cat multiline.conf
input {
file {
path => "/var/log/multiline.log"
start_position => "end"
codec => multiline {
pattern => "BIOS-e820: \["
what => "previous"
}
}
}
output {
file {
path => "/multiline.log"
}
}
其中,codec设置使用multiline插件,有点需要注意,这里不能带双引号,否则logstash识别不到该插件,日志中会有如下报错,
May 2 04:08:58 centos7 logstash: [2020-05-02T04:08:58,137][ERROR][logstash.plugins.registry] \
Tried to load a plugin's code, but failed. {:exception=>#<LoadError: no such file to load -- \
logstash/codecs/"multiline">, :path=>"logstash/codecs/\"multiline\"", :type=>"codec", :name=>"\"multiline\""}
multiline有以下选项,
-
pattern
用于指定具体匹配模式,可使用正则表达式设置规则 -
what
设置匹配的行合并到上一行或者下一行,previous表示合并到上一行,next表示合并到下一行
此外,还有一些常用选项,
-
nagate
指定我们需要操作的行是pattern匹配的行,还是未匹配的行,默认值为false,表示操作pattern匹配的行,如果设置为true,则表示操作未匹配的行 -
max_bytes
指定模式匹配中能存储的最大字节数,默认10M,如果该值过大容易造成OOM -
max_lines
和max_bytes类似,控制最大匹配行,默认500行
添加完logstash的配置文件后,我们同样需要重启下logstash进程,
systemctl restart logstash
然后将日志写入测试文件中,
[root@centos7 /]# cat a
Apr 30 10:19:37 centos7 kernel: e820: BIOS-provided physical RAM map:
Apr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
Apr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
Apr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
Apr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x0000000000100000-0x00000000bffdbfff] usable
Apr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x00000000bffdc000-0x00000000bfffffff] reserved
[root@centos7 /]# cat a >> /var/log/multiline.log
[root@centos7 /]# echo "the end" >> /var/log/multiline.log
[root@centos7 conf.d]# tail -f /multiline.log
{"@version":"1","path":"/var/log/multiline.log","@timestamp":"2020-05-02T10:00:29.286Z","host":"0.0.0.0","tags":["multiline"],"message":"Apr 30 10:19:37 centos7 kernel: e820: BIOS-provided physical RAM map:\nApr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable\nApr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved\nApr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved\nApr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x0000000000100000-0x00000000bffdbfff] usable\nApr 30 10:19:37 centos7 kernel: BIOS-e820: [mem 0x00000000bffdc000-0x00000000bfffffff] reserved"}
可见,日志全都合并到一行中,成为了一个事件。有一点要注意的是,如果只单纯追加日志到/var/log/multiline.log中,我们是没办法看到output中的输出的,只有在追加the end字符串后,output才会有输出。这是因为模式匹配还在工作,只有出现不匹配的行时,此次匹配才结束,因此需要输出一个不匹配的日志才能使该次匹配结束。