diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2016-11-11 20:22:39 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2016-11-12 22:53:43 -0500 |
commit | 1dee1ba64e52394446e8aa67a8418f066257a9a2 (patch) | |
tree | ede2123e397183bb68a7f25c907ee751d138c513 /klippy/queuelogger.py | |
parent | afecf7ce36d4d712413d8c90ac055baa51cb26bd (diff) | |
download | kutter-1dee1ba64e52394446e8aa67a8418f066257a9a2.tar.gz kutter-1dee1ba64e52394446e8aa67a8418f066257a9a2.tar.xz kutter-1dee1ba64e52394446e8aa67a8418f066257a9a2.zip |
queuelogger: Add support for background log writing
Writing to the debug log can cause an unbounded delay due to disk IO.
This is particularly so on embedded machines such as the Raspberry Pi
that run on SD cards. These log writing delays can cause problems for
the main processing threads.
The new "queuelogger" code forwards all the main thread log messages
to a queue, and a background thread writes the log messages from the
queue to the destination file. This eliminates the IO delay from the
main threads.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'klippy/queuelogger.py')
-rw-r--r-- | klippy/queuelogger.py | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/klippy/queuelogger.py b/klippy/queuelogger.py new file mode 100644 index 00000000..8494c6a8 --- /dev/null +++ b/klippy/queuelogger.py @@ -0,0 +1,48 @@ +# Code to implement asynchronous logging from a background thread +# +# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net> +# +# This file may be distributed under the terms of the GNU GPLv3 license. +import logging, threading, Queue + +# Class to forward all messages through a queue to a background thread +class QueueHandler(logging.Handler): + def __init__(self, queue): + logging.Handler.__init__(self) + self.queue = queue + def emit(self, record): + try: + self.format(record) + record.msg = record.message + record.args = None + record.exc_info = None + self.queue.put_nowait(record) + except Exception: + self.handleError(record) + +# Class to poll a queue in a background thread and log each message +class QueueListener(object): + def __init__(self, handler): + self.handler = handler + self.queue = Queue.Queue() + self.thread = threading.Thread(target=self._bg_thread) + self.thread.start() + def _bg_thread(self): + while 1: + record = self.queue.get(True) + if record is None: + break + self.handler.handle(record) + def stop(self): + self.queue.put_nowait(None) + self.thread.join() + +def setup_bg_logging(filename, debuglevel): + logoutput = open(filename, 'wb') + handler = logging.StreamHandler(logoutput) + ql = QueueListener(handler) + qh = QueueHandler(ql.queue) + root = logging.getLogger() + root.addHandler(qh) + root.setLevel(debuglevel) + return ql |