Mes journaux sont formatés comme ceci:
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 existe 2 types d'événements:
-log sur une ligne comme la première
-log sur plusieurs lignes comme la seconde
Je suis capable 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 une autre.
Voici 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"]
}
}
}
C'est donc ce que j'ai fait, et j'aimerais avoir dans ma console la sortie suivante:
{
"@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 message, "solution" et fin d'événement pour la variable solution), et que peu importe si l'expression est sur un seul ou plusieurs lignes.
Merci d'avance
En ce qui concerne le grok multiligne, il est préférable d'utiliser un drapeau spécial pour la chaîne de motif:
grok {
match => ["message", "(?m)%{SYSLOG5424LINE}"]
}
Il semble que vous ayez deux problèmes:
Vous devez combiner correctement vos multilignes:
filter
{
multiline
{
pattern => "^ "
what => "previous"
}
}
Cela combinera toute ligne commençant par un espace dans la ligne précédente. Vous pourriez finir par devoir utiliser un "suivant" au lieu d'un "précédent".
Remplacer les nouvelles lignes
Je ne crois pas que grok corresponde aux nouvelles lignes.
J'ai contourné cela 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 considérer les multilignes comme une seule grande ligne plutôt que de ne correspondre que jusqu'au "\ n".