Обработка логов. Создайте программу считывания логов Error
Контекст
Вы работаете в большой компании, которая обслуживает сложную систему торговли. Каждый день генерируется огромное количество лог-файлов, содержащих информацию о торговых операциях. Вам поставлена задача разработать программу, которая будет автоматически анализировать эти лог-файлы и находить строки с сообщениями об ошибках (ERROR). Это поможет вам быстро отслеживать проблемы в торговой системе и эффективно на них реагировать.
Задача
Напишите программу, которая считывает строки из файла и выводит строки, содержащие слово ERROR, в новый файл.
Требования
Используйте модуль os для работы с файлами и путями.
Учтите, что файл может быть очень большим по объёму, поэтому не загружайте его в память целиком.
Создайте функцию-генератор error_log_generator, которая будет получать на вход путь до файла с логами и возвращать строки из этого файла, которые содержат слово ERROR (одно обращение к генератору должно возвращать одну строку из файла).
Советы
Цикл for по файлу будет считывать в память ровно по одной строке из файла за итерацию.
Генератор должен возвращать только строки со словом ERROR. Другие строки, которые будут считываться из файла, нужно будет игнорировать (применять yield только к правильным строкам).
Для наглядного примера вы можете сгенерировать очень большой текстовый файл (для этого надо запустить код из файла text_generator.py) и попробовать загрузить его в память при помощи метода read(), применённого к этому файлу.
Учтите, что генерация файла такого размера может занять несколько десятков минут!
Файлы теста
# При помощи модуля os (и функции join) сформируйте пути до файлов work_logs.txt и output.txt в папке data
# (output.txt может не быть в папке data, но его нужно будет там создать, при помощи кода)
input_file_path = ...
output_file_path = ...
# Документация по join https://docs-python.ru/standart-library/modul-os-path-python/funktsija-join-modulja-os-path/
# Не забудьте проверить наличие файлов перед тем как начать работу с ними
# https://docs-python.ru/standart-library/modul-os-path-python/funktsija-exists-modulja-os-path/
with open(output_file_path, 'w') as output:
for error_line in error_log_generator(input_file_path):
output.write(error_line)
print("Файл успешно обработан.")
Для создания программы считывания логов Error, необходимо использовать модуль os для работы с файлами и путями. Файл может быть очень большим по объёму, поэтому не следует загружать его в память целиком. Для этого можно создать функцию-генератор error_log_generator, которая будет получать на вход путь до файла с логами и возвращать строки из этого файла, которые содержат слово ERROR (одно обращение к генератору должно возвращать одну строку из файла). Цикл for по файлу будет считывать в память ровно по одной строке из файла за итерацию. Генератор должен возвращать только строки со словом ERROR. Другие строки, которые будут считываться из файла, нужно будет игнорировать (применять yield только к правильным строкам). Для проверки наличия файлов перед началом работы с ними, можно использовать функцию exists() модуля os.path. Для записи строк, содержащих слово ERROR, в новый файл, можно использовать функцию write() для объекта файла, открытого в режиме 'w'.
Код для решения данной задачи:
import os
def error_log_generator(file_path):
with open(file_path, 'r') as file:
for line in file:
if 'ERROR' in line:
yield line
# Путь до файла с логами
input_file_path = os.path.join('data', 'work_logs.txt')
# Путь до файла, в который будут записываться строки с ошибками
output_file_path = os.path.join('data', 'output.txt')
# Проверка наличия файлов
if os.path.exists(input_file_path) and not os.path.exists(output_file_path):
with open(output_file_path, 'w') as output:
for error_line in error_log_generator(input_file_path):
output.write(error_line)
print("Файл успешно обработан.")
else:
print("Файлы не найдены или файл вывода уже существует.")
В данном коде используется функция-генератор error_log_generator, которая получает на вход путь до файла с логами и возвращает строки из этого файла, содержащие слово ERROR. Затем происходит проверка наличия файлов и запись строк, содержащих слово ERROR, в новый файл. Если файлы не найдены или файл вывода уже существует, выводится соответствующее сообщение.
Для написания тестов для функции, которая считывает строки из файла и выводит строки, содержащие слово ERROR, в новый файл, можно использовать модуль assert для создания самих тестов. Модуль assert позволяет проверять истинность переданного значения и выводить сообщение об ошибке в случае несоответствия.
код для тестирования функции:
import os
import tempfile
import unittest
from main import error_log_generator
class TestErrorLogGenerator(unittest.TestCase):
def setUp(self):
self.file = tempfile.NamedTemporaryFile(delete=False)
self.file.write(b'INFO: This is an info message\n')
self.file.write(b'ERROR: This is an error message\n')
self.file.write(b'WARNING: This is a warning message\n')
self.file.close()
def tearDown(self):
os.unlink(self.file.name)
def test_error_log_generator(self):
expected_output = b'ERROR: This is an error message\n'
with open(self.file.name, 'rb') as input_file:
with tempfile.NamedTemporaryFile(delete=False) as output_file:
for error_line in error_log_generator(input_file.name):
output_file.write(error_line.encode())
with open(output_file.name, 'rb') as output_file:
self.assertEqual(output_file.read(), expected_output)
if __name__ == '__main__':
unittest.main()
import os
def error_log_generator(file_path):
with open(file_path, 'r') as file:
for line in file:
if 'ERROR' in line:
yield line
# Путь до файла с логами
input_file_path = os.path.join('data', 'work_logs.txt')
# Путь до файла, в который будут записаны строки с ошибками
output_file_path = os.path.join('data', 'output.txt')
# Проверка наличия файлов перед началом работы с ними
if not os.path.exists(input_file_path):
print(f"Файл {input_file_path} не найден.")
elif not os.path.exists(output_file_path):
print(f"Файл {output_file_path} не найден.")
else:
with open(output_file_path, 'w') as output:
for error_line in error_log_generator(input_file_path):
output.write(error_line)
print("Файл успешно обработан.")
import os
from collections.abc import Iterable
def error_log_generator(path: str, text: str) -> Iterable:
"""Функция error_log_generator получат путь к файлу, обрабатывает его и отправляет строку с ошибкой."""
with open(path, 'r', encoding='utf8') as file_out:
for line in file_out:
if text in line:
yield line
def main():
input_file_path = os.path.join('data', 'work_logs.txt')
output_file_path = os.path.join('data', 'output.txt')
error_message = 'ERROR'
try:
"""Проверяем обрабатываем файл на наличие, лог-файл не проверяем, т.к. он создаться при записи."""
if os.path.exists(input_file_path):
with open(output_file_path, 'w', encoding='utf8') as output:
for error_line in error_log_generator(input_file_path, error_message):
output.write(error_line)
print("\nФайл успешно обработан.")
else:
raise FileNotFoundError('\nВ указанной директории файл отсутствует.')
except FileNotFoundError as exc:
print(exc)
main()