62 lines
2.0 KiB
Python
62 lines
2.0 KiB
Python
from logging.config import ConvertingList, ConvertingDict, valid_ident
|
|
from logging.handlers import QueueHandler, QueueListener
|
|
from queue import Queue
|
|
import atexit
|
|
|
|
|
|
class QueueHandlerHelper:
|
|
|
|
@staticmethod
|
|
def resolve_handlers(l):
|
|
if not isinstance(l, ConvertingList):
|
|
return l
|
|
|
|
# Indexing the list performs the evaluation.
|
|
return [l[i] for i in range(len(l))]
|
|
|
|
@staticmethod
|
|
def resolve_queue(q):
|
|
if not isinstance(q, ConvertingDict):
|
|
return q
|
|
if '__resolved_value__' in q:
|
|
return q['__resolved_value__']
|
|
|
|
cname = q.pop('class')
|
|
klass = q.configurator.resolve(cname)
|
|
props = q.pop('.', None)
|
|
kwargs = {k: q[k] for k in q if valid_ident(k)}
|
|
result = klass(**kwargs)
|
|
if props:
|
|
for name, value in props.items():
|
|
setattr(result, name, value)
|
|
|
|
q['__resolved_value__'] = result
|
|
return result
|
|
|
|
|
|
# The guy from this video https://www.youtube.com/watch?v=9L77QExPmI0 is using logging features only available in 3.12
|
|
# This article had the class required to build the queue handler in 3.11
|
|
# https://rob-blackbourn.medium.com/how-to-use-python-logging-queuehandler-with-dictconfig-1e8b1284e27a
|
|
class QueueListenerHandler(QueueHandler):
|
|
|
|
def __init__(self, handlers, respect_handler_level=False, auto_run=True, queue=Queue(-1)):
|
|
queue = QueueHandlerHelper.resolve_queue(queue)
|
|
super().__init__(queue)
|
|
handlers = QueueHandlerHelper.resolve_handlers(handlers)
|
|
self._listener = QueueListener(
|
|
self.queue,
|
|
*handlers,
|
|
respect_handler_level=respect_handler_level)
|
|
if auto_run:
|
|
self.start()
|
|
atexit.register(self.stop)
|
|
|
|
def start(self):
|
|
self._listener.start()
|
|
|
|
def stop(self):
|
|
self._listener.stop()
|
|
|
|
def emit(self, record):
|
|
return super().emit(record)
|