Разбор пользовательского файла журнала в Python - PullRequest
0 голосов
/ 21 марта 2019

У меня есть файл журнала с символом новой строки

Пример файла:

2019-02-12T00:01:03.428+01:00 [Error] ErrorCode {My error: "A"} -  -  - 00000000-0000-0000-6936-008007000000 
2019-02-12T00:01:03.428+01:00 [Error] ErrorCode {My error: "A"} -  -  - 00000000-0000-0000-6936-008007000000 
2019-02-12T00:03:23.944+01:00 [Information] A validation warning occurred: [[]] while running a file,
--- End of stack trace ---
    FileNotFoundError
--- End of stack trace from previous location where exception was thrown ---
    System Error

Я хочу разбить данные на три столбца, а именно Timestamp, type_code, чтобы показать, является ли событиеошибка, предупреждение или информация, а затем сообщение.

Я использовал для этого функцию разделения:

currentDict = {"date":line.split("] ")[0].split(" [")[0],
                   "type":line.split("] ")[0].split(" [")[1],"text":line.split(" ]")[0].split("] ")[1]}

Чтобы разделить данные в заданных столбцах, все работает нормально, но выдает ошибку, если у меня естьзапись, показанная ниже

2019-02-12T00:03:23.944+01:00 [Information] A validation warning occurred: [[]] while running a file,
--- End of stack trace ---
    FileNotFoundError
--- End of stack trace from previous location where exception was thrown ---
    System Error

, и второй подход использует регулярное выражение

with open(name, "r") as f:
         for lines in f:
             data_matcher = re.findall("^\\d{4}[-]?\\d{1,2}[-]?\\d{1,2}T\\d{1,2}:\\d{1,2}:\\d{1,2}.\\d{1,3}[+]?\\d{1,2}:\\d{1,2}",
                              lines)

Expected Output

, используя это, я могу толькоизвлечь метку времени, но застрял в том, как извлечь рядом с полями.

Ответы [ 2 ]

1 голос
/ 21 марта 2019

Вам не нужно быть настолько точным со своим регулярным выражением:

import re

log_pattern = re.compile(r"([0-9\-]*)T([0-9\-:.+]*)\s*\[([^]]*)\](.*)")

with open(name, "r") as f:
  for line in f:
      match = log_pattern.match(line)
      if not match:
        continue
      grps = match.groups()
      print("Log line:")
      print(f"  date:{grps[0]},\n  time:{grps[1]},\n  type:{grps[2]},\n  text:{grps[3]}")

Вы можете даже представить, что он менее точен, например, r"(.*)T([^\s]*)\s*\[([^]]*)\](.*)" тоже работает.Вот хороший инструмент для проверки регулярных выражений: regex101 .

0 голосов
/ 21 марта 2019

Хороший совет при разборе: не пытайтесь делать что-то одним выстрелом (даже если это весело). Например, написание большого регулярного выражения для разбора всего:

re.findall("...", TEXT)

Или извлечение значения из фрагмента текста в одной (иногда цепочечной) строке кода:

LINE.split("...")[...].split("...")[...]

Вместо этого разбейте логику на последовательность простых шагов (обычно с присваиванием промежуточным переменным), где каждый шаг готовит путь к другому простому шагу. В вашем случае эти шаги могут быть:

time, rest = line.split(' [', 1)
line_type, msg = rest.split('] ', 1)

А в реальном мире запутанных данных иногда нужно добавить логику обработки ошибок или проверки работоспособности между небольшими шагами.

...