前言

不管是PHP各种框架的日志
还是java的 Java Stack Traces
他们都是多行日志模式
这个时候如果使用
filebeat + elasticsearch + kibana 做日志的采集,存储,展示那么就需要用到
filebeat的 multiline 配置
一词日志是多行记录,其实这种多行的日志会有日志分段的分隔符
写出对于的分隔符正则即可解决filebeat采集一次日志记录为多行的情况

配置示例

例如我们有日志文件

/var/www/a.iamle.com/runtime/log/201904/01.log
/var/www/b.iamle.com/Application/Runtime/Logs/201904/02.log
/var/www/c.iamle.com/runtime/log/201905/03.log
/var/www/d.iamle.com/Application/Runtime/Logs/201906/04.log

分析日志后得出某一次日志通过什么标识作为分隔符

# 标识方式1 63个"-"作为分割符 正则为 ^\-{63}
# ...
---------------------------------------------------------------
2019-04-08T13:58:19+08:00 192.168.0.1 GET a.iamle.com/v1/1?type_id=1
[运行时间:0.582681s] [吞吐率:1.72req/s] [内存消耗:3,387.72kb] [文件加载:80]
[ err ] [ LANG ] /var/releases/balabala/20181227-101450/fw/lang/zh-cn.php
[ err ] [ ROUTE ] array (
  'rule' => 'v1',
  'route' => 'index/v1/1',
---------------------------------------------------------------
2019-04-08T13:58:19+08:00 192.168.0.1 GET b.iamle.com/v1/1?type_id=1
[运行时间:0.582681s] [吞吐率:1.72req/s] [内存消耗:3,387.72kb] [文件加载:80]
[ err ] [ LANG ] /var/releases/balabala/20181227-101450/fw/lang/zh-cn.php
[ err ] [ ROUTE ] array (
  'rule' => 'v1',
  'route' => 'index/v1/1',
---------------------------------------------------------------
# ...

# 标识方式2 "[ 2019 作为分隔符 正则为 ^\[\s{1}\d{4}
# ...

[ 2019-04-09T13:58:19+08:00 ] 192.168.0.1 GET a.iamle.com/v2
[运行时间:0.681s] [吞吐率:1.72req/s] [内存消耗:3,387.72kb] [文件加载:82]
[ err ] [ LANG ] /var/releases/balabala/20191227-101450/fw/lang/zh-cn.php
[ err ] [ ROUTE ] array (
  'rule' => 'v2',
  'route' => 'index/v2',

[ 2019-04-09T13:58:19+08:00 ] 192.168.0.1 GET b.iamle.com/v2/1
[运行时间:0.681s] [吞吐率:1.72req/s] [内存消耗:3,387.72kb] [文件加载:81]
[ err ] [ LANG ] /var/releases/balabala/20191227-101450/fw/lang/zh-cn.php
[ err ] [ ROUTE ] array (
  'rule' => 'v2',
  'route' => 'index/v2',
# ...

filebeat中配置文件
/etc/filebeat/filebeat.yml

# ...
- type: log
  enabled: true
  paths:
    - /var/www/*.iamle.com/runtime/log/*/*.log
    - /var/www/*.iamle.com/Application/Runtime/Logs/*/*.log
  # 正则需要支持2种不同的分隔符
  multiline.pattern: '^(\-{63}|\[\s{1}\d{4})'
  multiline.negate: true
  multiline.match: after

# ...
# 检查filebeat是否配置正确
 filebeat test config
# 重启filebeat
 systemctl restart filebeat

写正则的时候推荐用正则可视化工具检查正则
例如本文的正则

扩展

这种非自己能定义的日志,思路是寻找多行日志分段规律写出对于的正则即可
那么自己打日志的情况下,不太推荐这种多行日志了,采用结构化的json日志,一行一条是比较推荐的方式
这样在后期的处理分析中将会便利太多太多

参考

Filebeat Reference [7.0] » Configuring Filebeat » Manage multiline messages

1. 前言

filebeat 6.6.2 nginx module自定义字段
filebeat提供了多种Module预制模块,简化了各种日志的格式化
在nginx中默认的字段并不满足实际需求,例如我们需要记录额外的Nginx字段
例如 请求时间、后端响应时间、主机头等信息
那么在filebeat的nginx module中需要同步定义

2. rpm模式安装filebeat

curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.6.2-x86_64.rpm
sudo rpm -vi filebeat-6.6.2-x86_64.rpm

3. Nginx 自定义Log格式化

nginx原始log格式化定义:

        #log format
        log_format access '$remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '"$http_user_agent" "$http_x_forwarded_for" '

nginx自定义格式化log:

        #log format
        log_format access '$remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '"$http_user_agent" "$http_x_forwarded_for" '
                            '"$http_x_real_ip" "$server_addr" "$host" '
                            '$request_time $upstream_response_time "$upstream_addr" '
                            '"$time_iso8601"';

4. 启用filebeat的nginx module

执行

filebeat modules enable nginx

filebeat nginx module 增加字段
文件 /usr/share/filebeat/module/nginx/access/ingest/default.json 中
原始:

    "grok": {
      "field": "message",
      "patterns":[
        "\"?%{IP_LIST:nginx.access.remote_ip_list} - %{DATA:nginx.access.user_name} \\[%{HTTPDATE:nginx.access.time}\\] \"%{GREEDYDATA:nginx.access.info}\" %{NUMBER:nginx.access.response_code} %{NUMBER:nginx.access.body_sent.bytes} \"%{DATA:nginx.access.referrer}\" \"%{DATA:nginx.access.agent}\""
        ],
      "pattern_definitions": {
        "IP_LIST": "%{IP}(\"?,?\\s*%{IP})*"
      }

自定义修改:

    "grok": {
      "field": "message",
      "patterns":[
        "\"?%{IP_LIST:nginx.access.remote_ip_list} - %{DATA:nginx.access.user_name} \\[%{HTTPDATE:nginx.access.time}\\] \"%{GREEDYDATA:nginx.access.info}\" %{NUMBER:nginx.access.response_code} %{NUMBER:nginx.access.body_sent.bytes} \"%{DATA:nginx.access.referrer}\" \"%{DATA:nginx.access.agent}\" \"%{DATA:nginx.access.xff}\" \"%{DATA:nginx.access.x_real_ip}\" \"%{DATA:nginx.access.server_addr}\" \"%{DATA:nginx.access.host}\" %{DATA:nginx.access.request_time} %{DATA:nginx.access.upstream_response_time} \"%{DATA:nginx.access.upstream_addr}\" \"%{DATA:nginx.access.time_iso8601}\""
        ],
      "pattern_definitions": {
        "IP_LIST": "%{IP}(\"?,?\\s*%{IP})*"
      }

如果定制自己的字段
可以使用http://grokdebug.herokuapp.com/ 在线工具验证grok规则
可以使用Json工具处理转义问题

文件 /etc/filebeat/fields.yml 中
找到nginx字段配置

            - name: agent
              type: text
              description: >
                Contains the un-parsed user agent string. Only present if the user
                agent Elasticsearch plugin is not available or not used.

在后面增加

            - name: xff
              type: group
              description: >
                http_x_forwarded_for.
            - name: x_real_ip
              type: group
              description: >
                http_x_real_ip.
            - name: server_addr
              type: group
              description: >
                server_addr 服务器地址.
            - name: host
              type: group
              description: >
                host http_host http主机头.
            - name: request_time
              type: group
              description: >
                request_time 请求时间.
            - name: upstream_response_time
              type: group
              description: >
                upstream_response_time 后端响应时间.
            - name: upstream_addr
              type: group
              description: >
                upstream_addr 后端地址.
            - name: time_iso8601
              type: group
              description: >
                time_iso8601 iso8601格式时间.

5. Filebeta中 nginx 日志路径定义

在文件 /etc/filebeat/modules.d/nginx.yml 中修改日志路径

- module: nginx
  # Access logs
  access:
    enabled: true

    # Set custom paths for the log files. If left empty,
    # Filebeat will choose the paths depending on your OS.
    var.paths: ["/data/wwwlogs/*.log*"]

  # Error logs
  error:
    enabled: true

    # Set custom paths for the log files. If left empty,
    # Filebeat will choose the paths depending on your OS.
    var.paths: ["/usr/local/nginx/logs/error.log*"]

6. 扩展

6.1 解决增加字段后Kibana中不显示

  • 在Kibana的 Dev Tools中执行
DELETE _ingest/pipeline/filebeat-6.6.2-nginx-access-default
  • 字段出来以后有黄色小三角,刷新一下index 的字段缓存就好了
  • 重启下Filebeat
    方法来源