Я использую 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 {}
}
Вот пример PHP-скрипта, который отправляет исключения через TCP:
<?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);
}
Выполнение этого примера распознает только первое исключение как журнал событий. Второе исключение распознается, как только приходит следующая метка времени, которой в данном случае не будет, поскольку поток данных заканчивается.