Как получить номер строки для регистрации TypeError не всех аргументов, преобразованных во время форматирования строки?

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

logger.debug("The result is", result)

Затем я получаю бесполезное сообщение об ошибке:

Traceback (most recent call last):
File "/usr/lib/python2.6/logging/__init__.py", line 760, in emit
msg = self.format(record)
File "/usr/lib/python2.6/logging/__init__.py", line 644, in format
return fmt.format(record)
File "/usr/lib/python2.6/logging/__init__.py", line 432, in format
record.message = record.getMessage()
File "/usr/lib/python2.6/logging/__init__.py", line 302, in getMessage
msg = msg % self.args
TypeError: not all arguments converted during string formatting

Учитывая, что у меня очень большое количество операторов регистрации, есть ли способ получить более полезное сообщение об ошибке, показывающее номер строки, в которой была допущена ошибка?


person Claudiu    schedule 01.08.2013    source источник


Ответы (2)


Благодаря Грегу Смиту это легко сделать. Везде, где настроен код ведения журнала, выполните:

import logging

def handleError(self, record):
    raise
logging.Handler.handleError = handleError

Где-то в трассировке стека будет оскорбительный вызов logger.debug. Обратите внимание на предостережение:

Обратите внимание, что просто вставить подобный обработчик ошибок — это не то, что вы хотите развернуть, потому что ошибка в журнале должна привести к ошибке приложения. Это действительно больше для того, чтобы убедиться, что вы правильно поняли все сообщения журнала. Убедитесь, что вы прочитали и поняли комментарии о том, как работает handleError, позже в потоке сообщений, прежде чем навсегда оставить этот код дампа ошибки в своем приложении.

person Claudiu    schedule 01.08.2013

В последних версиях Python нужная вам информация выводится на печать. Рассмотрим следующий сценарий, logex.py:

import logging

logger = logging.getLogger(__name__)

def test():
    logger.debug('The result is ', 'abc')

def main():
    test()

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    main()

Когда это запускается с Python 2.7:

$ python logex.py
Traceback (most recent call last):
  File "/usr/lib/python2.7/logging/__init__.py", line 842, in emit
    msg = self.format(record)
  File "/usr/lib/python2.7/logging/__init__.py", line 719, in format
    return fmt.format(record)
  File "/usr/lib/python2.7/logging/__init__.py", line 464, in format
    record.message = record.getMessage()
  File "/usr/lib/python2.7/logging/__init__.py", line 328, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Logged from file logex.py, line 6

С Python 3.2:

$ python3.2 logex.py
Traceback (most recent call last):
  File "/usr/lib/python3.2/logging/__init__.py", line 937, in emit
    msg = self.format(record)
  File "/usr/lib/python3.2/logging/__init__.py", line 812, in format
    return fmt.format(record)
  File "/usr/lib/python3.2/logging/__init__.py", line 551, in format
    record.message = record.getMessage()
  File "/usr/lib/python3.2/logging/__init__.py", line 319, in getMessage
    msg = msg % self.args
TypeError: not all arguments converted during string formatting
Logged from file logex.py, line 6

Таким образом, вам не нужно прибегать к каким-либо уловкам, предложенным в ответе Клаудиу, если только вы не используете более старую версию Python.

person Vinay Sajip    schedule 01.08.2013
comment
О, я не знал! Да, я использую Python 2.6. - person Claudiu; 02.08.2013