@@ -2651,12 +2651,18 @@ The :class:`QueueHandler` class, located in the :mod:`logging.handlers` module,
26512651supports sending logging messages to a queue, such as those implemented in the
26522652:mod: `queue ` or :mod: `multiprocessing ` modules.
26532653
2654+ Along with the :class: `QueueListener ` class, :class: `QueueHandler ` can be used
2655+ to let handlers do their work on a separate thread from the one which does the
2656+ logging. This is important in Web applications and also other service
2657+ applications where threads servicing clients need to respond as quickly as
2658+ possible, while any potentially slow operations (such as sending an email via
2659+ :class: `SMTPHandler `) are done on a separate thread.
26542660
26552661.. class :: QueueHandler(queue)
26562662
26572663 Returns a new instance of the :class: `QueueHandler ` class. The instance is
26582664 initialized with the queue to send messages to. The queue can be any queue-
2659- like object; it's passed as-is to the :meth: `enqueue ` method, which needs
2665+ like object; it's used as-is by the :meth: `enqueue ` method, which needs
26602666 to know how to send messages to it.
26612667
26622668
@@ -2688,8 +2694,80 @@ supports sending logging messages to a queue, such as those implemented in the
26882694
26892695The :class: `QueueHandler ` class was not present in previous versions.
26902696
2697+ .. queue-listener:
2698+
2699+ QueueListener
2700+ ^^^^^^^^^^^^^
2701+
2702+ The :class: `QueueListener ` class, located in the :mod: `logging.handlers `
2703+ module, supports receiving logging messages from a queue, such as those
2704+ implemented in the :mod: `queue ` or :mod: `multiprocessing ` modules. The
2705+ messages are received from a queue in an internal thread and passed, on
2706+ the same thread, to one or more handlers for processing.
2707+
2708+ Along with the :class: `QueueHandler ` class, :class: `QueueListener ` can be used
2709+ to let handlers do their work on a separate thread from the one which does the
2710+ logging. This is important in Web applications and also other service
2711+ applications where threads servicing clients need to respond as quickly as
2712+ possible, while any potentially slow operations (such as sending an email via
2713+ :class: `SMTPHandler `) are done on a separate thread.
2714+
2715+ .. class :: QueueListener(queue, *handlers)
2716+
2717+ Returns a new instance of the :class: `QueueListener ` class. The instance is
2718+ initialized with the queue to send messages to and a list of handlers which
2719+ will handle entries placed on the queue. The queue can be any queue-
2720+ like object; it's passed as-is to the :meth: `dequeue ` method, which needs
2721+ to know how to get messages from it.
2722+
2723+ .. method :: dequeue(block)
2724+
2725+ Dequeues a record and return it, optionally blocking.
2726+
2727+ The base implementation uses ``get() ``. You may want to override this
2728+ method if you want to use timeouts or work with custom queue
2729+ implementations.
2730+
2731+ .. method :: prepare(record)
2732+
2733+ Prepare a record for handling.
2734+
2735+ This implementation just returns the passed-in record. You may want to
2736+ override this method if you need to do any custom marshalling or
2737+ manipulation of the record before passing it to the handlers.
2738+
2739+ .. method :: handle(record)
2740+
2741+ Handle a record.
2742+
2743+ This just loops through the handlers offering them the record
2744+ to handle. The actual object passed to the handlers is that which
2745+ is returned from :meth: `prepare `.
2746+
2747+ .. method :: start()
2748+
2749+ Starts the listener.
2750+
2751+ This starts up a background thread to monitor the queue for
2752+ LogRecords to process.
2753+
2754+ .. method :: stop()
2755+
2756+ Stops the listener.
2757+
2758+ This asks the thread to terminate, and then waits for it to do so.
2759+ Note that if you don't call this before your application exits, there
2760+ may be some records still left on the queue, which won't be processed.
2761+
2762+ .. versionadded :: 3.2
2763+
2764+ The :class: `QueueListener ` class was not present in previous versions.
2765+
26912766.. _zeromq-handlers :
26922767
2768+ Subclassing QueueHandler
2769+ ^^^^^^^^^^^^^^^^^^^^^^^^
2770+
26932771You can use a :class: `QueueHandler ` subclass to send messages to other kinds
26942772of queues, for example a ZeroMQ "publish" socket. In the example below,the
26952773socket is created separately and passed to the handler (as its 'queue')::
@@ -2716,6 +2794,7 @@ data needed by the handler to create the socket::
27162794 def __init__(self, uri, socktype=zmq.PUB, ctx=None):
27172795 self.ctx = ctx or zmq.Context()
27182796 socket = zmq.Socket(self.ctx, socktype)
2797+ socket.bind(uri)
27192798 QueueHandler.__init__(self, socket)
27202799
27212800 def enqueue(self, record):
@@ -2725,6 +2804,23 @@ data needed by the handler to create the socket::
27252804 def close(self):
27262805 self.queue.close()
27272806
2807+ Subclassing QueueListener
2808+ ^^^^^^^^^^^^^^^^^^^^^^^^^
2809+
2810+ You can also subclass :class: `QueueListener ` to get messages from other kinds
2811+ of queues, for example a ZeroMQ "subscribe" socket. Here's an example::
2812+
2813+ class ZeroMQSocketListener(QueueListener):
2814+ def __init__(self, uri, *handlers, **kwargs):
2815+ self.ctx = kwargs.get('ctx') or zmq.Context()
2816+ socket = zmq.Socket(self.ctx, zmq.SUB)
2817+ socket.setsockopt(zmq.SUBSCRIBE, '') # subscribe to everything
2818+ socket.connect(uri)
2819+
2820+ def dequeue(self):
2821+ msg = self.queue.recv()
2822+ return logging.makeLogRecord(json.loads(msg))
2823+
27282824.. _formatter-objects :
27292825
27302826Formatter Objects
0 commit comments