ELK logstash 处理多行事件(25th)

本文介绍如何使用Logstash的multilinecodec插件处理多行日志,包括配置示例和应用场景,如Java堆栈跟踪、C风格续行及基于时间戳的日志。

有些日志是分多行输出的,为了能正确的处理这些多行的事件,logstash必须哪些行是单一事件的一部分。多行事件处理是比较复杂的,需依赖正确的事件顺序。最佳方法是尽早的在管道中处理以保证日志有序。这就是本文要说到的logstash管道multiline codec,专门来处理合并多行事件的。

multiline插件最重要的方面:

  •  pattern 选项指定一个正则表达式。 事件匹配指定的正则表达式来确定是前一个事件的内容还是新的事件的内容。可以使用grok正则表达式的模板来配置该选项。
  •  what 选项有两个选择值:previous 或者 next。previous 值指定行匹配pattern选项的内容是上一行的一部分。 next 指定行匹配pattern选项的内容是下一行的一部分。* negate选项适用于 multiline codec 行不匹配pattern选项指定的正则表达式。

了解更多还需要看看multiline codec 和 multiline filter 插件的配置项。

下面介绍三个例子:

  • java 堆栈跟踪单个事件
  • C-style 线连续成单个事件
  • 从时间标记事件
java stack traces

Java stack traces  包含多行内容,后面几行与初始行缩进,如下所示:

Exception in thread "main" java.lang.NullPointerException
        at com.example.myproject.Book.getTitle(Book.java:16)
        at com.example.myproject.Author.getBookTitles(Author.java:25)
        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)
logstash配置如下:

input {
  stdin {
    codec => multiline {
      pattern => "^\s"
      what => "previous"
    }
  }
}
该配置将任何以空白开始的行与上一行合并。

输出的结果如下:

{
    "@timestamp" => "2015-12-11T07:32:20.872Z",
       "message" => "Exception in thread \"main\" java.lang.NullPointerException\n        at com.example.myproject.Book.getTitle(Book.java:16)\n        at com.example.myproject.Author.getBookTitles(Author.java:25)\n        at com.example.myproject.Bootstrap.main(Bootstrap.java:14)Settings: Default filter workers: 4",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "host" => "localhost"
}


line continuations

多种编程语言使用\字符在一行末尾表示该行继续,如:

printf ("%10.10ld  \t %10.10ld \t %s\
  %f", w, x, y, z );

logstash配置如下:

input {
  stdin {
    codec => multiline {
      pattern => "\\$"
      what => "next"
    }
  }
}
该配置将以\字符结尾的任何行合并到下一行。

输出的结果如下:

{
    "@timestamp" => "2015-12-11T07:46:02.116Z",
       "message" => "printf (\"%10.10ld  \\t %10.10ld \\t %s\\\n  %f\", w, x, y, z );",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "host" => "localhost"
}

timestamps

有些日志是以时间戳开始的,如:

[2015-08-24 11:49:14,389][INFO ][env                      ] [Letha] using [1] data paths, mounts [[/
(/dev/disk1)]], net usable_space [34.5gb], net total_space [118.9gb], types [hfs]

logstash配置如下:

input {
 stdin {
    codec => multiline {
      pattern => "^%{TIMESTAMP_ISO8601} "
      negate => true
      what => previous
    }
  }
}

该配置使用negate => true 选项来指定任何不是以时间戳开始的行属于前行。也就是不匹配pattern的行都属于前行的内容的一部分。

输出的结果如下:

{
    "@timestamp" => "2015-12-11T08:08:37.013Z",
       "message" => "[2015-08-24 11:49:14,389][INFO ][env                      ] [Letha] using [1] data paths, mounts [[/\n(/dev/disk1)]], net usable_space [34.5gb], net total_space [118.9gb], types [hfs]",
      "@version" => "1",
          "tags" => [
        [0] "multiline"
    ],
          "host" => "localhost"
}

后面看应用处理mysql慢查询日志。


### 如何设置ELK Stack中的Logstash #### 安装Java 由于Elasticsearch依赖于Java运环境,在安装Logstash之前,先要确保服务器上已经安装了合适的Java版本。通常建议安装最新稳定版的OpenJDK或Oracle JDK。 对于CentOS 7而言,可以通过以下命令来完成Java 8的安装[^3]: ```bash sudo yum install java-1.8.0-openjdk-devel ``` #### 下载并安装Logstash 官方推荐的方式是从Elastic官网下载对应的RPM包或者使用yum仓库来进自动化部署。这里给出基于yum源的方法: 更新yum库索引,并添加Elastic官方yum存储库: ```bash rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch cat << EOF | sudo tee /etc/yum.repos.d/logstash.repo [logstash-7.x] name=Elastic repository for 7.x packages baseurl=https://artifacts.elastic.co/packages/7.x/yum gpgcheck=1 gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch enabled=1 autorefresh=1 type=rpm-md EOF ``` 接着执如下指令以安装指定版本(此处假设为7.x系列)的Logstash软件包: ```bash sudo yum install logstash ``` #### 配置Logstash输入插件 编辑位于`/etc/logstash/conf.d/`目录下的配置文件,定义日志收集方式。例如创建名为`01-input.conf`的新文件用于监听TCP端口上的syslog消息: ```ruby input { tcp { port => 5000 type => syslog } } ``` #### 处理与过滤数据管道 继续在同一路径下建立另一个配置片段如`10-filter.conf`, 添加必要的filter规则以便清洗和转换接收到的数据流。下面的例子展示了怎样利用grok解析器拆分Apache访问记录字段: ```ruby filter { grok { match => { "message" => "%{COMBINEDAPACHELOG}" } } } ``` #### 输出到Elasticsearch或其他目的地 最后一步是决定经过处理后的事件应该送往哪里保存。同样地,在相同位置新建一个叫做`30-output.conf` 的文档,指明目标地址以及可能存在的其他参数设定。比如向本地ES集群推送JSON格式的结果集: ```ruby output { elasticsearch { hosts => ["localhost:9200"] index => "apache-access-%{+YYYY.MM.dd}" } } ``` 启动服务并将它设成开机自启项: ```bash sudo systemctl start logstash.service sudo systemctl enable logstash.service ``` 验证整个流程是否正常工作,可通过发送测试请求至先前声明过的tcp接口处观察响应情况;也可以登录Kibana界面查看是否有新的条目被成功录入数据库内。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值