我为一些java应用程序执行性能测试。在测试期间,应用程序生成非常大的日志文件(可以是7-10gb)。我需要在特定的日期和时间之间修剪这些日志文件。目前,我使用python脚本,它解析datetime python对象中的日志时间戳并只打印匹配的字符串。但这个解决方案非常缓慢。5 GB日志解析大约25分钟 显然,日志文件中的条目是按顺序排列的,我不需要逐行读取所有文件。 我考虑从开始和结束读取文件,直到条件匹配并在匹配的行数之间打印文件。但我不知道如何才能从反方向读取文件,而不下载到内存中。在
拜托,你能给我推荐一个合适的解决方案吗。在
以下是python脚本的一部分:
lfmt = '%Y-%m-%d %H:%M:%S'
file = open(filename, 'rU')
normal_line = ''
for line in file:
if line[0] == '[':
ltimestamp = datetime.strptime(line[1:20], lfmt)
if ltimestamp >= str and ltimestamp <= end:
normal_line = 'True'
else:
normal_line = ''
if normal_line:
print line,
由于数据是连续的,如果感兴趣区域的开始和结束接近文件的开头,那么从文件末尾读取(以找到匹配的端点)仍然是一个糟糕的解决方案!
我已经编写了一些代码,可以根据您的需要快速找到起点和终点,这种方法称为binary search,类似于clasic儿童的“高或低”猜谜游戏!
脚本读取
lower_bounds
和upper_bounds
(最初是SOF和EOF)之间的一条测试线,并检查匹配条件。如果查找的行更早,那么它将通过读取lower_bound
和上一次读取尝试之间的一行进行再次猜测(如果它的值较高,那么它将在猜测值和上限值之间拆分)。所以你在上下界之间不断迭代-这会产生最快的“平均”解。这应该是一个真正快速的解决方案(以2为基数记录行数!!)。例如,在最坏的情况下(在1000行中查找第999行),使用二进制搜索只需要读取9行!(10亿条线路只需30条……)
以下代码的假设:
进一步:
导入日期时间
7到10 GB是一个很大的数据量。如果要分析这类数据,我要么将应用程序记录到数据库,要么将日志文件上载到数据库。然后,您可以在数据库上高效地进行大量分析。如果您使用像Log4J这样的标准日志工具,那么将日志记录到数据库应该非常简单。只是建议另一个解决方案。
有关数据库日志记录的更多信息,请参阅以下文章:
A good database log appender for Java?
在Python can do much better (~500MB/s for ^{}) 中,即使是顺序
O(n)
扫描,也就是说,性能只受i/O的限制要对文件执行二进制搜索,您可以调整使用固定记录的FileSearcher,使用类似于 ^{} implementation in Python (它是})。
O(n)
来扫描{为了避免}和自定义的
O(n)
(如果日期范围只选择了日志的一小部分),您可以使用一个近似的搜索,该搜索使用较大的固定块,并允许由于某些记录位于块边界上而丢失某些记录,例如,使用带record_size=1MB
的未修改{Query
类:考虑到日期范围可以跨越多个块,可以修改
FileSearcher.__getitem__
返回(filepos, chunk)
,并搜索两次(bisect_left()
,bisect_right()
)以找到近似的filepos_mindate
,filepos_maxdate
。之后,您可以围绕给定的文件位置执行线性搜索(例如,使用tail -n
方法)以找到确切的第一个和最后一个日志记录。相关问题 更多 >
编程相关推荐