diff --git a/screenless/bureau/bureau.py b/screenless/bureau/bureau.py index 7324bb8..f4a6533 100644 --- a/screenless/bureau/bureau.py +++ b/screenless/bureau/bureau.py @@ -7,9 +7,9 @@ import os.path import random import string import subprocess -import sys import tempfile import textwrap +#import traceback import threading import lmdb @@ -60,6 +60,19 @@ def add_api(apistr, name=""): return decorator +#def log_traceback(func): +# """ this is a decorator that catches tracebacks for logging""" +# def wrapper(*args): +# my_bureau = args[0] +# try: +# func(*args) +# except Exception as e: +# my_bureau.log.error("CRASH TRACE: {0}".format(my_bureau.name), +# exc_info=e) +# raise +# return wrapper + + class LogPrinter(logging.Handler): """ LogPrinter prints logs on a receipt printer for screenless debugging. @@ -151,11 +164,6 @@ class Bureau(object): self.api = {} modpath = os.path.dirname(__file__) - #slimerjs = os.path.join(modpath, "..", "lib", "slimerjs", "slimerjs") - #renderer = os.path.join(modpath, "..", "slimerjs", "rasterize.js") - #self.slimerjs = os.path.abspath(slimerjs) - #self.html2pdf = self.slimerjs + " --headless " + \ - # os.path.abspath(renderer) + " " mypath = inspect.getfile(self.__class__) self.mdir = os.path.dirname(mypath) @@ -181,7 +189,6 @@ class Bureau(object): log_format = logging.Formatter('LOG ${levelname} $name: $message', style='$') log_printer.setFormatter(log_format) self.log.addHandler(log_printer) - sys.excepthook = self._log_exception # setup a dir to store files and data self.datadir = os.path.join(basepath, self.prefix) @@ -200,9 +207,9 @@ class Bureau(object): self.log.debug("commands: ") self.log.debug(str(self.commands)) - def _log_exception(typ, value, tb): - self.log.error("CRASH TRACE: {0}".format(str(value)), exc_info=(typ, value, tb)) - sys.__excepthook__(typ, value, tb) +# def _log_exception(typ, value, tb): +# self.log.error("CRASH TRACE: {0}".format(str(value)), exc_info=(typ, value, tb)) +# sys.__excepthook__(typ, value, tb) def open_db(self, name): """ @@ -361,6 +368,16 @@ class Bureau(object): print(("hi! testing. " + self.name + " bureau seems to work!")) return "seems to work." + def _run_io(self): + """ + wrapper for run_io so that we can catch threaded exceptions and log + """ + try: + self.run_io() + except Exception as err: + self.log.exception("%s CRASHED with %s\n", self.name, err) + raise + def run_io(self): """process hardware or timed input @@ -375,6 +392,16 @@ class Bureau(object): pass def run(self): + """ + wrapper running the main loop and logging all exceptions + """ + try: + self._run() + except Exception as err: + self.log.exception("%s CRASHED with %s\n", self.name, err) + raise + + def _run(self): """ main loop for processing messages @@ -382,7 +409,7 @@ class Bureau(object): """ # start the hardware input handler - io_handler = threading.Thread(target=self.run_io) + io_handler = threading.Thread(target=self._run_io) io_handler.start() # register commands and api methods @@ -398,10 +425,6 @@ class Bureau(object): msg = self._recv.recv_string(flags=zmq.NOBLOCK) else: continue - # msg = self._recv.recv_string(flags=zmq.NOBLOCK) - #except zmq.ZMQError: - # time.sleep(0.05) # don't waste CPU - # continue try: self.log.debug("got message:" + msg) dot = msg.find(".") @@ -411,7 +434,6 @@ class Bureau(object): self.log.debug("dot at %d", dot) # TODO: maybe trim off the trailing "." for convenience data = msg[dot + 1:] - # data = str(data) # force to be a string else: data = None self.log.debug("data: " + str(data))