How do I get the line number for a logging TypeError of "not all arguments converted during string formatting"?

StackOverflow https://stackoverflow.com/questions/18000985

Вопрос

If I'm using the built-in python logging mechanism and I make a mistake, such as:

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

Then I get an unhelpful error message:

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

Given I have a very large number of logging statements, is there any way to get a more helpful error message - one showing the line number where the mistake was made?

Это было полезно?

Решение

Thanks to Greg Smith, this is easy to do. Wherever the logging code is set up, do:

import logging

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

Somewhere in the stack trace will be the offending call to logger.debug. Note the caveat:

Note that just inserting an error handler like this isn't what you want to deploy, because an error in logging should introduce an application error. It's really more for making sure you get all your log messages correct in the first place. Make sure you read and following through understanding the comments about how handleError works later in the message thread before leaving this error dumping code in your app permanently.

Другие советы

In recent versions of Python, the information you want is printed. Consider the following script, 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()

When this is run with 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

With 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

So, you shouldn't have to resort to any tricks as suggested in Claudiu's answer, unless you are using an older version of Python.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top