2014-06-19 15 views
18

Meine Protokolle werden wie folgt formatiert:Logstash grok mehrzeilige Nachricht

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 

Es gibt 2 Arten von Veranstaltungen:

-log auf einer Linie wie der erste

-log auf mehrzeilige wie die zweite

Ich bin in der Lage, die Ein-Zeilen-Ereignis zu verarbeiten, aber ich bin nicht in der Lage, den zweiten Typ zu verarbeiten, wo ich die Nachricht in einer Variablen und die Lösung in einem anderen auf Lager haben möchte .

Das ist meine config:

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

} 

Also das ist, was ich getan habe, und ich möchte in meiner Konsolenausgabe folgendes haben:

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

Konkret möchte ich Erhalte den gesamten Ausdruck zwischen zwei Wörtern ("Nachricht" und "Lösung" für die Nachrichtenvariable, "Lösung" und das Ende des Ereignisses für die Lösungsvariable), und zwar unabhängig davon, ob der Ausdruck auf einer oder mehreren Zeilen steht.

Vielen Dank im Voraus

+2

Haben Sie versucht, nur 'Nachricht: (?. *) Lösung :( *)'?.? Ich weiß nicht, ob. passt zu newline in grok oder nicht - wenn nicht, könntest du '[. \ r \ n] *' anstelle von '. *' setzen – Alcanzar

Antwort

11

Es sieht aus wie Sie zwei Probleme haben:

Sie müssen die korrekte Schreibweise Ihrer Multilinien kombinieren:

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

Dies wird jede Linie kombinieren, die mit einem Raum beginnt in die vorherige Zeile. Sie können am Ende einen "nächsten" anstelle eines "vorherigen" verwenden müssen.

ersetzen Newlines

Ich glaube nicht, dass grok sich über mehrere Zeilen übereinstimmt.

Ich habe das umgangen, indem ich Folgendes in Ihrem Filterabschnitt getan habe. Dies sollte vor die grok Sektion:

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

Das erlaubte mir, Multilinien als eine große Linie zu grok anstatt nur bis zum „\ n“ entsprechen.

+0

Die mehrzeiligen Einstellungen in der Frage sind mehr oder weniger korrekt und ähneln denen in der Dokumentation. Das Muster TIMESTAMP_ISO8601 stimmt möglicherweise nicht mit ihm überein - wenn dies der Grund dafür war, warum die Stichprobe von OP falsch war, sollte dies angegeben werden. – makhdumi

+1

Der Filter 'multiline' ist veraltet und sollte ersetzt werden durch [den mehrzeiligen Code] (https://www.elastic.co/guide/en/logstash/current/plugin-codecs-multiline.html) – exhuma

11

Wie für mehrzeilige grok, ist es am besten spezielle Flag für Musterzeichenfolge zu verwenden:

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

Bedenken Sie grok * nach * der Multiline-Anweisung zu verwenden. –

+1

Dies sollte die beste Antwort sein.Funktioniert perfekt und kann unter http://grokdebug.herokuapp.com/ getestet werden. Vielen Dank – makhdumi

Verwandte Themen