Слияние и сортировка файлов журналов в Python - PullRequest
10 голосов
/ 11 июля 2011

Я совершенно новичок в python и у меня есть серьезная проблема, которую я не могу решить.

У меня есть несколько файлов журнала с идентичной структурой:

[timestamp] [level] [source] message

Например:

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

Мне нужно написать программу на чистом Python, которая должна объединить эти файлы журнала в один файл, а затем отсортировать объединенный файл по отметке времени.После этой операции я хочу напечатать этот результат (содержимое объединенного файла) в STDOUT (консоль).

Я не понимаю, как это сделать, нужна помощь.Это возможно?

Ответы [ 4 ]

11 голосов
/ 11 июля 2011

Вы можете сделать это

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,
8 голосов
/ 11 июля 2011

Прежде всего, вы захотите использовать модуль fileinput для получения данных из нескольких файлов, например:

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

, который затем напечатает все строки вместе.Вы также хотите отсортировать, что вы можете сделать с помощью отсортированного ключевого слова.

Предполагая, что ваши строки начинаются с [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)

, который позволит вам читать в gzip-файлах журнала.

Тогда будет использоваться:

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

или подобное.

2 голосов
/ 11 июля 2011

Что касается критической функции сортировки:

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

Это следует использовать в качестве аргумента key для sort или sorted, а не cmp.Так будет быстрее.

О, и у вас должен быть

from datetime import datetime

в вашем коде, чтобы эта работа работала.

0 голосов
/ 11 июля 2011

Считайте строки обоих файлов в список (теперь они будут объединены), предоставьте пользовательскую функцию сравнения, которая преобразует метку времени в секунды с начала эпохи, вызовите сортировку с определенным пользователем сравнением, запишите строки в объединенный файл ...

def compare_func():
    # comparison code
    pass


lst = []

for line in open("file_1.log", "r"):
   lst.append(line)

for line in open("file_2.log", "r"):
   lst.append(line)

# create compare function from timestamp to epoch called compare_func

lst.sort(cmp=compare_func)  # this could be a lambda if it is simple enough

что-то подобное должно сделать это

...