2017-01-11 48 views
1

我想分析大量文本日志文件(约100万线)。下面的示例:解析一个大的文本文件,并提取数据,而循环一次以上 - Python的

2016年11月8日03:49.879的阿尔法:(157)一切都很好

2016年11月8日03:49.979的阿尔法:(157)有一个错误这里

2016年11月8日03:50.879伽玛:(2)其他东西在这里

2016年11月8日03:51.879三角洲:(69)有些事情正在发生

我想实现的是查找错误,然后返回与该错误相关的所有行 - 在这种情况下为alfa。问题是,当我第一次循环并发现错误,然后将alfa(157)保存为参考,然后如何在没有循环通过1M的情况下返回所有的alfa(157)行(即使是在例如错误之前发生的行)再次行。如果有50个错误怎么办?这可能吗?这是否是O(n2)问题?

我想使用Python:

def analyze_log(f): 
    for line in f: 
     (..) 
+1

在'dict'中出现的组错误,其中键是日志标签,值是行列表。您可以使用该词典打印报告。 –

+0

是否需要连续抓取所有线? – jure

+0

@jure他们直到(数),消息长度不同 –

回答

0

你可以从你的错误157,或任何椅子中错误的所有行追加,在相同的字典键:

log_errors = {} 
... 
if log_errors.has_key(error_key): 
    log_errors[error_key].append(line_from_log) 
else: 
    log_errors[error_key] = line_from_log 

PS。 has_key()已从python 3中删除,请使用'in'运算符。

1

1M线是不是现代的硬件那么大,我会用字典组装的内存数据库。喜欢的东西:

log_database = {} 
for i, line in enumerate(logfile): 
    date, time, label, message = line.split(None, 3) 
    log_database.setdefault(label, []).append({ 
     "line number": i, 
     "date": date, 
     "time": time, 
     "message": message, 
    }) 
+0

我会运行脚本后处理内存数据库的?它会从内存中删除它,还是我必须处理它? –

+0

如果你想访问数据的脚本运行后,你将不得不坚持好歹它,例如,转储到一个JSON文件(或只是使用关系数据库一样'sqlite'或'mysql')。脚本运行后,所有内存都将被回收。 –

1

我建议你建立一个管道,你可以在每一行上执行多个操作的方式。如果你想变得更加奇特,你甚至可以使用协程来构建它,然后异步并行运行。

def has_errors(line): 
    return True if ('alfa' in line and 'ERROR' in line) else False 

def do_something(line): 
    # add your processing logic 
    processed = line 
    return processed 

errors = list() 
processed = list() 

with open('kwyjibo.log') as log_file: 
    for line in log_file: 
     if has_errors(line): 
      errors.append(line) 
     processed.append(do_something(line)) 

# contents of kwyjibo.log 
# 2016-11-08 03:49.879 alfa: (157) all is good 
# 2016-11-08 03:49.979 alfa: (157) there is an ERROR here 
# 2016-11-08 03:50.879 gamma: (2) something else is here 
# 2016-11-08 03:51.879 delta: (69) something is going on 

# Output 
# In [3]: errors 
# Out[3]: ['2016-11-08 03:49.979 alfa: (157) there is an ERROR here\n'] 

# In [4]: processed 
# Out[4]: 
# ['2016-11-08 03:49.879 alfa: (157) all is good\n', 
# '2016-11-08 03:49.979 alfa: (157) there is an ERROR here\n', 
# '2016-11-08 03:50.879 gamma: (2) something else is here\n', 
# '2016-11-08 03:51.879 delta: (69) something is going on\n'] 
+0

这种方法的好处是您可以根据需要进行多种不同的处理步骤。考虑在建立管道的地方使用* NIX类型的工具。这种方法的好处在于,如果通过使处理元素协同并行,然后执行并行处理来实现并发处理,则可以水平扩展。 –

+0

你在大文件上试过这种方法吗?几百万行? –

+0

@Always_hungry我已经用这种方法处理400万行文件。如果你在内存和约束方面有问题,那么你需要考虑如何处理每个处理步骤的输出,也许不是将它存储在列表中,而是将它写入另一个文件。在这种情况下,我通常会编写我的应用程序,以便可以同时运行,然后平行运行它。 –

相关问题