Логирование исключений с трассировкой в Python: практики

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для логирования исключений в Python рекомендуется использовать модуль logging. В блоке except обработчика исключений try/except применяйте метод logging.exception(), что обеспечивает автоматическую запись информации об исключениях и их трассировку.

Python
Скопировать код
import logging

logging.basicConfig(level=logging.ERROR)  # Определяем уровень логирования ERROR

try:
    problematic_operation()  # Код, способный вызвать исключение
except Exception:
    logging.exception("Возникло исключение")  # Фиксируем исключение

Такой подход гарантирует сохранение информации о возникших ошибках вместе с их трассировкой в лог-файле.

Настройка логгера

Модуль logging предлагает широкие возможности для настройки параметров логирования. Функция logging.basicConfig позволяет задать файл для хранения логов и уровень логирования. Для детального анализа ошибок стоит установить уровень DEBUG.

Python
Скопировать код
logging.basicConfig(filename='app.log', filemode='w', level=logging.DEBUG)

Приведенная команда создаст файл app.log, который будет перезаписываться при каждом запуске программы, и будет вести запись всех сообщений, начиная с уровня DEBUG.

Перехват и логирование неперехваченных исключений

sys.excepthook — мощный инструмент для перехвата исключений, которые ускользнули от стандартной обработки, это особенно актуально для многопоточных приложений.

Python
Скопировать код
import sys

def handle_exception(exc_type, exc_value, exc_traceback):
    logging.error("Неперехваченное исключение", exc_info=(exc_type, exc_value, exc_traceback))

sys.excepthook = handle_exception

Не забывайте использовать блок try-except в стартовой точке каждого потока для перехвата возникших исключений. В случае проблем при работе с многопоточностью обратите внимание на методы типа InstallThreadExcepthook.

Визуализация

Чтобы наглядно представить механизм логирования исключений, можно прибегнуть к детективной аналогии:

  1. Исключение — это подозрительное происшествие.
  2. Модуль logging действует в роли вашего детективного аналитика.
  3. Использование logger.exception() — это документирование доказательств непосредственно на месте события.
Python
Скопировать код
import logging
logger = logging.getLogger(__name__)

try:
    # Код, в котором может произойти ошибка
except Exception:
    logger.exception("Шерлок, мы столкнулись с проблемой!")

Каждая деталь существенна для глубокого понимания характера проблемы.

Многопоточность и пользовательские обработчики

Пользовательские обработчики логирования

Для более тонкой настройки системы логирования можно создавать собственные обработчики.

Python
Скопировать код
class CustomHandler(logging.Handler):
    # Ваш код для пользовательской обработки логов

logger.addHandler(CustomHandler())  # Добавляем пользовательский обработчик

Проблемы многопоточного логирования и их решения

Чтобы избежать путаницы в логах многопоточных приложений, можно переопределить метод run потока, добавив в него обработку исключений:

Python
Скопировать код
class MyThread(threading.Thread):
    def run(self):
        try:
            super().run()
        except Exception:
            logger.exception("Необходима уборка после вечеринки в потоке '%s'", self.name)
            raise

Полное логирование трассировки

Для сохранения полной трассировки используйте аргумент exc_info вместе с logging.error.

Python
Скопировать код
logging.error("Неожиданная ошибка!", exc_info=True)

Трассировка с контекстом

В сообщения лога можно включить контекстные пояснения, что сделает их более информативными.

Python
Скопировать код
except Exception as e:
    logging.exception("Обнаружено несоответствие: %s", e)

Форматирование для последующего анализа

Сообщения в логах должны быть структурированными и содержать информацию о дате, времени и важности сообщения, что облегчает их последующий анализ.

Python
Скопировать код
logging.basicConfig(
    format='%(asctime)s – %(name)s – %(levelname)s – %(message)s',
    datefmt='%m/%d/%Y %I:%M:%S %p',
    level=logging.DEBUG
)

Лучшие практики для идеального логирования

Соблюдение лучших практик логирования, таких как правильное использование raise, делает обработку ошибок более эффективной. Также стоит учитывать совместимость с актуальными версиями Python.

Полезные материалы

  1. logging — Ведение логов для Python — официальная документация.
  2. traceback — Обработка трассировок стека — подробное руководство по работе с трассировками.
  3. Логирование в Python – Real Python — обучающий материал о логировании.
  4. Книга рецептов логирования — Документация Python 3.12.2 — адвансированные приемы логирования.
  5. Хорошие практики логирования в Python – Заметки разработчика Фан Пен — советы для эффективного ведения логов.