Ответ
Логгер — это объект, который предоставляет приложению интерфейс для записи событий (логов). Вместо использования print() для отладки, логгеры позволяют гибко управлять выводом сообщений, их форматом и назначением (консоль, файл, удаленный сервис).
В Python для этого используется встроенный модуль logging.
Основные компоненты logging:
- Logger: Основной объект, с которым взаимодействует код (
logger.info(...)). - Handler: Определяет, куда отправляются логи (например,
StreamHandlerв консоль,FileHandlerв файл). - Formatter: Задает формат вывода лог-сообщений (время, уровень, текст).
Уровни логирования (по возрастанию важности):
DEBUG: Детальная информация для диагностики проблем.INFO: Подтверждение, что все работает штатно.WARNING: Указание на потенциальную проблему.ERROR: Ошибка, из-за которой программа не смогла выполнить какую-то функцию.CRITICAL: Серьезная ошибка, которая может привести к аварийному завершению программы.
Пример настройки (best practice):
import logging
# 1. Создаем логгер. Принято называть его по имени модуля.
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG) # Устанавливаем минимальный уровень для логгера
# 2. Создаем обработчик (хендлер) для вывода в консоль
ch = logging.StreamHandler()
ch.setLevel(logging.INFO) # Устанавливаем уровень для конкретного обработчика
# 3. Создаем форматер и добавляем его в обработчик
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
# 4. Добавляем обработчик в логгер
logger.addHandler(ch)
# Используем логгер
logger.debug("Это сообщение для отладки. Оно не появится в консоли.")
logger.info("Приложение успешно стартовало.")
logger.warning("Внимание: используется устаревшая конфигурация.")
Почему это лучше, чем print()?
- Уровни важности: Легко фильтровать сообщения (например, показывать только ошибки в production).
- Гибкость вывода: Можно одновременно писать логи в консоль, файл и отправлять по сети, не меняя код приложения.
- Контекст: Автоматически добавляется полезная информация (время, имя модуля, номер строки).
Ответ 18+ 🔞
Да ты посмотри, какая хуйня придумана, чтобы не пиздеть в консоль как последний распиздяй! Вместо того чтобы тыкать print() на каждом углу, как обезьяна с гранатой, есть целая система — логгер.
Это, блядь, такой надзиратель, который записывает всё, что происходит с твоим кодом. Не просто записывает, а ещё и сортирует по степени пиздеца.
Из чего эта шайка-лейка состоит:
- Сам Логгер (Logger): Это главный стукач. Ты ему говоришь: «Запиши, что я тут делаю», а он уже решает — куда и в каком виде это понести.
- Отправитель (Handler): Решает, куда слать донос. В консоль (
StreamHandler), в файл (FileHandler) или, например, на почту начальнику, чтобы он знал, что ты опять всё сломал. - Оформитель (Formatter): Чтобы донос выглядел солидно. Добавляет время, имя стукача (модуля) и уровень тревоги.
Уровни тревоги, от «ничего страшного» до «всё пропало»:
DEBUG: Для полных дегенератов, которые хотят знать КАЖДОЕ движение своей программы. «Переменнаяiтеперь равна 5».INFO: Нормальные рабочие моменты. «Сервис запустился, все довольны».WARNING: Предупреждение, что пахнет жареным. «Братан, ты используешь старую библиотеку, скоро будет больно».ERROR: Всё, пиздец наступил в конкретном месте. «Не удалось подключиться к базе данных, пользователь не сохранён».CRITICAL: Полный и окончательный пиздец. «Диск сгорел, данные потеряны, мы все умрём».
Вот как это выглядит в коде, если делать не как попало:
import logging
# 1. Заводим своего стукача. Имя даём обычно по имени модуля, чтобы потом знать, кто на кого донёс.
logger = logging.getLogger(__name__)
# Говорим ему: "Слушай сюда, фиксируй ВСЁ, начиная от мельчайшей хуйни (DEBUG)"
logger.setLevel(logging.DEBUG)
# 2. Создаём канал для доноса. Например, в консоль.
ch = logging.StreamHandler()
# Но в консоль пусть тащит только важное, начиная с INFO. Отладочную муть не выводи.
ch.setLevel(logging.INFO)
# 3. Оформляем донос по красоте, чтобы всё понятно было.
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
# 4. Приставляем этого отправителя к нашему логгеру.
logger.addHandler(ch)
# А теперь пользуемся!
logger.debug("Сейчас функция вошла в цикл, i=0.") # Этого в консоли НЕ БУДЕТ, ибо уровень низкий.
logger.info("Модуль инициализирован, работаем.") # А это будет.
logger.warning("Конфиг загружен из дефолтного файла, проверь пути, долбоёб.")
И нахуй это всё, если есть print()?
- Не надо руками всё фильтровать. Захотел в продакшене только ошибки — поменял одну строчку уровня, а не вырезал к хуям собачьим сотню
print. - Пишешь в одно место, а летит в десять. Одно сообщение можно и в консоль вывести, и в файлик записать, и в телегу отправить.
- Контекст автоматом. Не нужно самому приписывать «[ERROR] 12:34:56», форматер сделает это за тебя, да ещё и строку кода подскажет, где пиздец случился. Красота, ёпта!