I am trying to design a Python program that logs all uncaught exceptions using the logging module. I am doing this by using the sys.excepthook function to override the default exception handling. I noticed that if I run the program directly from the command line, it works fine, but if I try to import the file, it doesn't work. It seems like the sys.excepthook function is unaware of the logging module. Here is an example:
#! /usr/bin/env python2.7
import logging, sys
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.FileHandler("test.log"))
print "outside of exception handler: logger = %s" % logger
def handleException(excType, excValue, traceback):
#global logger # this function doesn't work whether or not I include this line
print "inside exception handler: logger = %s" % logger
logger.error("Uncaught exception", exc_info=(excType, excValue, traceback))
sys.excepthook = handleException
logger.debug("starting")
asdf # create an exception
If I run this from the command line (./loggingTest.py
), it works fine. The exception gets logged, and I see this output:
outside of exception handler: logger = <logging.RootLogger object at 0x7f2022eab950>
inside exception handler: logger = <logging.RootLogger object at 0x7f2022eab950>
However, if I run the Python interpreter and try to import the file (import loggingTest
), it acts strangely. The exception doesn't get logged and I see this:
outside of exception handler: logger = <logging.RootLogger object at 0x7f8ab04f3ad0>
inside exception handler: logger = None
Error in sys.excepthook:
Traceback (most recent call last):
File "loggingTest.py", line 13, in handleException
logger.error("Uncaught exception", exc_info=(excType, excValue, traceback))
AttributeError: 'NoneType' object has no attribute 'error'
Original exception was:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "loggingTest.py", line 18, in <module>
asdf # create an exception
NameError: name 'asdf' is not defined
I can maybe work around this problem by importing the logging module again within sys.excepthook, but I am still curious: why is this happening?
I reported this issue as a bug on the Python bug tracker. So far, someone responded that there is definitely a change between Python 2.7 and 2.7.1 and he thinks this is expected behavior. He suggested something like this to log all exceptions:
def handleException(excType, excValue, traceback, logger=logger):
logger.error("Uncaught exception", exc_info=(excType, excValue, traceback))
sys.excepthook = handleException
I can't reproduce your error, even if it happens in exhook.py
. This is exhook.py
:
#! /usr/bin/env python2.7
import logging, sys, traceback as tb
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.FileHandler("test.log"))
print "outside of exception handler: logger = %s" % logger
def handleException(excType, excValue, traceback):
#global logger # this function doesn't work whether or not I include this line
tb.print_exception(excType, excValue, traceback)
print "inside exception handler: logger = %s" % logger
logger.error("Uncaught exception", exc_info=(excType, excValue, traceback))
sys.excepthook = handleException
raise Exception
Then:
Python 2.7 (r27:82525, Jul 4 2010, 09:01:59) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import exhook
outside of exception handler: logger = <logging.RootLogger object at 0x02AB0A70>
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "exhook.py", line 18, in <module>
raise Exception
Exception inside exception handler: logger = <logging.RootLogger object at 0x02AB0A70>
It works just fine. Does this work for you?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With