Filebeat 采集日志实践经验记录

2020-10-22 0 By admin

Filebeat 日志采集工具在日常工作中,使用场景更多的是用来采集Nginx 日志和Java 应用运行的日志了。这里简单记录一下踩到坑,和大家分享。

一、Filebeat 收集Nginx 访问日志

Nginx 服务记录的日志,默认都是每行一条单独的日志;所以每条日志的分割很容易处理。
为了避免在日志中字段分割浪费精力,我们可以在Nginx的配置文件中,使用log_format 指令,将日志记录为Json格式。这样的话使用Filebeat服务的配置文件中json指令,很简单就可以完成字段的分割。

1.1、Nginx 服务日志中文乱码

这里和大家分享的是Nginx 服务日志中的中文乱码的处理方式。
nginx 服务日志记录中,最常见出现乱码的字段有:url和request_url。当这两个字段中出现中文内容时,默认日志中会记录乱码。

  1. url:请求中的当前URI(不带请求参数,参数位于$args)。
  2. request_url:这个变量等于包含一些客户端请求参数的原始URI。

1.2、消除Nginx 日志中部分乱码

  1. url:会对中文进行转为16进制。
  2. request_url:浏览器中会对中文进行百分号编码;这里记录的内容就是百分号编码后的内容。

只需要在定义log_format 时;设置escape属性,设置其值为json就可以消除 url 中的中文乱码。另外也可以解决日志字段中不能转化为Json字段的特殊符号。

For json escaping, all characters not allowed in JSON strings will be escaped: characters “"” and “\” are escaped as “\"” and “\\”, characters with values less than 32 are escaped as “\n”, “\r”, “\t”, “\b”, “\f”, or “\u00XX”.

1.3、Filebeat 消除中文百分号编码乱码

Filebeat 日志收集工具提供了 urldecode 模块扩展,可以将百分号编码的中文还原。配置案例:

processors:
    - urldecode:
        fields:
          - from: "json.request"
            to: "json.new_request"
          - from: "json.referer"
            to: "json.new_referer"
    - drop_fields:
        fields: ["json.referer","json.request"]

二、Java 程序中的多行日志

在Java 程序运行过程中,如果发生异常,则会记录多行的异常信息日志;在收集日志过程中需要考虑到对于应用中异常堆栈日志的处理。
此时有两种方案,一种是在采集是归并,一种是 Logstash 过滤时归并,更建议在客户端 agent 上直接实现堆栈的合并,把合并操作的压力在输入源头上进行控制。
filebeat 合并行的思路有两种,正向和逆向处理。
由于 filebeat 在合并行的时候需要设置 negate 和 match 来决定合并动作,意义混淆,简直是一种糟糕的设计,直接附上配置源码和说明便于理解。

2.1、符合条件才合并

容易有漏网之鱼说明:将以空格开头的所有行合并到上一行;并把以Caused by开头的也追加到上一行

multiline: 
  pattern: '^[[:space:]]+(at|\.{3})\b|^Caused by:'
  negate:  false
  match:   after

negate 参数为 false,表示“否定参数=false”。multiline 多行参数负负得正,表示符合 pattern、match 条件的行会融入多行之中、成为一条完整日志的中间部分。如果match=after,则以b开头的和前面一行将合并成一条完整日志;如果 match=before,则以 b 开头的和后面一行将合并成一条完整日志。

2.2、不符合条件通通合并

需事先约定 说明:约定一行完整的日志开头必须是以“[”开始,不符合则归并。

multiline:
  pattern: '^\['
  negate:  true
  match:   after

negate 参数为 true,表示“否定参数=true”。multiline 多行参数为负,表示符合 match 条件的行是多行的开头,是一条完整日志的开始或结尾。如果 match=after,则以 b 开头的行是一条完整日志的开始,它和后面多个不以 b 开头的行组成一条完整日志;如果 match=before,则以 b 开头的行是一条完整日志的结束,和前面多个不以 b 开头的合并成一条完整日志。