与Kibana内部的多个单线匹配的多线Grok模式

mepcadol  于 2022-12-09  发布在  Kibana
关注(0)|答案(2)|浏览(210)

我正在尝试设置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将日志从本地计算机发送到logstash容器,并使用以下filebeat.yml配置:

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中不起作用。

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

ylamdve6

ylamdve61#

您的多行模式不正确,它使与之不匹配的每一行都被视为多行事件的一部分(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" ]
}
eit6fx6z

eit6fx6z2#

在Filebeat而不是Logstash中实现多行事件。
PFB注意到来自弹性。

如果要将多行事件发送到Logstash,请在将事件数据发送到Logstash之前使用此处描述的选项处理多行事件。尝试在Logstash中实现多行事件处理(例如,通过使用Logstash多行编解码器)可能会导致流与损坏的数据混合在一起

来源:https://www.elastic.co/guide/en/beats/filebeat/8.4/multiline-examples.html

相关问题