bpo-34334: Don't log traceback twice in QueueHandler (GH-9537) (GH-9581)

(cherry picked from commit d345bb4d9b6e16c681cd8a4e1fff94ecd6b0bb09)

Co-authored-by: Cheryl Sabella <cheryl.sabella@gmail.com>
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index 974c089..e213e43 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -1374,13 +1374,14 @@
         # (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):
diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py
index 13f49f6..5d5eba7 100644
--- a/Lib/test/test_logging.py
+++ b/Lib/test/test_logging.py
@@ -3278,6 +3278,21 @@
         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