Getting a more useful 'logging' module error output in python
python, python-3.x
Solution
Was just about to post this when Unutbu beat me to it. But here it is anyway:
You could try subclassing whichever handler you're using (example below using StreamHandler) and overiding the format method with a function that wraps it in a try: block
import traceback, logging
class MyStreamHandler(logging.StreamHandler):
def format(self, record):
try:
return logging.StreamHandler.format(self, record)
except TypeError:
# Print a stack trace that includes the original log call
traceback.print_stack()
if __name__ == "__main__":
log = logging.getLogger("testlogger")
handler = MyStreamHandler()
log.addHandler(handler)
log.error("Try interpolating an int correctly: %i", 1)
log.error("Now try passing a string to an int: %d", 'abc')
log.error("And then a string to a string %s", 'abc')
gives me:
Try interpolating an int correctly: 1
File "logtest2.py", line 19, in ?
log.error("Now try passing a string to an int: %d", 'abc')
File "/usr/lib64/python2.4/logging/__init__.py", line 999, in error
apply(self._log, (ERROR, msg, args), kwargs)
File "/usr/lib64/python2.4/logging/__init__.py", line 1079, in _log
self.handle(record)
File "/usr/lib64/python2.4/logging/__init__.py", line 1089, in handle
self.callHandlers(record)
File "/usr/lib64/python2.4/logging/__init__.py", line 1126, in callHandlers
hdlr.handle(record)
File "/usr/lib64/python2.4/logging/__init__.py", line 642, in handle
self.emit(record)
File "/usr/lib64/python2.4/logging/__init__.py", line 731, in emit
msg = self.format(record)
File "logtest2.py", line 8, in format
traceback.print_stack()
None
And then a string to a string abc
I wouldn't leave this in any production code, but it should help you find things like
log.error("%d", 'a string')
Problem
I am using the `logger` module of python (python version 3.x, but it should not matter) and I noticed that an error in a format string is reported as such: ``` Traceback (most recent call last): File "/usr/lib/python3.1/logging/__init__.py", line 770, in emit msg = self.format(record) File "/usr/lib/python3.1/logging/__init__.py", line 650, in format return fmt.format(record) File "/usr/lib/python3.1/logging/__init__.py", line 438, in format record.message = record.getMessage() File "/usr/lib/python3.1/logging/__init__.py", line 308, in getMessage msg = msg % self.args TypeError: %d format: a number is required, not str ``` As you can see, there is no mention of where the actual error (in my code) was. By the way, here's what was wrong in my code: ``` logging.debug('This is a string %d', str(foo)) ``` Changing the `%d` in `%s` solved the problem. My question is: how do I get some slightly more useful information from the `logging` module output? Do I have to write my own logger? Where do I tweak the `logger` module?