【问题标题】:multiline grok pattern matched to multiple single lines inside kibana多行 grok 模式与 kibana 内的多条单行匹配
【发布时间】:2020-09-21 13:18:00
【问题描述】:

我正在尝试设置 sebp/elk docker 容器以在我的机器上运行 ELK 堆栈。 目标是使用 ELK 记录/解析/搜索日志文件,例如 apache 的访问/错误日志,以及记录 php 执行期间发生的 php 错误日志(这是带有堆栈跟踪的多行错误)。

我尝试解析的 php 错误日志文件示例如下:

[03-Jun-2020 00:39:11 Europe/Berlin] PHP Stack trace:
[03-Jun-2020 00:39:11 Europe/Berlin] PHP   1. {main}() /var/www/myserver.domain/html/index.php:0
[03-Jun-2020 00:39:11 Europe/Berlin] PHP   2. require() /var/www/myserver.domain/html/index.php:17
[03-Jun-2020 00:39:11 Europe/Berlin] PHP   3. require_once() /var/www/myserver.domain/html/wp-blog-header.php:16
[03-Jun-2020 00:39:11 Europe/Berlin] PHP   4. include() /var/www/myserver.domain/html/wp-includes/template-loader.php:27
[03-Jun-2020 00:39:11 Europe/Berlin] PHP   5. the_content() /var/www/myserver.domain/html/wp-content/themes/summer_freedom/index.php:20
[03-Jun-2020 00:39:11 Europe/Berlin] PHP   6. apply_filters() /var/www/myserver.domain/html/wp-includes/post-template.php:79
[03-Jun-2020 00:39:11 Europe/Berlin] PHP   7. call_user_func_array:{/var/www/myserver.domain/html/wp-includes/plugin.php:163}() /var/www/myserver.domain/html/wp-includes/plugin.php:163
[03-Jun-2020 00:39:11 Europe/Berlin] PHP   8. searchnggallerytags() /var/www/myserver.domain/html/wp-includes/plugin.php:163

我使用 filebeat 通过以下 filebeat.yml 配置将日志从本地计算机发送到我的 logstash 容器:

  logstash:
    enabled: true
    hosts:
      - localhost:5044
    ssl:
      certificate_authorities:
        - /etc/filebeat/logstash-beats.crt
    timeout: 15

filebeat:
  prospectors:

    -
      paths:
        - /var/log/php/php_errors.log
      document_type: php-errors

到目前为止,我在 elk 容器内想出的 logstash 配置如下:

input {
    stdin {
        codec => multiline {
            pattern => "^\[%{MONTHDAY}-%{MONTH}-%{YEAR} %{TIME} (?<tzname>[a-zA-Z]+/[a-zA-Z]+)\]"
            negate => true
            what => "previous"
            auto_flush_interval => 10
        }
        type => "php-errors"
    }
}

filter {
  if [type] == "php-errors" {
    grok {
        match => { "message" => "(?m)\[(?<logtime>%{MONTHDAY}-%{MONTH}-%{YEAR} %{TIME} (?<tzname>[a-zA-Z]+/[a-zA-Z]+))\] ?%{GREEDYDATA:message}" }
        overwrite => [ "message" ]
    }

    date {
        match => [ "logtime", "dd-MMM-yyyy HH:mm:ss" ]
        remove_field => [ "logtime" ]
    }
  }
}

output {
    stdout {
        codec => rubydebug
    }
}

一开始我不确定模式是否真的匹配,所以我使用 kibana 中的 grok 调试器仔细检查它是否正确,并与日志文件中的输入真正匹配。

当在 sebp/elk 容器的 logstash 中使用此配置时,我可以看到 kibana 中的条目,因此通过 filebeat 进行的一般传输工作并且logstash 也能够匹配数据。 不幸的是,我在 kibana 中为 php 错误日志文件中的每一行收到一条消息,尽管我希望将所有属于彼此的行连接起来并作为一个事件存储在 elk 中。

据我了解这里的 grok 模式,logstash 应该在每一行中使用相同的时间戳并匹配多行以将所有行写入一条消息中,而不是创建多个事件。

所以问题是,如果我只是使用了错误的配置,或者如果缺少任何东西,那么我只会得到 1 个事件而不是多个事件。

更新: 按照@leandrojmp 的要求,我按照建议更新了logstash 配置,但是在cli 上运行时,从stdout 上的logstash 中的php-error.log 中的每一行仍然得到以下输出:

{
          "host" => {
        "name" => "myserver.domain"
    },
      "@version" => "1",
    "@timestamp" => 2020-06-03T21:54:53.886Z,
       "message" => "[03-Jun-2020 23:54:49 Europe/Berlin] PHP   1. {main}() /var/www/myserver.domain/html/index.php:0",
          "beat" => {
         "version" => "6.4.3",
        "hostname" => "myserver.domain",
            "name" => "myserver.domain"
    },
          "tags" => [
        [0] "beats_input_codec_plain_applied"
    ],
        "offset" => 15896045,
        "source" => "/var/log/php/php_errors.log"
}

所以看起来多行匹配在我的logstash中不起作用。

