How can I log my Python errors?
try:
do_something()
except:
# How can I log my exception here, complete with its traceback?
How can I log my Python errors?
try:
do_something()
except:
# How can I log my exception here, complete with its traceback?
Use exc_info options may be better, remains warning or error title:
My job recently tasked me with logging all the tracebacks/exceptions from our application. I tried numerous techniques that others had posted online such as the one above but settled on a different approach. Overriding
traceback.print_exception
.I have a write up at http://www.bbarrows.com/ That would be much easier to read but Ill paste it in here as well.
When tasked with logging all the exceptions that our software might encounter in the wild I tried a number of different techniques to log our python exception tracebacks. At first I thought that the python system exception hook, sys.excepthook would be the perfect place to insert the logging code. I was trying something similar to:
This worked for the main thread but I soon found that the my sys.excepthook would not exist across any new threads my process started. This is a huge issue because most everything happens in threads in this project.
After googling and reading plenty of documentation the most helpful information I found was from the Python Issue tracker.
The first post on the thread shows a working example of the
sys.excepthook
NOT persisting across threads (as shown below). Apparently this is expected behavior.The messages on this Python Issue thread really result in 2 suggested hacks. Either subclass
Thread
and wrap the run method in our own try except block in order to catch and log exceptions or monkey patchthreading.Thread.run
to run in your own try except block and log the exceptions.The first method of subclassing
Thread
seems to me to be less elegant in your code as you would have to import and use your customThread
class EVERYWHERE you wanted to have a logging thread. This ended up being a hassle because I had to search our entire code base and replace all normalThreads
with this customThread
. However, it was clear as to what thisThread
was doing and would be easier for someone to diagnose and debug if something went wrong with the custom logging code. A custome logging thread might look like this:The second method of monkey patching
threading.Thread.run
is nice because I could just run it once right after__main__
and instrument my logging code in all exceptions. Monkey patching can be annoying to debug though as it changes the expected functionality of something. The suggested patch from the Python Issue tracker was:It was not until I started testing my exception logging I realized that I was going about it all wrong.
To test I had placed a
somewhere in my code. However, wrapping a a method that called this method was a try except block that printed out the traceback and swallowed the exception. This was very frustrating because I saw the traceback bring printed to STDOUT but not being logged. It was I then decided that a much easier method of logging the tracebacks was just to monkey patch the method that all python code uses to print the tracebacks themselves, traceback.print_exception. I ended up with something similar to the following:
This code writes the traceback to a String Buffer and logs it to logging ERROR. I have a custom logging handler set up the 'customLogger' logger which takes the ERROR level logs and send them home for analysis.
What I was looking for:
See:
maybe not as stylish, but easier:
Use
logging.exception
from with anexcept:
handler to log the current exception, prepended with a message.Now looking at the log file,
/tmp/logging_example.out
:Heres a simple example taken from the python 2.6 documentation: