【问题标题】:Parse a custom log file in python在 python 中解析自定义日志文件
【发布时间】:2019-08-12 12:20:15
【问题描述】:

我有一个带有换行符的日志文件

示例文件:

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

我想将数据分成三列,即时间戳、类型代码,以显示事件是错误、警告还是信息,然后是消息。

我为此使用了拆分功能:

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)

使用这个我只能提取时间戳,但不知道如何提取字段的下一个。

【问题讨论】:

  • 好吧,怎么说最好:使用空格作为字段分隔符和字段内部而不被同时引用将是解析这个的一个严重问题。您可以尝试有限的左拆分,然后是有限的右拆分,从两侧靠近文本字段。

标签: python logparser


【解决方案1】:

您的正则表达式不需要那么精确:

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

【讨论】:

    【解决方案2】:

    解析时的一条好建议是停止尝试一次性完成某件事(尽管这很有趣)。例如,编写一个大的正则表达式来解析所有内容:

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

    或者从一行(有时是链式)代码中的一段文本中提取一个值:

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

    相反,将逻辑分解为一系列简单步骤(通常分配给中间变量),其中每个步骤都为另一个简单步骤做好准备。在您的情况下,这些步骤可能是:

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

    在杂乱数据的现实世界中,您有时需要在小步骤之间添加错误处理或完整性检查逻辑。

    【讨论】:

      猜你喜欢
      • 2016-12-17
      • 2015-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多