Обработчики логов
В предыдущей статье мы рассказали о логах, и что их можно записывать в файл. На самом деле всё ещё круче: их можно записывать куда угодно, даже в телеграм-ботов. В этой статье мы рассмотрим как это делать.
Вывод в файл
Первое, что стоит попробовать — это вывод логов в файл:
import logging
logging.basicConfig(filename='app.log', filemode='w')
logging.warning('This will get logged to a file')
Этот код запишет warning не в терминал, а в файл app.log
. Наверное, вы уже обратили внимание на расширение файла. Да, для ведения логов создают файлы .log
.
Ротация логов
Со временем файл начнёт разбухать. А через пару месяцев он может даже скушать всё свободное место на диске. Чтобы такого избежать, можно в явном виде сказать логеру, сколько памяти он может занимать:
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger("Название логера")
logger.setLevel(logging.INFO)
handler = RotatingFileHandler("app.log", maxBytes=200, backupCount=2)
logger.addHandler(handler)
logger.info("Я новый логер!")
В этом примере кода мы создали свой логер. Логер — это штука, которая записывает логи. У логера уровень логирования INFO, а хэндлер — RotatingFileHandler
. Хэндлер — это штука, которая распоряжается логами. Она получает готовые логи, и лишь отвечает за то, куда их положить.
Хэндлер RotatingFileHandler
складывает логи в файл app.log
. Когда логов накапливается больше допустимого размера (200Байт), файл переименовывется в app.log.1
. Затем появляется новый файл app.log
, в который теперь пишутся логи. Когда и он заполнится, файл app.log.1
переименутеся в app.log.2
, а файл app.log
в app.log.1
.
Файлы app.log.1
и app.log.2
— это бэкапы. Их создают, чтобы логи после переполнения файла не стирались совсем. Без них может случиться так, что вы зайдёте в логи как раз в момент, когда всё стёрлось. Бэкапов у вас будет столько, сколько указано в backupCount
.
Когда все бэкапы уже заняты логами, и основной файл app.log
— переполнен, сотрётся самый старый бэкап — app.log.2
, на его место встанет бэкап чуть новее — app.log.1
. Сам же app.log
станет бэкапом app.log.1
и появится новый файл для логов — app.log
.
Чтобы пользоваться логером, нужно писать логи в него. Обратите внимание на последнюю строчку в примере. Мы пишем не привычное logging.info("...")
, а именно logger.info("...")
.
Свой хэндлер
Возможно, вам захочется написать свою логику для обработки логов. Модуль logging
будет не против, вот шаблон:
import logging
class MyLogsHandler(logging.Handler):
def emit(self, record):
log_entry = self.format(record)
# тут ваша логика
Если вы не знаете, что такое классы — не пугайтесь, это не обязательно. Просто заполните код в функции emit(self, record)
, где record
— это как раз запись в логах. Причём, именно сам лог, объект, который помнит когда и где лог был сделан. Чтобы получить отформатированный текст лога, используйте log_entry = self.format(record)
. Здесь хэндлер обрабатывает лог к формату, который вы указали. О форматах было в статье о форматировании логов.
Когда всё готово, создайте логер с вашим хэндлером и пользуйтесь:
import logging
logger = logging.getLogger("Название логера")
logger.setLevel(logging.INFO)
logger.addHandler(MyLogsHandler())
logger.info("Я новый логер!")