Kubernetes使用filebeat Multiline自定义收集日志

我们介绍了如何在 kubernetes 环境中使用 filebeat sidecar 方式收集日志

使用的是 filebeat 的 moudle 模块,但凡是常用的软件,基本都有对应的模块可用,所以我们首先应该使用模块来收集日志。

那对于一些我们自己写的 Go 软件呢,或者根本不是标准的,那该怎么办呢?

那就自定义 filebeat.inputs,网上的 filebeat 例子,其实大多都是这样的

很简单,给个例子

1[beat-logstash-some-name-832-2015.11.28] IndexNotFoundException[no such index]
2    at org.elasticsearch.cluster.metadata.(IndexNameExpressionResolver.java:566)
3    at org.elasticsearch.cluster.metadata.(IndexNameExpressionResolver.java:133)
4    at org.elasticsearch.cluster.metadata.(IndexNameExpressionResolver.java:77)
5    at org.elasticsearch.action.admin..checkBlock(TransportDeleteIndexAction.java:75)

看如上日志,如果不用模式匹配的话,那么会送5条记录到 ES, Kibana 看起来就十分割裂了。

所以要用正则把底下的4行和上面的第1行合在一起,合并成一条就记录推送到 ES 去

仔细观察,开头一行是以 [ 开始的,所以正则就是 ‘^\[',我们要匹配的是底下的4行,必须反转一下模式。

multiline 的 negate 属性,这个是指定是否反转匹配到的内容,这里如果是 true 的话,反转,那就是选择不以 [ 开头的行。 netgate 属性的缺省值是 false

multiline 的 match 属性,after 指追加到上一条事件(向上合并),before 指合并到下一条(向下合并)

于是,我们就可以写出以下的匹配模式,这样就把匹配到条目追加到上一条,合并在一起了:

 1filebeat.inputs:
 2  - type: log
 3    enabled: true
 4    paths:
 5      - /Users/liuxg/data/multiline/multiline.log
 6    multiline.type: pattern
 7    multiline.pattern: '^\['
 8    multiline.negate: true
 9    multiline.match: after
10
11output.elasticsearch:
12 hosts: ["localhost:9200"]
13 index: "multiline"
14

再给个例子,java 的 stack 调用,日志格式如下:

1Exception in thread "main" java.lang.NullPointerException
2        at com.example.myproject.Book.getTitle(Book.java:16)
3        at com.example.myproject.Author.getBookTitles(Author.java:25)
4        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)

分析一下:

  • 匹配到开头是空格的那些行,正则 ‘^[[:space]]’
  • 匹配的行不反转,就是要那些空格开头的行,所以 negate 是缺省的 false
  • 匹配的空格行追加到上一个事件,向上合并,所以 match 是 after
1filebeat.inputs:
2  - type: log
3    enabled: true
4    paths:
5      - /Users/liuxg/data/multiline/multiline.log
6    multiline.type: pattern
7    multiline.pattern: '^[[:space:]]'
8    multiline.negate: false
9    multiline.match: after

再给个例子,假如你在 Go 程序里定义了输出日志的格式,以 Start new event 开头,以 End event 结尾

1[2015-08-24 11:49:14,389] Start new event
2[2015-08-24 11:49:14,395] Content of processing something
3[2015-08-24 11:49:14,399] End event
4[2015-08-24 11:50:14,389] Some other log
5[2015-08-24 11:50:14,395] Some other log
6[2015-08-24 11:50:14,399] Some other log
7[2015-08-24 11:51:14,389] Start new event
8[2015-08-24 11:51:14,395] Content of processing something
9[2015-08-24 11:51:14,399] End event

我们就用到 filebeat multiline 的另一个开关,flush_pattern,来控制如何结束,注意 negate 是 true ,匹配到的是 Start 和 End 中间的部分:

 1multiline.type: pattern
 2multiline.pattern: 'Start new event'
 3multiline.negate: true
 4multiline.match: after
 5multiline.flush_pattern: 'End event'
 6
 7filebeat.inputs:
 8  - type: log
 9    enabled: true
10    paths:
11      - /Users/liuxg/data/multiline/multiline.log
12    multiline.type: pattern
13    multiline.pattern: 'Start new event'
14    multiline.negate: true
15    multiline.match: after
16    multiline.flush_pattern: 'End event'

给两篇参考,大家一定要先看那篇原版英文的,中文的那篇翻得不太好;最好两篇对照着看。

参考:


生产环境kubernetes使用持久化卷GlusterFS
Python的协程详细解释
comments powered by Disqus