0

我使用 logstash 来解析通过 TCP 通过网络发送的异常日志。由于异常日志是多行的,我使用多行过滤器来解析数据。不幸的是,最后一个正在发送的异常日志无法识别,因为 logstash 不知道它在哪里结束(由于多行模式)。甚至有可能识别它的结束位置吗?异常的结束可以是任何东西(那么如何进行正则表达式呢?)。或者是否有可能以某种方式知道,因为 TCP 流结束了,这意味着异常也已经结束?

这是我的logstash配置文件:

input { 
    tcp {
        port => 1337
        type => "exception"
    } 
}
filter {
    if [type] == "exception" {
        multiline {
            pattern => "%{TIMESTAMP_ISO8601}"
            negate => true
            what => previous
        }
        grok {
            match => ["message", "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:log_level} \(%{INT:log_level_code}\): exception '%{DATA:exception_name}' with message '%{DATA:exception_message}' in %{PATH:path} Stack trace: %{GREEDYDATA:stack_trace}"]
            remove_field => ["log_level", "log_level_code", "host"]
        }
        date {
            match => ["timestamp", "ISO8601"]
        }  
    }
}
output {
    elasticsearch { host => localhost }
    stdout {}
}

这是一个通过 TCP 发送异常的示例 PHP 脚本:

<?php
$content = "2014-11-25T20:11:55+00:00 ERR (3):
exception 'Exception' with message 'some error' in /private/var/www/index.php:88
Stack trace:
#0 {main}
2014-11-25T20:11:56+00:00 ERR (3):
exception 'Exception' with message 'some error' in /private/var/www/index.php:88
Stack trace:
#0 {main}";

$fp = stream_socket_client("tcp://127.0.0.1:1337", $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
    fwrite($fp, $content);
    fclose($fp);
}

运行此示例只会将第一个异常识别为事件日志。一旦下一个时间戳到达,第二个异常就会被识别出来,在这种情况下不会,因为数据流结束了。

4

2 回答 2

1

多行编解码器不支持清除最后一个事件。多行过滤器有一个 enable_flush 参数,但它被列为不用于生产用途。

可悲的是,唯一的解决方案是有更多的例外:)

于 2014-11-30T20:07:11.837 回答
0

1.5.0(目前以 RC 形式提供)纠正了这个问题,但仅限于多线过滤器。 原始 JIRA 错误已关闭 GitHub 问题

我遇到了同样的问题,并且发生在 Jira/GitHub 讨论中。尝试了几次,但我确实让它工作了。我会说在等待刷新事件发生时要耐心等待——它会等待几秒钟。

于 2015-03-27T23:25:34.237 回答