我正在尝试设置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合并它们。
2条答案
按热度按时间ylamdve61#
您的多行模式不正确,它使与之不匹配的每一行都被视为多行事件的一部分(
negate
选项),并包含在前一个事件中(what
选项),但在您的示例中,每一行都以相同的模式开始,因此您永远不会有多行事件。您的模式需要与多行事件开头的唯一字符串匹配,在您的情况下,它可以是
"PHP Stack trace"
字符串将多线样式变更为以下样式:
这将给予以下结果:
请注意,现在所有行都在同一个事件中,在kibana中,
message
字段中将显示如下内容:此外,您需要修复您的
date
过滤器,您的时间戳具有时区信息,您需要将其添加到模式中。正确的答案是:
eit6fx6z2#
在Filebeat而不是Logstash中实现多行事件。
PFB注意到来自弹性。
如果要将多行事件发送到Logstash,请在将事件数据发送到Logstash之前使用此处描述的选项处理多行事件。尝试在Logstash中实现多行事件处理(例如,通过使用Logstash多行编解码器)可能会导致流与损坏的数据混合在一起。
来源:https://www.elastic.co/guide/en/beats/filebeat/8.4/multiline-examples.html