[Python-checkins] cpython: Added respect_handler_level to QueueListener.

vinay.sajip python-checkins at python.org
Mon Feb 9 20:49:10 CET 2015


https://hg.python.org/cpython/rev/e548ab4ce71d
changeset:   94573:e548ab4ce71d
user:        Vinay Sajip <vinay_sajip at yahoo.co.uk>
date:        Mon Feb 09 19:49:00 2015 +0000
summary:
  Added respect_handler_level to QueueListener.

files:
  Doc/howto/logging-cookbook.rst   |   9 +++++++++
  Doc/library/logging.handlers.rst |  11 +++++++++--
  Lib/logging/handlers.py          |  14 ++++++++++----
  Lib/test/test_logging.py         |  19 +++++++++++++++++++
  Misc/NEWS                        |   3 +++
  5 files changed, 50 insertions(+), 6 deletions(-)


diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst
--- a/Doc/howto/logging-cookbook.rst
+++ b/Doc/howto/logging-cookbook.rst
@@ -325,6 +325,15 @@
 
     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
--- a/Doc/library/logging.handlers.rst
+++ b/Doc/library/logging.handlers.rst
@@ -953,13 +953,20 @@
 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
--- 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 @@
         """
         _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 @@
             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 @@
             """
             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
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -3006,6 +3006,25 @@
         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
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,6 +13,9 @@
 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?
 =================================

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list