Подтвердить что ты не робот

Многострочное сообщение Logstash grok

Мои журналы отформатированы следующим образом:

2014-06-19 02:26:05,556 INFO ok
2014-06-19 02:27:05,556 ERROR
 message:space exception
         at line 85
 solution:increase space
          remove files   

Существует 2 типа событий:

-log на одной строке, такой как первая

-log на нескольких строках, таких как второй

Я могу обработать однострочное событие, но я не могу обработать второй тип, где я хотел бы разместить сообщение в одной переменной и решение в другом.

Это моя конфигурация:

input {
 file {
    path => ["logs/*"]
    start_position => "beginning"
    codec => multiline {
                   pattern => "^%{TIMESTAMP_ISO8601} "
                   negate => true
                   what => previous
    }       
 }
}
filter {
 #parsing of one line event
 grok {
 patterns_dir => "./patterns"
 match=>["message","%{TIMESTAMP_ISO8601:timestamp} %{WORD:level} ok"]
 }
#the parsing fail, so we assumed we are in multiline events, now I process them and I am stuck when I am getting to the new line.
if "_grokparsefailure" in [tags] {
 grok {
 patterns_dir => "./patterns"
 match=>["message","%{TIMESTAMP_ISO8601:timestamp} %{WORD:level}\r\n"]
 }
}

}

Итак, это то, что я сделал, и я хотел бы иметь на своем консольном выходе следующее:

{
"@timestamp" => "2014-06-19 00:00:00,000"
"path" => "logs/test.log"
"level"=>"INFO"
},
{
"@timestamp" => "2014-06-19 00:00:00,000"
"path" => "logs/test.log"
"level"=>"ERROR"
"message" => "space exception at line 85"
"solution"=>"increase space remove files"
}

Конкретно, я хотел бы получить все выражение между двумя словами ( "сообщение" и "решение" для переменной сообщения, "решение" и конец события для переменной решения), и что независимо от того, выполняется ли выражение находится на одной или нескольких строках.

Заранее спасибо

4b9b3361

Ответ 1

Похоже, у вас есть две проблемы:

Вам необходимо правильно комбинировать мультилинии:

filter
{
    multiline
   {
        pattern => "^ "
        what => "previous"
   }
}

Это объединит любую строку, начинающуюся с пробела в предыдущей строке. Возможно, вам придется использовать "следующий", а не "предыдущий".

Заменить новые строки

Я не верю, что сопоставления grok по новостям.

Я обошел это, выполнив следующее в разделе фильтра. Это должно быть до раздела grok:

mutate
{
    gsub => ["message", "\n", "LINE_BREAK"]
}

Это позволило мне заманить многострочные линии как одну большую строку, а не сопоставлять только до "\n".

Ответ 2

Что касается многострочного grok, лучше использовать специальный флаг для строки шаблона:

grok {
    match => ["message", "(?m)%{SYSLOG5424LINE}"]
}