lyuba
09.07.2026, 01:20
Введение
Если пишешь на Python, рано или поздно сталкиваешься с задачей логирования ошибок. Просто писать print в except-блоке — это удобно для быстрого отлова, но на больших проектах или если скрипты работают в продакшене, такой подход абсолютно не подходит. Нужно записывать все ошибки в надежный журнал, чтобы потом не гадать, что сломалось, когда и почему. В этой теме хочу поделиться опытом, как организовать логирование ошибок в Python, какие инструменты существуют, какие моменты нужно учитывать и как не напортачить.
Что такое логирование в Python и зачем оно нужно
Логирование — это процесс автоматической записи информации о работе программы во внешние файлы или специальные сервисы. Особенно когда речь идет об ошибках — исключениях, которые программа не смогла обработать нормально.
Пример: если скрипт падает, лог должен содержать не просто “Ошибка!”, а минимум: тип исключения, строку и файл, где оно произошло, стек вызовов, параметры, с которыми вызвалась функция, и, по возможности, дополнительный контекст (например, имя пользователя или данные сессии). Это позволяет намного быстрее понять, что именно случилось на бою или в тестах, и где искать решение.
Встроенный модуль logging — это стандарт де-факто
Python из коробки предоставляет модуль logging, который крайне мощный, гибкий и без проблем настраивается под любые задачи. В самом простом варианте достаточно указать файл для записи и уровень логирования. При желании можно настраивать разные «обработчики» (handlers), когда одни записи идут в файл, другие — в консоль, третьи — на удаленный сервер.
Пример минимальной настройки:
import logging
logging.basicConfig(filename='errors.log', level=logging.ERROR,
format='%(asctime)s %(levelname)s %(message)s')
try:
1 / 0
except Exception as e:
logging.error("Exception occurred", exc_info=True)
Здесь ключевое — параметр exc_info=True, который добавляет в лог подробный трейсбек.
Где обычно используется логирование ошибок
- В веб-приложениях — для анализа ошибок пользователей и багов сервера.
- В бэкап-скриптах и автоматизации — чтобы понять, что пошло не так в задании.
- В консольных утилитах, которые работают в батчах и не имеют GUI.
- В системах мониторинга и аналитики, где логи идут в централизованные хранилища (ELK, Graylog и т.п.).
Без нормального логирования практически невозможно поддерживать серьезные проекты, особенно если они работают без постоянного контроля и вмешательства человека.
На что обратить внимание, чтобы не напортачить
1. Уровень логирования
Часто новички ставят уровень DEBUG или INFO на продакшн, из-за чего логи быстро разрастаются и забивают диск. Ошибки обычно логируют с уровнем ERROR или CRITICAL. Остальное — по ситуации.
2. Формат и содержимое лога
Важно включать timestamp, уровень, сообщение и, если это ошибка — стек вызовов. Полезно добавлять идентификаторы пользователя, сессии, параметры вызовов функций — чтобы было легче анализировать.
3. Ротация файлов
Никогда не оставляйте логи без ограничения по размеру или времени. Для этого есть RotatingFileHandler или TimedRotatingFileHandler.
4. Не блокировать основной поток
Если логирование идет часто и много, иногда стоит использовать асинхронные обработчики (например, через queue), чтобы логирование не тормозило программу.
5. Не игнорировать ошибки в логировании
Да, и такое бывает — если неправильно сконфигурировать логгеры, сообщения могут просто пропадать. После настройки рекомендуется протестировать.
Расширенные примеры
Вот пример настройки логирования с ротацией и несколькими обработчиками:
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger('myapp')
logger.setLevel(logging.ERROR)
# Обработчик для записи в файл с ротацией
file_handler = RotatingFileHandler('app.log', maxBytes=1024*1024, backupCount=3)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(module)s:%(lineno)d %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
# Обработчик для вывода ошибок в консоль
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.ERROR)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
try:
x = int('abc')
except Exception:
logger.error("Failed to convert string to int", exc_info=True)
Чек-лист перед настройкой логирования ошибок
- Понял, зачем и какую информацию нужно логировать
- Выбрал правильный уровень логов (ERROR или выше для ошибок)
- Настроил формат вывода с датой, временем и трассировкой
- Организовал ротацию файлов, чтобы логи не заполнили диск
- Протестировал, что ошибки действительно пишутся и читаются
- При необходимости добавил контекст (пользователь, сессия и пр.)
- Если логи важны — продумал стратегии бэкапа и хранения
Типичные ошибки новичков при логировании ошибок в Python
- Логировать только сообщение без exc_info — теряется важный стек вызовов
- Использовать print вместо нормального логирования в production
- Не ограничивать размер логов, из-за чего логи разрастаются и ломают диск
- Писать слишком много логов в уровень ERROR (например, обычные предупреждения)
- Игнорировать ошибки настройки логгера и не проверять, что записи пишутся
- Пытаться логировать объекты без явного преобразования в строки, что вызывает ошибки
- Не учитывать многопоточность/мультипроцессность при записи в общий файл
FAQ
1) Почему в логе нет информации об исключении?
Проверь, передаешь ли в logging.error/exception параметр exc_info=True. Без него будет только текст, но не стек.
2) Как логировать ошибки с асинхронного кода (asyncio)?
В целом — так же, но лучше использовать asyncio-совместимые логгеры или обрабатывать ошибки в корутинах с вызовом логгера.
3) Как быстро тестировать логирование?
Просто намеренно вызови ошибку в try-except и посмотри, что она записалась в нужный файл.
4) Можно ли логировать не в файл, а в базу или удаленный сервис?
Да, для этого существуют специальные обработчики или сторонние библиотеки. В стандартном logging можно написать свой handler.
5) Что делать, если логирование сильно замедляет программу?
Попробуй асинхронные обработчики, отправку логов в очередь или уменьшение детализации логов в продакшене.
Надеюсь, эта тема поможет тем, кто еще ковыряется с логированием в Python. Делитесь своими наработками, советами и вопросами — вместе сделаем код более надежным и удобным для поддержки.
Если пишешь на Python, рано или поздно сталкиваешься с задачей логирования ошибок. Просто писать print в except-блоке — это удобно для быстрого отлова, но на больших проектах или если скрипты работают в продакшене, такой подход абсолютно не подходит. Нужно записывать все ошибки в надежный журнал, чтобы потом не гадать, что сломалось, когда и почему. В этой теме хочу поделиться опытом, как организовать логирование ошибок в Python, какие инструменты существуют, какие моменты нужно учитывать и как не напортачить.
Что такое логирование в Python и зачем оно нужно
Логирование — это процесс автоматической записи информации о работе программы во внешние файлы или специальные сервисы. Особенно когда речь идет об ошибках — исключениях, которые программа не смогла обработать нормально.
Пример: если скрипт падает, лог должен содержать не просто “Ошибка!”, а минимум: тип исключения, строку и файл, где оно произошло, стек вызовов, параметры, с которыми вызвалась функция, и, по возможности, дополнительный контекст (например, имя пользователя или данные сессии). Это позволяет намного быстрее понять, что именно случилось на бою или в тестах, и где искать решение.
Встроенный модуль logging — это стандарт де-факто
Python из коробки предоставляет модуль logging, который крайне мощный, гибкий и без проблем настраивается под любые задачи. В самом простом варианте достаточно указать файл для записи и уровень логирования. При желании можно настраивать разные «обработчики» (handlers), когда одни записи идут в файл, другие — в консоль, третьи — на удаленный сервер.
Пример минимальной настройки:
import logging
logging.basicConfig(filename='errors.log', level=logging.ERROR,
format='%(asctime)s %(levelname)s %(message)s')
try:
1 / 0
except Exception as e:
logging.error("Exception occurred", exc_info=True)
Здесь ключевое — параметр exc_info=True, который добавляет в лог подробный трейсбек.
Где обычно используется логирование ошибок
- В веб-приложениях — для анализа ошибок пользователей и багов сервера.
- В бэкап-скриптах и автоматизации — чтобы понять, что пошло не так в задании.
- В консольных утилитах, которые работают в батчах и не имеют GUI.
- В системах мониторинга и аналитики, где логи идут в централизованные хранилища (ELK, Graylog и т.п.).
Без нормального логирования практически невозможно поддерживать серьезные проекты, особенно если они работают без постоянного контроля и вмешательства человека.
На что обратить внимание, чтобы не напортачить
1. Уровень логирования
Часто новички ставят уровень DEBUG или INFO на продакшн, из-за чего логи быстро разрастаются и забивают диск. Ошибки обычно логируют с уровнем ERROR или CRITICAL. Остальное — по ситуации.
2. Формат и содержимое лога
Важно включать timestamp, уровень, сообщение и, если это ошибка — стек вызовов. Полезно добавлять идентификаторы пользователя, сессии, параметры вызовов функций — чтобы было легче анализировать.
3. Ротация файлов
Никогда не оставляйте логи без ограничения по размеру или времени. Для этого есть RotatingFileHandler или TimedRotatingFileHandler.
4. Не блокировать основной поток
Если логирование идет часто и много, иногда стоит использовать асинхронные обработчики (например, через queue), чтобы логирование не тормозило программу.
5. Не игнорировать ошибки в логировании
Да, и такое бывает — если неправильно сконфигурировать логгеры, сообщения могут просто пропадать. После настройки рекомендуется протестировать.
Расширенные примеры
Вот пример настройки логирования с ротацией и несколькими обработчиками:
import logging
from logging.handlers import RotatingFileHandler
logger = logging.getLogger('myapp')
logger.setLevel(logging.ERROR)
# Обработчик для записи в файл с ротацией
file_handler = RotatingFileHandler('app.log', maxBytes=1024*1024, backupCount=3)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(module)s:%(lineno)d %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
# Обработчик для вывода ошибок в консоль
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.ERROR)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
try:
x = int('abc')
except Exception:
logger.error("Failed to convert string to int", exc_info=True)
Чек-лист перед настройкой логирования ошибок
- Понял, зачем и какую информацию нужно логировать
- Выбрал правильный уровень логов (ERROR или выше для ошибок)
- Настроил формат вывода с датой, временем и трассировкой
- Организовал ротацию файлов, чтобы логи не заполнили диск
- Протестировал, что ошибки действительно пишутся и читаются
- При необходимости добавил контекст (пользователь, сессия и пр.)
- Если логи важны — продумал стратегии бэкапа и хранения
Типичные ошибки новичков при логировании ошибок в Python
- Логировать только сообщение без exc_info — теряется важный стек вызовов
- Использовать print вместо нормального логирования в production
- Не ограничивать размер логов, из-за чего логи разрастаются и ломают диск
- Писать слишком много логов в уровень ERROR (например, обычные предупреждения)
- Игнорировать ошибки настройки логгера и не проверять, что записи пишутся
- Пытаться логировать объекты без явного преобразования в строки, что вызывает ошибки
- Не учитывать многопоточность/мультипроцессность при записи в общий файл
FAQ
1) Почему в логе нет информации об исключении?
Проверь, передаешь ли в logging.error/exception параметр exc_info=True. Без него будет только текст, но не стек.
2) Как логировать ошибки с асинхронного кода (asyncio)?
В целом — так же, но лучше использовать asyncio-совместимые логгеры или обрабатывать ошибки в корутинах с вызовом логгера.
3) Как быстро тестировать логирование?
Просто намеренно вызови ошибку в try-except и посмотри, что она записалась в нужный файл.
4) Можно ли логировать не в файл, а в базу или удаленный сервис?
Да, для этого существуют специальные обработчики или сторонние библиотеки. В стандартном logging можно написать свой handler.
5) Что делать, если логирование сильно замедляет программу?
Попробуй асинхронные обработчики, отправку логов в очередь или уменьшение детализации логов в продакшене.
Надеюсь, эта тема поможет тем, кто еще ковыряется с логированием в Python. Делитесь своими наработками, советами и вопросами — вместе сделаем код более надежным и удобным для поддержки.