function: Add except hook for threads

This will log exceptions on different threads
This commit is contained in:
Jordan Ruthe 2021-05-02 17:48:04 -04:00
parent 7b6efa0521
commit c2c4e9c42e
2 changed files with 25 additions and 1 deletions

View File

@ -1,8 +1,11 @@
import logging import logging
import logging.handlers import logging.handlers
import os import os
import re
import subprocess import subprocess
import sys import sys
import threading
import time
import traceback import traceback
from queue import SimpleQueue as Queue from queue import SimpleQueue as Queue
@ -66,6 +69,24 @@ def get_software_version():
logging.exception("Error runing git describe") logging.exception("Error runing git describe")
return "?" return "?"
def patch_threading_excepthook():
"""Installs our exception handler into the threading modules Thread object
Inspired by https://bugs.python.org/issue1230540
"""
old_init = threading.Thread.__init__
def new_init(self, *args, **kwargs):
old_init(self, *args, **kwargs)
old_run = self.run
def run_with_excepthook(*args, **kwargs):
try:
old_run(*args, **kwargs)
except (KeyboardInterrupt, SystemExit):
raise
except:
sys.excepthook(*sys.exc_info(), thread_identifier=threading.get_ident())
self.run = run_with_excepthook
threading.Thread.__init__ = new_init
# Timed rotating file handler based on Klipper and Moonraker's implementation # Timed rotating file handler based on Klipper and Moonraker's implementation
class KlipperScreenLoggingHandler(logging.handlers.TimedRotatingFileHandler): class KlipperScreenLoggingHandler(logging.handlers.TimedRotatingFileHandler):
def __init__(self, software_version, filename, **kwargs): def __init__(self, software_version, filename, **kwargs):
@ -113,8 +134,9 @@ def setup_logging(log_file, software_version):
queue, stdout_hdlr) queue, stdout_hdlr)
listener.start() listener.start()
def logging_exception_handler(type, value, tb): def logging_exception_handler(type, value, tb, thread_identifier=None):
logging.exception("Uncaught exception %s: %s\nTraceback: %s" % (type, value, "\n".join(traceback.format_tb(tb)))) logging.exception("Uncaught exception %s: %s\nTraceback: %s" % (type, value, "\n".join(traceback.format_tb(tb))))
sys.excepthook = logging_exception_handler sys.excepthook = logging_exception_handler
logging.captureWarnings(True)
return listener, fh return listener, fh

View File

@ -745,6 +745,8 @@ def main():
version version
) )
functions.patch_threading_excepthook()
logging.info("KlipperScreen version: %s" % version) logging.info("KlipperScreen version: %s" % version)