Какие уровни логирования бывают и какой самый низкий
Что проверяют
Знаете ли вы стандартный модуль logging глубже print: числовые значения уровней, как уровни логгера и обработчика фильтруют сообщения, какой порог стоит по умолчанию. Вопрос с подвохом: самым низким обычно называют DEBUG, а формально это NOTSET.
Как отвечать
Уровни в logging это просто числа, сообщение проходит, если его уровень не ниже порога:
CRITICAL(50): приложение не может продолжать работу.FATALэто синоним;ERROR(40): операция не выполнена. Внутриexceptудобно зватьlogger.exception(), он пишет на уровнеERRORи добавляет трейсбек;WARNING(30): что-то пошло не так, но работа продолжается.WARNэто устаревший синоним;INFO(20): штатные события вроде запуска, завершения задачи, ключевых шагов;DEBUG(10): подробности для отладки, самый низкий из рабочих уровней;NOTSET(0): «уровень не задан». Логгер сNOTSETберёт эффективный уровень у родителя, обработчик сNOTSETпропускает всё.
Важная деталь: корневой логгер по умолчанию стоит на WARNING, поэтому logging.debug() и logging.info() без настройки ничего не выводят. Фильтрация идёт дважды: сначала по уровню логгера, потом по уровню каждого обработчика.
Хорошая практика: в модуле logger = logging.getLogger(__name__), настройка один раз в точке входа через basicConfig() или dictConfig(), аргументы передаются отдельно, logger.debug("user %s", user_id), чтобы строка не форматировалась при отключённом уровне. Свой уровень регистрируется через logging.addLevelName(), но нужно это редко.
Где спотыкаются
Не понимают, почему DEBUG не выводится: уровень логгера понизили, а у обработчика остался порог выше, или наоборот.
Вызывают basicConfig() повторно и удивляются, что ничего не меняется: если у корневого логгера уже есть обработчики, вызов молча игнорируется, пока не передать force=True.
Пишут logger.debug(f"...") с тяжёлым вычислением внутри. Такая строка собирается всегда, даже если уровень отключён.