Анализ автообновляемых логов c Python
Нужно организовать анализ логов, в которые чуть ли не каждую секунду добавляются строки. У меня появилось две проблемы:
После каждого перезапуска программы, она создаёт новый файл с логами в формате
<дата>_<время>.log. Можно ли как то сделать так, чтобы скрипт открывал именно последний лог файл?Как можно сделать так, чтобы скрипт запоминал последнюю проанализированную строку и при следующем цикле начинал со следующей, пропустив предыдущие?
Мой код на данный момент:
while True:
print('analyse logs...')
f = open('test.txt', 'r')
logs = f.readlines()
f.close()
for line in logs:
if ('executed' in line) or ('for test' in line):
print(line)
time.sleep(60)
Ответы (1 шт):
После каждого перезапуска программы, она создаёт новый файл с логами в формате <дата>_<время>.log. Можно ли как то сделать так, чтобы скрипт открывал именно последний лог файл?
Нужно получить список файлов, распарсить их, и вытащить файл, чья дата наибольшая.
Я придумал файлы с форматом %d%m%y_%H%M%S.log:
logs/
110220_113400.log
130220_113400.log
130220_120000.log
131219_113446.log
А теперь парсим их названия:
import datetime as DT
from glob import glob
from pathlib import Path
logs = glob('logs/*_*.log')
print(logs)
# ['logs\\110220_113400.log', 'logs\\130220_113400.log', 'logs\\130220_120000.log', 'logs\\131219_113446.log']
for file_name in logs:
date_str = Path(file_name).stem
print(date_str, DT.datetime.strptime(date_str, '%d%m%y_%H%M%S'), sep=' -> ')
# 110220_113400 -> 2020-02-11 11:34:00
# 130220_113400 -> 2020-02-13 11:34:00
# 130220_120000 -> 2020-02-13 12:00:00
# 131219_113446 -> 2019-12-13 11:34:46
Код разбора имени в дату перенесем в отдельную функцию и используем ее в функции max для получения максимального элемента по дате:
def get_datetime_from_log_file_name(file_name):
date_str = Path(file_name).stem
return DT.datetime.strptime(date_str, '%d%m%y_%H%M%S')
...
last_log = max(logs, key=get_datetime_from_log_file_name)
print(last_log)
# logs\130220_120000.log
Как можно сделать так, чтобы скрипт запоминал последнюю проанализированную строку и при следующем цикле начинал со следующей, пропустив предыдущие?
Сохраняйте последнюю строку в памяти. Это будет работать пока скрипт запущен. Либо сохраняйте в файле и при запуске приложения считывайте из файла. А так, создайте переменную last_line инициируйте ее None, в цикле проверяйте, ее значение с текущей строкой и пропускайте строки, что не проходят ее. А после цикла for актуализируйте last_line.
Примерно так:
last_line = None
while True:
print('analyse logs...')
with open('test.txt') as f:
logs = f.readlines()
for line in logs:
if last_line is not None:
# Если текущая строка является последней, то сбросим флаг, чтобы не было
# проверки last_line и продолжим разбор со следующей строки
if last_line == line:
last_line = None
# Пропускаем текущие строки пока задан last_line
continue
if ('executed' in line) or ('for test' in line):
print(line)
last_line = line
time.sleep(60)