summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinay Sajip <vinay_sajip@yahoo.co.uk>2015-02-09 19:49:00 (GMT)
committerVinay Sajip <vinay_sajip@yahoo.co.uk>2015-02-09 19:49:00 (GMT)
commit365701add94255d753d555c6b3833dd8cc6d43a0 (patch)
treeb4f6639641bfd98ca65bb73ef2227351d5c317ed
parent438f9134cfb7a3b68cff9de9f730f42f68c2cc94 (diff)
downloadcpython-365701add94255d753d555c6b3833dd8cc6d43a0.zip
cpython-365701add94255d753d555c6b3833dd8cc6d43a0.tar.gz
cpython-365701add94255d753d555c6b3833dd8cc6d43a0.tar.bz2
Added respect_handler_level to QueueListener.
-rw-r--r--Doc/howto/logging-cookbook.rst9
-rw-r--r--Doc/library/logging.handlers.rst11
-rw-r--r--Lib/logging/handlers.py14
-rw-r--r--Lib/test/test_logging.py19
-rw-r--r--Misc/NEWS3
5 files changed, 50 insertions, 6 deletions
diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
index 57e23f9..e31b6c2 100644
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -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:
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst
index 48c57cf..67403a9 100644
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -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)
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index c67ac99..d4f8aef 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -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):
"""
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 9674322..c8b6a98 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -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)
diff --git a/Misc/NEWS b/Misc/NEWS
index 9175fe5..b34ff5c 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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?
=================================