![]() |
Как логировать ошибки в Python-скриптах — кто сталкивался?
Логирование ошибок — тема, которая рано или поздно становится актуальной для любого, кто пишет на Python хоть немного серьёзнее, чем "привет мир". Когда код начинает расти, с ним появляются баги и непонятные ситуации, которые не всегда видны в консоли при запуске. Без нормального логирования проще потеряться и тратить огромные кучи времени на поиск проблемы. Делюсь своим опытом и сборной информацией, надеюсь, кому-то пригодится.
Что такое логирование в Python и зачем оно нужно По сути, логирование — это процесс записи информации о том, что происходит внутри кода во время его выполнения. Это не просто вывод текста, а определённая система, которая помогает отлавливать ошибки, предупреждения, полезные сообщения и другие события. Благодаря логам можно понять, где и почему программа упала, какова последовательность действий и даже что происходило непосредственно перед сбоем. В Python для этого чаще всего используют стандартный модуль logging. Он мощный, гибкий и не требует установки сторонних пакетов. Есть возможность настраивать уровни важности сообщений, задавать разные выводы — в файл, в консоль, на удалённые сервера. У каждого события в логах есть уровень «severity»: DEBUG, INFO, WARNING, ERROR, CRITICAL. Это помогает фильтровать и быстро находить нужные записи. Кому и где это нужно Логирование пригодится, когда: - проект становится больше одного файла и простого запуска из консоли уже недостаточно; - пишешь веб-приложения на Flask, Django или других фреймворках: там ошибки могут быть как в коде, так и из-за внешних факторов — например, база данных упала; - автоматизируешь процессы — скрипты могут работать на сервере или в фоне, и следить за ними руками неудобно; - готовишь стабильное приложение для пользователей, где важно, чтобы программа не просто зависала, а сообщала о проблемах и быстро их решала. Пример базового логирования Самый простой способ начать — импортировать logging и настроить его: import logging logging.basicConfig(level=logging.ERROR, filename='app.log', format='%(asctime)s - %(levelname)s - %(message)s') try: 1 / 0 except ZeroDivisionError as e: logging.error("Ошибка деления на ноль: %s", e) Что здесь происходит? Все ошибки уровня ERROR и выше пишутся в файл app.log, в удобном формате с временем и уровнем. Если запустить скрипт, в файле появится запись с описанием исключения. Более продвинутый пример с несколькими обработчиками Часто хочется видеть часть логов в консоли, а часть писать в файл. Можно добавить два обработчика (handlers): logger = logging.getLogger('my_app') logger.setLevel(logging.DEBUG) # Создаём обработчик для файла fh = logging.FileHandler('app.log') fh.setLevel(logging.ERROR) # Обработчик для консоли ch = logging.StreamHandler() ch.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) ch.setFormatter(formatter) logger.addHandler(fh) logger.addHandler(ch) logger.info("Приложение запущено") logger.error("Какое-то критическое исключение!") Такой подход даёт большую гибкость: важные сообщения можно видеть сразу в терминале, а более серьёзные ошибки сохранять отдельно. Чек-лист для правильного логирования - Используй разные уровни логов (DEBUG, INFO, WARNING, ERROR, CRITICAL) в зависимости от важности сообщения. - Не пиши слишком много логов уровня DEBUG в продакшене — это может перегрузить диск и затруднить чтение. - Форматируй логи так, чтобы была дата, время, уровень и текст — это поможет искать по времени. - Если приложение многопоточное или мультипроцессное — учитывай, что логирование должно быть потокобезопасным. - Настраивай ротацию логов (например, RotatingFileHandler), чтобы не накапливались гигабайты старых записей. - Для веб-сервисов добавляй в логи информацию о запросах, сессиях, пользователях — это сильно помогает в анализе проблем. - Не записывай в логи чувствительные данные, пароли и другую приватную информацию. Типичные ошибки при логировании - Просто print() вместо нормального логирования. Это быстро, но неудобно и плохо масштабируется. - Настройка logging.basicConfig несколько раз в одном приложении — это не работает, и логируется только первая настройка, что часто сбивает с толку. - Логи слишком громоздкие или, наоборот, слишком короткие и ничего не говорят о проблеме. - Не учитывание многопоточности — иногда логи идут в кашу или теряются. - Отсутствие ротации — файл растёт бесконечно, потом места на диске не хватает. - Логирование без исключений — просто "что-то пошло не так" без детализации, что именно. - Использование очень низкого уровня логов в продакшене (например DEBUG) — плохо влияет на производительность. FAQ по логированию на Python 1. Как правильно захватывать исключения для логирования? Лучше всего использовать конструкцию try-except и внутри блока except писать logging.error("Текст ошибки", exc_info=True), чтобы вместе с сообщением в лог попадал и traceback. 2. Нужно ли логировать каждое событие в программе? Не обязательно. Логи нужны, чтобы отслеживать важные действия и ошибки. Слишком много логов создаёт шум и мешает видеть суть. 3. Чем rotative logging отличается от обычного? RotatingFileHandler позволяет автоматически создавать новый лог-файл при достижении определённого размера или по времени, чтобы не засорять диск. 4. Можно ли писать логи в базу данных? Можно, но чаще это усложняет настройку. Есть внешние системы сбора логов (например, ELK, Graylog), куда логи удобнее отправлять через специальные агенты. 5. Почему иногда лог-файл не создаётся? Чаще всего из-за неправильных прав доступа или ошибки в пути к файлу. 6. Как логировать в JSON-формате? Нужно использовать сторонние библиотеки или писать собственный форматтер, чтобы формировать вывод в JSON. Это удобно для последующей обработки. Заключение Логирование — это не прихоть, а необходимость, особенно если программа неидеальна (а это почти всегда). Если с самого начала подключить нормальный логгер, то отлавливать и исправлять ошибки станет гораздо легче. Да и при поддержке кода потом не придется всё находить методом тыка. Со временем можно усложнять настройки, добавлять удалённый сбор, интеграции с мониторингом — всё зависит от задач и масштаба проекта. В общем, делитесь опытом и приколами с логированием, что работает, а что нет. Может вместе ещё что-то дельное придумаем. |
| Время: 12:09 |