Как я могу получить трассировку стека из LogRecord в Python? - PullRequest
0 голосов
/ 15 мая 2019

Я реализую пользовательский обработчик с Python. Естественно, мне нужно переопределить emit(self, record), чтобы сделать это. Пример:

from logging import Handler, LogRecord

class FooHandler(Handler):
    def emit(self, record: LogRecord):
        # handler logic

Как видите, каждый раз, когда я регистрирую что-либо с экземпляром Logger, это обеспечивает метод от LogRecord до emit.

Я вижу текущую реализацию LogRecord из источника CPython, вы также можете увидеть ее из здесь .

Предположим, у меня есть Logger экземпляр с именем logger. Позже где-нибудь в коде я делаю это:

# either this
logger.exception(Exception("foo"))
# it does not have to be an instance of Exception, it's for the sake of simplicity

# or this
logger.error("foo", exc_info=True)
# this also provides a stack trace on the console handler

Поскольку @thebjorn прокомментировал модуль traceback , я думаю, что могу обойти это. Однако сейчас у меня есть три вопроса:

  1. Как получить исключение из LogRecord instance?
  2. Если я сделаю logger.error("message", exc_info=True), я не пропущу ни одного экземпляра исключения. В таком случае, как мне получить трассировку, поскольку у меня просто нет экземпляра исключения?

Заранее спасибо.

Окружающая среда

  • Python 3.5 и выше

1 Ответ

1 голос
/ 15 мая 2019

Я - ОП, и это, возможно, не лучший ответ, на практике или более Pythonic, но для Google, есть метод.

Как @ thebjorn , заявленный вкомментарии к вопросу, вам нужен встроенный модуль traceback .

Затем вам нужно убедиться, что целевое исключение является последним исключением, созданным вашим программным обеспечением.Затем вы можете просто позвонить:

traceback.print_last()

Если исключений нет, вы получите строку ниже:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python3.7/traceback.py", line 173, in print_last
    raise ValueError("no last exception")
ValueError: no last exception

В противном случае вы получите трассировку последнего исключения.:

raise Exception("foo")
traceback.print_last()

# will return a string similar to below

Traceback (most recent call last):
  File "/foo/bar/baz.py", line 3296, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "/foo/bar/biz.py", line 1, in <module>
    raise Exception("foo")
Exception: foo

Надеюсь, что это поможет Google.

Что нужно знать

Как я уже говорил, вам нужно убедиться, последнее возникшее исключение - это исключение, на которое вы нацелены.Это не может быть жизнеспособным решением

  • для многопоточной кодовой базы , потому что вы должны быть очень осторожны с тем, в каком потоке работает ваш код, или
  • aкодовая база, которая структурирована на фреймворке, таком как Django , потому что обработка исключений в таких фреймворках может быть довольно сложной, и вы можете получить другое исключение, нежели то, которое вы исключали, чтобы получить
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...