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

#regex #logstash

#регулярное выражение #logstash

Вопрос:

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

 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 типа событий:

-войдите в одну строку, как в первую

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

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

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

 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}rn"]
 }
}

}
 

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

 {
"@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"
}
 

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

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

Комментарии:

1. Вы пробовали просто message: (?<message>.*) solution:(?<solution>.*) ? Я не знаю, соответствует ли . новой строке в grok или нет — если нет, вы могли бы поместить [.rn]* вместо .*

Ответ №1:

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

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

Комментарии:

1. Это должно быть лучшим ответом. Работает отлично и может быть протестировано на grokdebug.herokuapp.com . Спасибо

Ответ №2:

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

Вам нужно правильно комбинировать свои многострочные:

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

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

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

Я не верю, что grok совпадает с новыми строками.

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

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

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

Комментарии:

1. Многострочные настройки в вопросе более или менее правильные и аналогичны тем, что указаны в документации. Шаблон TIMESTAMP_ISO8601 может не соответствовать ему — если это было причиной того, почему пример OP был неправильным, это должно быть указано.

2. multiline Фильтр устарел и должен быть заменен многострочным кодом