2017-07-13 8 views
0

Ich habe eine große Protokolldatei mit großem Volumen. Wie nehme ich nur die JSON-Zeichenkette, nur die JSON-Zeichenkette nur, wenn es einen Fehler in der nächsten Zeile gibt, aber nach '_____GP D_____' in der vorherigen Zeile?Python analysieren von Protokolldatei

2017-04-22T11:27:11+06:00 smth.com pgp: [16136]: INFO:modules.gp.helpers.parameter_getter:_____GP D_____ 
2017-04-22T11:27:11+06:00 smth.com pgp: [16136]: {'D': 't12', 'telephone': None, 'from_time': '2016-04-22 11:30', 'C': 'C12', 'to_time': '2016-04-22 11:40', 'email': None} 
2017-04-22T11:27:11+06:00 smth.com pgp: [16136]: INFO:tornado.access:200 POST /gp/C (192.168.1.240) 15.77ms 

2017-04-22T11:28:19+06:00 smth.com pgp: [16136]: INFO:modules.security.authentication:LOADING USER... 
2017-04-22T11:28:19+06:00 smth.com pgp: [16136]: INFO:modules.gp.helpers.parameter_getter:_____GP D_____ 
2017-04-22T11:28:19+06:00 smth.com pgp: [16136]: {'D': 'testim12', 'telephone': None, 'from_time': '2017-04-20 17:30', 'C': 'CnGP13', 'to_time': '2017-04-22 21:40', 'email': None} 
2017-04-22T11:28:19+06:00 smth.com pgp: [16136]: ERROR:modules.common.actionexception:ActionError: [{'from': 'time is already passed'}] 
2017-04-22T11:28:19+06:00 smth.com pgp: [16136]: Traceback (most recent call last): 
2017-04-22T11:28:19+06:00 smth.com pgp: [16136]: File "/app/src/modules/base/actions/base_action.py", line 96, in do_action 
2017-04-22T11:28:19+06:00 smth.com pgp: [16136]:  self._produce_response() 
2017-04-22T11:28:19+06:00 smth.com pgp: [16136]: modules.common.actionexception.ActionValidationErr: [] 

zum Beispiel aus dieser Protokolldatei möchte ich

'{' D ': 'testim12', 'Telefon': Keine, 'FROM_TIME': '2017.04.20 17.30', 'C': 'CnGP13', 'to_time': '2017-04-22 21:40', 'E-Mail': Keine} '.

Nur wenn ich eine Ausnahme habe, 'FEHLER: modules.common.actionexception: ActionError:' in der nächsten Zeile? wie mache ich es?

+0

Sie müssen keine Regex dafür verwenden: Lesen Sie das Protokoll für Zeile, verwenden Sie eine begrenzte Aufteilung und überprüfen Sie die 5. Spalte. –

+0

Warum das Regex-Tag entfernen? Jetzt kann ich nicht zurück ... – sln

Antwort

0

, dass das gleiche Problem wie die one you had yesterday ist, nur mit eine zusätzliche Überprüfung vor der Auswahl der Linie - zum Beispiel prüfen, ob die nächste Zeile cont ains ]: ERROR: string:

found_line = None # store for our matched line 
with open("input.log", "r") as f: # open your log file 
    for line in f: # read it line by line 
     if line.rstrip()[-14:] == "_____GP D_____": # if a line ends with our string... 
      found_line = next(f).rstrip() # grab the next line as our potential candidate 
      if next(f).find("]: ERROR:") != -1: # if the next line contains an error marker 
       break # match found, break out as we don't need to search any more... 
      else: # the next line wasn't an error... 
       found_line = None # ... reset the potential result and continue searching 

Da jedoch Ihre found_line tatsächlich die ganze Zeile (einschließlich der Zeitstempel) enthalten würde, müssen Sie sich zunächst, dass Streifen aus, und das hängt alles davon ab, wie Sie Ihren Logger eingestellt ist. Ein vernünftiger Weg, basierend auf Ihren Daten besteht darin, die ersten 39 Zeichen (<date-time> smth.com pgp:) zu überspringen und alles nach dem nächsten Doppelpunkt aufzunehmen, vorausgesetzt, dass die Zahl in den folgenden Klammern geändert werden kann (wenn nicht - Sie können einfach die ersten n Zeichen entfernen und mit ihr geschehen):

if found_line: 
    found_line = found_line[found_line.find(":", 39) + 1:].strip() 

Vorsicht, tho, dass die ‚Fehler‘ Überprüfung kann fehlschlagen, wenn ein Teil der protokollierten Daten enthält das genaue Muster - wenn Sie darauf schärfen möchten, können Sie versuchen, die Verwendung von ähnliche Technik, mit der wir den JSON aus der Protokollzeile heben und prüfen, ob er mit ERROR: beginnt.

Sie sollten auch versuchen, Dinge selbst zu tun, anstatt blind Code von SO zu kopieren - Sie werden nicht viel auf diese Weise lernen.

0

Sie diese verwenden können, wo die JSON-String in Capture-Gruppe ist 1

(?m)^.*?_____GP[ ]D_____.*\r?\n\s*^[^{\r\n]+(.+)\r?\n\s*^.*?ERROR:.*

https://regex101.com/r/UQ8gni/2

erklärt
(?m)       # Modifiers: multi-line 
^ .*? _____GP [ ] D_____ .* # Line that starts error block 
\r? \n \s*     # Required newline 
^ [^{\r\n]+     # Up to start of Json string 
(.+)      # (1), Json string 
\r? \n \s*     # Required newline 
^ .*? ERROR: .*    # Line that ends error block 
0

eine Generatorfunktion benutzen:

def getjson (f): 
    for line in filter(lambda x: '_GP D_' in x, f): 
     line1 = next(f) 
     line2 = next(f).split(' ', 4) 
     if line2[4].startswith('ERROR'): 
      yield line1.rstrip().split(' ', 4)[4] 

with open('input.log', 'r') as f: 
    for json in getjson(f): 
     print(json) 

Ein Interesse des Generators ist, dass es eine eventuelle StopIteration Ausnahme von next()verursacht Raste (beispielsweise, wenn es weniger als 2 Zeilen nach der Zeile mit _G PD_.) und stoppen.

Beachten Sie, dass bei diesem Ansatz davon ausgegangen wird, dass die Zeilen durch mindestens zwei Zeilen getrennt sind.

Verwandte Themen