管理多行事件

编辑

有些用例会生成跨越多行文本的事件。为了正确处理这些多行事件,Logstash 需要知道如何判断哪些行属于单个事件。

多行事件处理很复杂,并且依赖于正确的事件排序。保证日志处理顺序的最佳方法是在管道中尽早实现处理。

multiline 编解码器是在 Logstash 管道中处理多行事件的首选工具。多行编解码器使用一组简单的规则合并来自单个输入的行。

如果您使用的是支持多个主机的 Logstash 输入插件,例如 beats 输入插件,则不应使用 multiline 编解码器来处理多行事件。这样做可能会导致流的混合和损坏的事件数据。在这种情况下,您需要在将事件数据发送到 Logstash 之前处理多行事件。

配置多行编解码器最重要的方面如下:

  • pattern 选项指定一个正则表达式。与指定的正则表达式匹配的行被认为是前一行的延续,或者是一个新的多行事件的开始。 您可以将 grok 正则表达式模板与此配置选项一起使用。
  • what 选项接受两个值:previousnextprevious 值指定与 pattern 选项中的值匹配的行是前一行的一部分。next 值指定与 pattern 选项中的值匹配的行是下一行的一部分。 negate 选项将多行编解码器应用于与 pattern 选项中指定的正则表达式匹配的行。

有关配置选项的更多信息,请参阅 multiline 编解码器插件的完整文档。

多行编解码器配置示例

编辑

本节中的示例涵盖以下用例:

  • 将 Java 堆栈跟踪合并到单个事件中
  • 将 C 风格的行延续合并到单个事件中
  • 合并来自带时间戳的事件的多行

Java 堆栈跟踪

编辑

Java 堆栈跟踪由多行组成,初始行之后的每一行都以空格开头,如以下示例所示:

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"
    }
  }
}

此配置将任何以空格开头的行合并到上一行。

行延续

编辑

一些编程语言使用行末的 \ 字符来表示该行是延续的,如以下示例所示:

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

要在 Logstash 中将这些行合并为单个事件,请对多行编解码器使用以下配置:

input {
  stdin {
    codec => multiline {
      pattern => "\\$"
      what => "next"
    }
  }
}

此配置将任何以 \ 字符结尾的行与下一行合并。

时间戳

编辑

来自 Elasticsearch 等服务的活动日志通常以时间戳开头,后跟有关特定活动的信息,如以下示例所示:

[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 {
  file {
    path => "/var/log/someapp.log"
    codec => multiline {
      pattern => "^%{TIMESTAMP_ISO8601} "
      negate => true
      what => previous
    }
  }
}

此配置使用 negate 选项来指定任何不以时间戳开头的行都属于上一行。