【问题标题】:Creating dictionary and its key- value from line of log-file从日志文件行创建字典及其键值
【发布时间】:2020-08-09 08:45:56
【问题描述】:

如果我在日志文件中有以下 ERROR 行,我正在尝试执行以下操作:

Aug  9 12:44:39 hostnameABC gnome-terminal-[12581]: Theme parsing error: gtk.css:6765:28: Missing opening bracket in color definition

我最终需要一个字典(python),看起来像这样:

gnome-terminal-[1258] = {ERROR: 1}

如果范围内已经有这样的字典,则 ERROR += 1 。 最后打印字典名和键值。

这可能吗?

【问题讨论】:

  • 您想统计日志文件中gnome-terminal-[12581] 的出现次数吗?
  • 是什么让错误成为错误?
  • 请详细说明“范围”
  • 错误行由其中存在“错误”表示。那是错误的时候。里面也可能有“信息”。
  • 错误行由其中存在“错误”表示。那是错误的时候。里面也可能有“信息”。范围也意味着,如果有另一个错误行 forgnome-terminal-[12581] 的实例,那么我们需要检查它是否已经初始化为字典并将 1 添加到错误键。或者以任何其他方式实现这一目标。

标签: python dictionary python-re


【解决方案1】:

试试这个:

import re

# As I don't have access to the original file, you can
# uncomment the code below to get the lines from the file

#with open('filename.txt') as file:
#     lines = file.readlines()


# Now, assuming  these are the lines from the log file
lines = [
'Aug 9 12:44:39 hostnameABC gnome-terminal-[12581]: Theme parsing error: gtk.css:6765:28: Missing opening bracket in color definition',
'Aug 9 12:44:39 hostnameABC gnome-terminal-[12581]: Theme parsing error: gtk.css:6765:28: Missing opening bracket in color definition',
'Aug 9 12:44:39 hostnameABC gnome-terminal-[1581]: Theme parsing error: gtk.css:6765:28: Missing opening bracket in color definition'
]

er_regex = re.compile(r'gnome-terminal-\[\d+\]')

def er_count():
   count = {}
   er_ins = er_regex.findall(' '.join(lines))
   for er in er_ins:
       count.setdefault(er, 0)
       count[er] += 1
   return(count)

print(er_count())

你会得到一个字典,每个错误都有一个计数:)

【讨论】:

  • 感谢代码贡献。您是否可以将名称、计数字典更改为 gnome-terminal-[12581] ?在这种情况下,要求字典名称按其错误类型 "gnome-terminal-[12581] "。还要记住,如果下次出现在日志文件中,我们需要检查字典是否已经存在,然后将错误计数加 1。
  • 一般来说,动态分配变量名是almost never a good idea。最好的方法是拥有一个字典变量,并在其中有带有错误名称的键,每个键都有一个适当的值。至于检查字典是否已经存在,我不确定我理解你的意思......
【解决方案2】:

您不能在变量名中使用连字符和方括号。您可以通过使用更高级别的字典来解决此问题,以便您的带有连字符和方括号的名称是该字典中的键。您的解决方案可能如下所示:

import re

log = '''Aug  9 12:44:39 hostnameABC gnome-terminal-[12581]: Theme parsing error: gtk.css:6765:28: Missing opening bracket in color definition
Aug  9 12:44:39 hostnameABC gnome-terminal-[12581]: Theme parsing error: gtk.css:6765:28: Missing opening bracket in color definition
Aug  9 12:44:39 hostnameABC gnome-terminal-[12581]: Info only'''

data = {}

matches = re.findall(r'(gnome-terminal-\[\d+\])(?=.*error)', log)
for match in matches:
  data[match] = data.setdefault(match, {'ERROR': 0})
  data[match]['ERROR'] += 1

print(data)
# {'gnome-terminal-[12581]': {'ERROR': 2}}

如果您避免名称中出现无效字符,您可以使用与上述相同的方法,只需省略顶级字典即可。

【讨论】:

  • 字典名称只需要来自日志行,在这种情况下是 gnome-terminal-[12581]
  • 您的变量名不能包含连字符。你可以这样做:error_dicts['gnome-terminal-'] = {} 字典应该是例如'gnome-terminal-' 和密钥 '12581'?还是您的意思是 dict 实际上必须是 'gnome-terminal-[12581]'...?
  • 为了简单起见,让我们在日志文件中说 gnome_terminal 而不是 gnome-terminal-[12581] :) ,前提是 var name 中允许使用下划线
  • 我已经更新了我的答案以接近您的需要,通过使用顶级字典 data 来避免字典名称中的连字符。
  • 方括号也是一个问题,因为它是为访问字典而保留的。
【解决方案3】:

感谢各位,特别是 Pitamer 和 rikus 的所有帮助。我能够使用您的输入代码和想法并为自己制定解决方案。

    error_pattern = r'ticky: ERROR ([\w\s\']*) \((.+)\)'
    info_pattern = r'ticky: INFO.* \((.+)\)'
    user_stat = {}
    
    with open('syslog.log','r') as logs:
      for line in logs.readlines():
        if re.search(error_pattern,line):
          results = re.search(error_pattern, line)
          user_stat.setdefault(results.group(2),[0,0])[1]+=1
        if re.search(info_pattern,line):
          results = re.search(info_pattern, line)
          user_stat.setdefault(results.group(1),[0,0])[0]+=1
    
    user_sorted = sorted(user_stat.items())
    
with open('user_statistics.csv','w') as output:
  csvfiler = csv.writer(output)
  csvfiler.writerow(['Username','INFO','ERROR'])
  for item in user_sorted:
      onerow = [item[0],item[1][0],item[1][1]]
      csvfiler.writerow(onerow)

【讨论】:

    猜你喜欢
    • 2018-11-03
    • 2020-11-05
    • 1970-01-01
    • 1970-01-01
    • 2014-10-08
    • 2021-07-21
    • 1970-01-01
    • 2016-09-03
    • 1970-01-01
    相关资源
    最近更新 更多