我正在尝试设置sebpelk docker容器来在我的机器上运行ELK堆栈,目标是使用ELK来记录parsesearch通过日志文件,如apache的accesserror日志,以及记录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调试器来仔细检查它是否正确,是否真的与日志文件中的输入匹配。
当在sebpelk容器的logstash里面使用这个配置的时候,我可以在kibana里面看到条目,所以一般通过filebeat的传输是有效的,logstash也能够匹配数据.不幸的是,我在kibana里面收到的消息是php错误日志文件里面的每一行,虽然我希望所有属于对方的行都被连在一起,作为一个事件存储在elk里面。
根据我对这里的grok模式的理解,logstash应该在每一行中使用相同的时间戳,并匹配multiline将所有的行写在一条消息中,而不是创建几个事件。
所以问题是,如果我只是使用了错误的配置,或者有什么缺失,所以我将只得到一个事件,而不是多个事件。
更新。按照 @leandrojmp 的要求,我按照建议更新了 logstash 的配置,但是当在 cli 上运行时,从 stdash 的 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实例,它可能最终会将不同的日志混合成一条消息。之前 将它们发送到logstash。
你的多行模式是不对的,它使每一行不匹配的行都被认为是一个多行事件的一部分(the 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" ]
}