在 python 中解析自定义日志文件
Parse a custom log file in python
我有一个包含换行符的日志文件
示例文件:
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
我想将数据分成三列,即时间戳,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)
使用这个我只能提取时间戳,但不知道如何提取下一个字段。
您的正则表达式不需要那么精确:
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.
解析时的一个很好的建议是停止尝试一次做事(尽管这很有趣)。例如,编写一个大正则表达式来解析所有内容:
re.findall("...", TEXT)
或者在单行(有时是链式)代码中从一段文本中提取值:
LINE.split("...")[...].split("...")[...]
相反,将逻辑分解为简单步骤序列(通常分配给中间变量),其中每个步骤都为另一个简单步骤做准备。在您的情况下,这些步骤可能是:
time, rest = line.split(' [', 1)
line_type, msg = rest.split('] ', 1)
在数据混乱的现实世界中,您有时需要在小步骤之间添加错误处理或健全性检查逻辑。
我有一个包含换行符的日志文件
示例文件:
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
我想将数据分成三列,即时间戳,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)
使用这个我只能提取时间戳,但不知道如何提取下一个字段。
您的正则表达式不需要那么精确:
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.
解析时的一个很好的建议是停止尝试一次做事(尽管这很有趣)。例如,编写一个大正则表达式来解析所有内容:
re.findall("...", TEXT)
或者在单行(有时是链式)代码中从一段文本中提取值:
LINE.split("...")[...].split("...")[...]
相反,将逻辑分解为简单步骤序列(通常分配给中间变量),其中每个步骤都为另一个简单步骤做准备。在您的情况下,这些步骤可能是:
time, rest = line.split(' [', 1)
line_type, msg = rest.split('] ', 1)
在数据混乱的现实世界中,您有时需要在小步骤之间添加错误处理或健全性检查逻辑。