2014-06-19 15 views
18

Moje dzienniki są sformatowane tak:Logstash grok multiline wiadomość

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 

Istnieją 2 rodzaje zdarzeń:

-log w jednej linii jak pierwszy

-log na stwardnienie linii jak drugi Jestem w stanie przetworzyć jedno liniowe zdarzenie, ale nie jestem w stanie przetworzyć drugiego typu, w którym chciałbym przechowywać wiadomość w jednej zmiennej, a rozwiązanie w innej .

To jest mój 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"] 
} 
} 

} 

Więc to jest to, co mam zrobić, a chciałbym mieć w moim wyjścia konsoli następujące:

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

Konkretnie chciałbym uzyskać całe wyrażenie między dwoma słowami ("komunikat" i "rozwiązanie" dla zmiennej komunikatu, "rozwiązanie" i koniec zdarzenia dla zmiennej rozwiązania) i to bez względu na to, czy wyrażenie występuje w jednym, czy w wielu wierszach.

góry dzięki

+2

Czy próbowałeś po prostu 'wiadomość: (?. *) rozwiązanie :( *)'?.? Nie wiem, czy. dopasowuje znak nowej linii w grok lub nie - jeśli nie, możesz wpisać '[. \ r \ n] * zamiast". * ' – Alcanzar

Odpowiedz

11

Wygląda na to masz dwa problemy:

Musisz poprawnie połączyć swoje multilinie:

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

To będzie łączyć dowolną linię, która rozpoczyna się w przestrzeni w poprzedniej linii. Może się zdarzyć, że będziesz musiał użyć "następnego" zamiast "poprzedniego".

Wymień nowymi liniami

Nie wierzę, że grok mecze w całej nowej linii.

Obejrzałem to, wykonując następujące czynności w sekcji filtru. To powinno iść przed sekcję Grok:

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

To pozwoliło mi grok multilinie jak jeden wielki linii zamiast dopasowane tylko do tej „\ n”.

+0

Ustawienia multilinii w pytaniu są mniej więcej poprawne i są podobne do tych zawartych w dokumentacji. Wzorzec TIMESTAMP_ISO8601 może nie pasować do niego - jeśli to było uzasadnienie, dlaczego próbka OP była niepoprawna, należy ją podać. – makhdumi

+1

Filtr "multiline" został uznany za przestarzały i powinien zostać zastąpiony przez [kod wieloliniowy] (https://www.elastic.co/guide/en/logstash/current/plugins-codecs-multiline.html) – exhuma

11

Jak dla wielowierszowego Grok, to najlepiej użyć specjalną flagę na wzór łańcucha:

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

Pamiętaj używać grok * po * instrukcji wieloliniowej. –

+1

To powinna być najlepsza odpowiedź.Działa doskonale i może być testowany na http://grokdebug.herokuapp.com/. Dziękuję Ci – makhdumi