在Python中合并和排序日志文件

12 投票
5 回答
13781 浏览
提问于 2025-04-16 21:16

我刚接触Python,遇到了一个大问题,自己解决不了。

我有几个日志文件,它们的结构是一样的:

[timestamp] [level] [source] message

比如说:

[Wed Oct 11 14:32:52 2000] [error] [client 127.0.0.1] error message

我需要写一个纯Python的程序,把这些日志文件合并成一个文件,然后按照时间戳对合并后的文件进行排序。完成这个操作后,我想把结果(合并后文件的内容)打印到STDOUT(控制台)上。

我不知道该怎么做,希望能得到帮助。这可能吗?

5 个回答

2

关于这个重要的排序功能:

def sort_key(line):
    return datetime.strptime(line.split(']')[0], '[%a %b %d %H:%M:%S %Y')

这个功能应该作为 sortsortedkey 参数来使用,而不是作为 cmp。这样做会更快。

哦,还有,你的代码里应该有

from datetime import datetime

才能让这个功能正常工作。

8

首先,你需要使用 fileinput 模块来从多个文件中获取数据,比如这样:

data = fileinput.FileInput()
for line in data.readlines():
    print line

这样做会把所有的行一起打印出来。你还需要对这些行进行排序,可以使用 sorted 这个关键词。

假设你的行是以 [2011-07-20 19:20:12] 开头的,那就没问题了,因为这种格式不需要比字母和数字更复杂的排序,所以可以这样做:

data = fileinput.FileInput()
for line in sorted(data.readlines()):
    print line

不过,如果你有一些更复杂的事情需要处理:

def compareDates(line1, line2):
   # parse the date here into datetime objects
   NotImplemented
   # Then use those for the sorting
   return cmp(parseddate1, parseddate2)

data = fileinput.FileInput()
for line in sorted(data.readlines(), cmp=compareDates):
    print line

为了额外加分,你甚至可以这样做:

data = fileinput.FileInput(openhook=fileinput.hook_compressed)

这样可以让你读取压缩过的日志文件。

使用方法就会是:

$ python yourscript.py access.log.1 access.log.*.gz

或者类似的方式。

14

你可以这样做

import fileinput
import re
from time import strptime

f_names = ['1.log', '2.log'] # names of log files
lines = list(fileinput.input(f_names))
t_fmt = '%a %b %d %H:%M:%S %Y' # format of time stamps
t_pat = re.compile(r'\[(.+?)\]') # pattern to extract timestamp
for l in sorted(lines, key=lambda l: strptime(t_pat.search(l).group(1), t_fmt)):
    print l,

撰写回答