2017-09-28 1 views
0

Ich habe eine Datei (application.log), wo meine Anwendungen ihre Protokolle speichern. Manchmal habe ich eine Ausnahme, und ich möchte nur diese Ausnahmen in einer anderen Datei (exception.log) speichern. Jede Zeile von Protokollen beginnt ab dem Zeitpunkt, in einem solchen Format:Wie man Multiline Stack Trace grep? Nicht vorhandene Threads werden mit meiner Lösung erstellt

[2017-28-09 10:00:00,000] Text of log number 1 
[2017-28-09 10:00:05,000] Text of log number 2 
[2017-28-09 10:00:10,000] Text of Exception number 1 
at bla bla bla 
at bla bla bla  
at bla bla bla  
at bla bla bla  
[2017-28-09 10:00:15,000] Text of log number 4 

In einem solchen siutation Exception.log gespeichert werden sollen:

[2017-28-09 10:00:10,000] Text of Exception number 1 
at bla bla bla 
at bla bla bla  
at bla bla bla  
at bla bla bla 

ich mit einem solchen Verfahren versucht:

kill $(ps -ef | grep tail | awk '{print $2}') 
tail -f /path/to/my/application.log | pcregrep -M 'Exception[^\[]+' | while read line 
do 
(echo "$line" >> /path/to/my/exception.log) 
done & 

Diese Lösung hat die Aufgabe erfolgreich erledigt, aber es hat auch viele Threads und die Anzahl der gesamten Threads in meinem System dramatisch erhöht. Aus diesem Grund muss ich eine andere Lösung verwenden oder ein "nicht behobenes Problem" lösen.

Haben Sie eine Idee, wie kann ich nur Exception Stack Trace in eine andere Datei schneiden, grep oder kopieren oder verhindern, dass nicht mehr existierende Threads geöffnet werden?

+1

Hat 'tail -f /path/to/my/application.log | awk '/\[.*\]/{d=0; if ($ 0 ~ "Exception") d = 1} d '>>/Pfad/zu/my/exception.log' Arbeit für Sie? – CWLiu

+0

Das ist genau das, wonach ich gefragt habe! Danke :-) –

+0

@CWLiu Hmmm ... jetzt habe ich gemerkt, dass es auch die letzte Zeile fängt (ich meine "[2017-28-09 10: 00: 15.000] Text von Log Nummer 4"). Wie kann ich diesen Code ändern, um nur Zeile mit Ausnahme zu schreiben, nicht mit nächste. –

Antwort

2
$ cat test.txt 
[2017-28-09 10:00:00,000] Text of log number 1 
[2017-28-09 10:00:05,000] Text of log number 2 
[2017-28-09 10:00:10,000] Text of Exception number 1 
at bla bla bla 
at bla bla bla  
at bla bla bla  
at bla bla bla  
[2017-28-09 10:00:15,000] Text of log number 4 

$ awk '/\[.*\]/{d=0; if($0 ~ "Exception")d=1}d' test.txt 
[2017-28-09 10:00:10,000] Text of Exception number 1 
at bla bla bla 
at bla bla bla  
at bla bla bla  
at bla bla bla 
+0

Sie hatten Recht, jetzt war es mein falsches. Alles ist gut, danke :-) –

0

Weisen Sie grep an, eine Zeile zu drucken, bevor Sie eine Zeile beginnen, die mit einem Leerzeichen beginnt.

grep -B1 '^ ' 
+0

das ist nicht das, was ich gefragt habe, aber danke für die Unterstützung versuchen –

+0

Für die Beispieldaten in Ihrer Frage ist es, was Sie gefragt haben. Es erzeugt genau die gleiche Ausgabe wie die Antwort, die Sie akzeptiert haben. Wenn es Ihr Problem nicht löst, stimmt Ihre Frage nicht mit Ihrem Problem überein. – ceving

0

Unten ist die @CWLiu Lösung und Art der Lösung ohne "tail -f". Einfach aber brauchbar und es gibt keine Zombie-Prozess oder tail -f Faden hängen:

#!/bin/bash 

# Below I checked if last.log file exists 
if [ ! -f /path/to/my/last.log ]; then 
    echo "" > /path/to/my/last.log 
fi 

# Thanks @CWLiu again for your below solution 
awk '/\[.*\]/{d=0; if($0 ~ "Exception")d=1}d' /path/to/my/application.log > /path/to/my/now.log 

# Creation differential file - now.log stores all exceptions, last.log stores all exceptions from previous check 
diff /path/to/my/now.log /path/to/my/last.log > /path/to/my/tmp.log 
diff /path/to/my/last.log /path/to/my/now.log | grep ">" | tr -d '>' >> /path/to/my/exception.log 

Jetzt habe ich die Ausführung dieser Datei in crontab hinzufügen können, dh jede Minute zu überprüfen, ob einige Ausnahme auftritt:

* * * * * /path/to/my/file.sh