2 минут чтения
30 марта 2021 г.
Эффективное логирование в Python
В Python существует встроенный модуль logging, который позволяет журналировать этапы выполнения программы. Логирование полезно когда, например, нужно оставить большой скрипт сбора / обработки данных на длительное время, а в случае возникновения непредвиденных ошибок выяснить, с чем они могут быть связаны. Анализ логов позволяет быстро и эффективно выявлять проблемные места в коде, но для удобного использования модуля следует написать несколько функций по взаимодействию с ним и вынести их в отдельный файл — сегодня мы этим и займёмся.
Пишем логгер
Создадим файл loggers.py. Для начала импортируем модули и задаём пару значений по умолчанию — директорию для файла с логом и наименование конфигурационного файла, содержащего шаблоны логирования. Его мы опишем следом.
import os
import json
import logging
import logging.config
FOLDER_LOG = «log»
LOGGING_CONFIG_FILE = ‘loggers.json’
Опишем функцию для создания папки с логом: она принимает наименование для папки, но по умолчанию будет называть её «log». Директорию создаём при помощи модуля os и только в том случае, если такой директории ещё не существует.
def create_log_folder(folder=FOLDER_LOG):
if not os.path.exists(folder):
os.mkdir(folder)
Теперь опишем функцию создания нового логгера по заданному шаблону. Функция должна создать директорию для логирования, открыть конфигурационный файл и достать нужный шаблон. Затем по шаблону при помощи модуля logging создаём новый логгер:
def get_logger(name, template=’default’):
create_log_folder()
with open(LOGGING_CONFIG_FILE, «r») as f:
dict_config = json.load(f)
dict_config[«loggers»][name] = dict_config[«loggers»][template]
logging.config.dictConfig(dict_config)
return logging.getLogger(name)
Для удобства опишем ещё одну функцию – получение стандартного лога. Она ничего не принимает и нужна только для инициализации лога с шаблоном default:
def get_default_logger():
create_log_folder()
with open(LOGGING_CONFIG_FILE, «r») as f:
logging.config.dictConfig(json.load(f))
return logging.getLogger(«default»)
Описываем конфигурационный файл
Создадим по соседству файл loggers.json — он будет содержать настройки логгера. Внутри указываем такие настройки, как версию логгера, форматы логирования для разных уровней, наименование выходного файла и его максимальный размер:
{
«version»: 1,
«disable_existing_loggers»: false,
«formatters»: {
«default»: {
«format»: «%(asctime)s — %(processName)-10s — %(name)-10s — %(levelname)-8s — %(message)s»
}
},
«handlers»: {
«console»: {
«class»: «logging.StreamHandler»,
«level»: «INFO»,
«formatter»: «default»
},
«rotating_file»: {
«class»: «logging.handlers.RotatingFileHandler»,
«level»: «DEBUG»,
«formatter»: «default»,
«filename»: «log/main.log»,
«maxBytes»: 10485760,
«backupCount»: 20
}
},
«loggers»: {
«default»: {
«handlers»: [«console», «rotating_file»],
«level»: «DEBUG»
}
}
}
Использование логгера
Теперь давайте представим, что вы выгружаете данные по API и складываете их в базу данных на примере нашего материала про транзакции в SQLAlchemy. Рассмотрим заключительную часть кода: добавим строку с инициализацией стандартного логгера и изменим код так, чтобы сначала в лог выводился offset, затем в случае успеха предложение «Successfully inserted data», а в случае ошибки выводилась сама ошибка и предложение: «Error: tried to insert data but got an error».
Теперь во время работы программы будет отображаться такой вывод, который также будет записан в файл main.log папки log в директории проекта. После завершения работы программы можно исследовать логи, посмотреть, на каких offset возникли проблемы, какие данные не удалось вставить и прочитать текст ошибки:
[ Рекомендации ]
Читайте также
3 минут чтения
21 сентября 2021
[ Связаться ]
Давайте раскроем потенциал вашего бизнеса вместе
Заполните форму на бесплатную консультацию