2014-06-19 2 views
18

Mes journaux sont formatés comme ceci:Logstash grok message multiligne

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 

Il y a 2 types d'événements:

-log sur une ligne comme la première

-log sur plusieurs lignes comme la seconde

Je suis en mesure de traiter l'événement d'une ligne, mais je ne suis pas en mesure de traiter le deuxième type, où je voudrais stocker le message dans une variable et la solution dans un autre .

C'est ma 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"] 
} 
} 

} 

Voilà donc ce que je l'ai fait, et je voudrais avoir dans ma sortie de la console comme suit:

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

Concrètement, je voudrais obtenir toute l'expression entre deux mots ("message" et "solution" pour la variable de message, "solution" et la fin de l'événement pour la variable de solution), et ce peu importe si l'expression est sur une ou plusieurs lignes.

Merci à l'avance

+2

Avez-vous essayé juste 'message: (?. *) solution :( *)'?.? Je ne sais pas si. correspond à newline dans grok ou pas - sinon vous pourriez mettre '[. \ r \ n] *'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' – Alcanzar

Répondre

11

Il semble que vous avez deux questions:

Vous devez combiner correctement vos multilignes:

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

Ce combinera une ligne qui commence par un espace dans la ligne précédente. Vous pourriez devoir utiliser un "suivant" au lieu d'un "précédent".

Remplacer

nouvelles lignes

Je ne crois pas que grok correspond dans les nouvelles lignes. J'ai contourné ceci en faisant ce qui suit dans votre section de filtre. Cela devrait aller avant la section grok:

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

Cela m'a permis de Grok multilignes comme une grande ligne plutôt que de correspondre seulement jusqu'à ce que le « \ n ».

+0

Les paramètres multilignes de la question sont plus ou moins corrects et sont similaires à ceux de la documentation. Le modèle TIMESTAMP_ISO8601 peut ne pas correspondre - si c'était le raisonnement pour lequel l'échantillon d'OP était incorrect, il devrait être indiqué. – makhdumi

+1

Le filtre 'multiline' a été abandonné et devrait être remplacé par [le code multiligne] (https://www.elastic.co/guide/fr/logstash/current/plugins-codecs-multiline.html) – exhuma

11

En ce qui concerne multiligne grok, il est préférable d'utiliser le drapeau spécial pour chaîne de motif:

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

Gardez à l'esprit utiliser grok * après * l'instruction multiligne. –

+1

Cela devrait être la meilleure réponse.Fonctionne parfaitement et peut être testé sur http://grokdebug.herokuapp.com/. Je vous remercie – makhdumi