]> granicus.if.org Git - python/commitdiff
bpo-34334: Don't log traceback twice in QueueHandler (GH-9537)
authorCheryl Sabella <cheryl.sabella@gmail.com>
Tue, 25 Sep 2018 23:00:08 +0000 (19:00 -0400)
committerVinay Sajip <vinay_sajip@yahoo.co.uk>
Tue, 25 Sep 2018 23:00:08 +0000 (00:00 +0100)
Doc/library/logging.handlers.rst
Lib/logging/handlers.py
Lib/test/test_logging.py
Misc/NEWS.d/next/Library/2018-09-25-08-42-34.bpo-34334.rSPBW9.rst [new file with mode: 0644]

index bdf16a8177e99476bd98438abfc9fc9f9a629084..dee9a84e3337643e2429ce2dcca0ba5f679a05f7 100644 (file)
@@ -973,9 +973,9 @@ possible, while any potentially slow operations (such as sending an email via
       Prepares a record for queuing. The object returned by this
       method is enqueued.
 
-      The base implementation formats the record to merge the message
-      and arguments, and removes unpickleable items from the record
-      in-place.
+      The base implementation formats the record to merge the message,
+      arguments, and exception information, if present.  It also
+      removes unpickleable items from the record in-place.
 
       You might want to override this method if you want to convert
       the record to a dict or JSON string, or send a modified copy
index 974c089d40ec346eebd62dd063a232dcd4efd3c0..e213e438c31aa140f696fb69f4ee249762d521b1 100644 (file)
@@ -1374,13 +1374,14 @@ class QueueHandler(logging.Handler):
         # (if there's exception data), and also returns the formatted
         # message. We can then use this to replace the original
         # msg + args, as these might be unpickleable. We also zap the
-        # exc_info attribute, as it's no longer needed and, if not None,
-        # will typically not be pickleable.
+        # exc_info and exc_text attributes, as they are no longer
+        # needed and, if not None, will typically not be pickleable.
         msg = self.format(record)
         record.message = msg
         record.msg = msg
         record.args = None
         record.exc_info = None
+        record.exc_text = None
         return record
 
     def emit(self, record):
index b9dad64a5949c7bc619a284cbd3fde01f582b62a..d352e5fa3f3de69b6226734b7210695dd2a9c3ba 100644 (file)
@@ -3345,6 +3345,21 @@ class QueueHandlerTest(BaseTest):
         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'))
+        handler.close()
+
+    @unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'),
+                         'logging.handlers.QueueListener required for this test')
+    def test_queue_listener_with_StreamHandler(self):
+        # Test that traceback only appends once (bpo-34334).
+        listener = logging.handlers.QueueListener(self.queue, self.root_hdlr)
+        listener.start()
+        try:
+            1 / 0
+        except ZeroDivisionError as e:
+            exc = e
+            self.que_logger.exception(self.next_message(), exc_info=exc)
+        listener.stop()
+        self.assertEqual(self.stream.getvalue().strip().count('Traceback'), 1)
 
 if hasattr(logging.handlers, 'QueueListener'):
     import multiprocessing
diff --git a/Misc/NEWS.d/next/Library/2018-09-25-08-42-34.bpo-34334.rSPBW9.rst b/Misc/NEWS.d/next/Library/2018-09-25-08-42-34.bpo-34334.rSPBW9.rst
new file mode 100644 (file)
index 0000000..137a4f7
--- /dev/null
@@ -0,0 +1,2 @@
+In :class:`QueueHandler`, clear `exc_text` from :class:`LogRecord` to
+prevent traceback from being written twice.