Added respect_handler_level to QueueListener.

This commit is contained in:
Vinay Sajip 2015-02-09 19:49:00 +00:00
parent 438f9134cf
commit 365701add9
5 changed files with 50 additions and 6 deletions

View File

@ -325,6 +325,15 @@ which, when run, will produce::
MainThread: Look out!
.. versionchanged:: 3.5
Prior to Python 3.5, the :class:`QueueListener` always passed every message
received from the queue to every handler it was initialized with. (This was
because it was assumed that level filtering was all done on the other side,
where the queue is filled.) From 3.5 onwards, this behaviour can be changed
by passing a keyword argument ``respect_handler_level=True`` to the
listener's constructor. When this is done, the listener compares the level
of each message with the handler's level, and only passes a message to a
handler if it's appropriate to do so.
.. _network-logging:

View File

@ -953,13 +953,20 @@ applications where threads servicing clients need to respond as quickly as
possible, while any potentially slow operations (such as sending an email via
:class:`SMTPHandler`) are done on a separate thread.
.. class:: QueueListener(queue, *handlers)
.. class:: QueueListener(queue, *handlers, respect_handler_level=False)
Returns a new instance of the :class:`QueueListener` class. The instance is
initialized with the queue to send messages to and a list of handlers which
will handle entries placed on the queue. The queue can be any queue-
like object; it's passed as-is to the :meth:`dequeue` method, which needs
to know how to get messages from it.
to know how to get messages from it. If ``respect_handler_level`` is ``True``,
a handler's level is respected (compared with the level for the message) when
deciding whether to pass messages to that handler; otherwise, the behaviour
is as in previous Python versions - to always pass each message to each
handler.
.. versionchanged:: 3.5
The ``respect_handler_levels`` argument was added.
.. method:: dequeue(block)

View File

@ -1,4 +1,4 @@
# Copyright 2001-2013 by Vinay Sajip. All Rights Reserved.
# Copyright 2001-2015 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
@ -18,7 +18,7 @@
Additional handlers for the logging package for Python. The core package is
based on PEP 282 and comments thereto in comp.lang.python.
Copyright (C) 2001-2013 Vinay Sajip. All Rights Reserved.
Copyright (C) 2001-2015 Vinay Sajip. All Rights Reserved.
To use, simply 'import logging.handlers' and log away!
"""
@ -1350,7 +1350,7 @@ if threading:
"""
_sentinel = None
def __init__(self, queue, *handlers):
def __init__(self, queue, *handlers, respect_handler_level=False):
"""
Initialise an instance with the specified queue and
handlers.
@ -1359,6 +1359,7 @@ if threading:
self.handlers = handlers
self._stop = threading.Event()
self._thread = None
self.respect_handler_level = respect_handler_level
def dequeue(self, block):
"""
@ -1399,7 +1400,12 @@ if threading:
"""
record = self.prepare(record)
for handler in self.handlers:
handler.handle(record)
if not self.respect_handler_level:
process = True
else:
process = record.levelno >= handler.level
if process:
handler.handle(record)
def _monitor(self):
"""

View File

@ -3006,6 +3006,25 @@ class QueueHandlerTest(BaseTest):
self.assertTrue(handler.matches(levelno=logging.WARNING, message='1'))
self.assertTrue(handler.matches(levelno=logging.ERROR, message='2'))
self.assertTrue(handler.matches(levelno=logging.CRITICAL, message='3'))
handler.close()
# Now test with respect_handler_level set
handler = support.TestHandler(support.Matcher())
handler.setLevel(logging.CRITICAL)
listener = logging.handlers.QueueListener(self.queue, handler,
respect_handler_level=True)
listener.start()
try:
self.que_logger.warning(self.next_message())
self.que_logger.error(self.next_message())
self.que_logger.critical(self.next_message())
finally:
listener.stop()
self.assertFalse(handler.matches(levelno=logging.WARNING, message='4'))
self.assertFalse(handler.matches(levelno=logging.ERROR, message='5'))
self.assertTrue(handler.matches(levelno=logging.CRITICAL, message='6'))
ZERO = datetime.timedelta(0)

View File

@ -13,6 +13,9 @@ Core and Builtins
Library
-------
- logging.handlers.QueueListener now takes a respect_handler_level keyword
argument which, if set to True, will pass messages to handlers taking handler
levels into account.
What's New in Python 3.5 alpha 1?
=================================