更新 2: 经过更多研究后,我发现不建议在logstash中匹配多行内容,因为如果您将不同机器的多条日志发送到一个logstash实例,最终可能会将不同的日志混合到一条消息中。 建议的方法是使用 filebeat.yml 合并多行消息将它们发送到 logstash。

【问题讨论】:

    标签: logstash kibana logstash-grok elk


    【解决方案1】:

    您的多行模式不正确,它使与它不匹配的每一行都被视为多行事件的一部分(negate 选项)并包含在前一个事件中(what 选项),但在您的示例每行都以相同的模式开头,因此您永远不会有多行事件。

    您的模式需要与您的多行事件开始时所独有的内容相匹配,在您的情况下,它可能是 "PHP Stack trace" 字符串

    将你的多行模式改为这个:

    codec => multiline {
        pattern => "PHP Stack trace"
        negate => true
        what => "previous"
    }
    

    这会给你以下结果:

    {
          "@version" => "1",
              "tags" => [
            [0] "multiline"
        ],
        "@timestamp" => 2020-06-02T22:39:11.000Z,
            "tzname" => "Europe/Berlin",
              "type" => "php-errors",
           "message" => "PHP Stack trace:\n[03-Jun-2020 00:39:11 Europe/Berlin] PHP   1. {main}() /var/www/myserver.domain/html/index.php:0\n[03-Jun-2020 00:39:11 Europe/Berlin] PHP   2. require() /var/www/myserver.domain/html/index.php:17\n[03-Jun-2020 00:39:11 Europe/Berlin] PHP   3. require_once() /var/www/myserver.domain/html/wp-blog-header.php:16\n[03-Jun-2020 00:39:11 Europe/Berlin] PHP   4. include() /var/www/myserver.domain/html/wp-includes/template-loader.php:27\n[03-Jun-2020 00:39:11 Europe/Berlin] PHP   5. the_content() /var/www/myserver.domain/html/wp-content/themes/summer_freedom/index.php:20\n[03-Jun-2020 00:39:11 Europe/Berlin] PHP   6. apply_filters() /var/www/myserver.domain/html/wp-includes/post-template.php:79\n[03-Jun-2020 00:39:11 Europe/Berlin] PHP   7. call_user_func_array:{/var/www/myserver.domain/html/wp-includes/plugin.php:163}() /var/www/myserver.domain/html/wp-includes/plugin.php:163\n[03-Jun-2020 00:39:11 Europe/Berlin] PHP   8. searchnggallerytags() /var/www/myserver.domain/html/wp-includes/plugin.php:163",
              "host" => "logstash"
    }
    

    现在您的所有行都在同一个事件中,在 kibana 中,您将在 message 字段中看到类似的内容:

    PHP Stack trace:
    [03-Jun-2020 00:39:11 Europe/Berlin] PHP   1. {main}() /var/www/myserver.domain/html/index.php:0\n[03-Jun-2020 00:39:11 Europe/Berlin] PHP   2. require() /var/www/myserver.domain/html/index.php:17
    [03-Jun-2020 00:39:11 Europe/Berlin] PHP   3. require_once() /var/www/myserver.domain/html/wp-blog-header.php:16
    [03-Jun-2020 00:39:11 Europe/Berlin] PHP   4. include() /var/www/myserver.domain/html/wp-includes/template-loader.php:27
    [03-Jun-2020 00:39:11 Europe/Berlin] PHP   5. the_content() /var/www/myserver.domain/html/wp-content/themes/summer_freedom/index.php:20
    [03-Jun-2020 00:39:11 Europe/Berlin] PHP   6. apply_filters() /var/www/myserver.domain/html/wp-includes/post-template.php:79
    [03-Jun-2020 00:39:11 Europe/Berlin] PHP   7. call_user_func_array:{/var/www/myserver.domain/html/wp-includes/plugin.php:163}() /var/www/myserver.domain/html/wp-includes/plugin.php:163
    [03-Jun-2020 00:39:11 Europe/Berlin] PHP   8. searchnggallerytags() /var/www/myserver.domain/html/wp-includes/plugin.php:163
    

    另外,您需要修复date 过滤器,您的时间戳包含时区信息,您需要将其添加到模式中。

    正确的应该是:

    date {
        match => [ "logtime", "dd-MMM-yyyy HH:mm:ss ZZZ" ]
        remove_field => [ "logtime" ]
    }
    

    【讨论】:

    • 我根据您的帖子更改了编解码器和日期,并保留了我的示例中的过滤器,但我仍然在单独的 kibana 消息中获取每一行,所以我想我将不得不更改过滤器也是,或者还有什么我没有得到的东西?
    • 过滤器对多行代码没有影响,它发生在之后。您可以再次运行并使用 logstash 输出更新您的问题吗?我已经用我所做的更改复制了您的管道并得到了上面的结果。
    • 又做了一次,检查了logstash的输出并将其添加到我的问题中
    • 我无法复制,它正在使用您的示例日志在这里工作。您是否尝试过如您在更新中所说的将multiline pattern 移动到 filebeat?
    • 是的,我在 filebeat 中使用了多行模式,现在我在 logstash 中收到了一条我期待的消息。感谢@leandrojmp 到目前为止的帮助!
    猜你喜欢
    • 1970-01-01
    • 2015-03-15
    • 2013-04-02
    • 2010-11-26
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    相关资源
    最近更新 更多