]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.10] bpo-46755: Don't log stack info twice in QueueHandler (GH-31355) (GH-94565)
authorVinay Sajip <vinay_sajip@yahoo.co.uk>
Tue, 5 Jul 2022 15:04:29 +0000 (16:04 +0100)
committerGitHub <noreply@github.com>
Tue, 5 Jul 2022 15:04:29 +0000 (16:04 +0100)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
Doc/library/logging.handlers.rst
Lib/logging/handlers.py
Lib/test/test_logging.py
Misc/NEWS.d/next/Library/2022-02-15-12-40-48.bpo-46755.zePJfx.rst [new file with mode: 0644]

index a5b181ee612d5fd9489a3b53ff6ad3a2dd3d919d..1447cabb9a1df00f0672adede3d37fd970e223e1 100644 (file)
@@ -1034,8 +1034,12 @@ possible, while any potentially slow operations (such as sending an email via
       method is enqueued.
 
       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.
+      arguments, exception and stack information, if present.  It also removes
+      unpickleable items from the record in-place. Specifically, it overwrites
+      the record's :attr:`msg` and :attr:`message` attributes with the merged
+      message (obtained by calling the handler's :meth:`format` method), and
+      sets the :attr:`args`, :attr:`exc_info` and :attr:`exc_text` attributes
+      to ``None``.
 
       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
@@ -1047,7 +1051,13 @@ possible, while any potentially slow operations (such as sending an email via
       want to override this if you want to use blocking behaviour, or a
       timeout, or a customized queue implementation.
 
+   .. attribute:: listener
 
+      When created via configuration using :func:`~logging.config.dictConfig`, this
+      attribute will contain a :class:`QueueListener` instance for use with this
+      handler. Otherwise, it will be ``None``.
+
+      .. versionadded:: 3.12
 
 .. _queue-listener:
 
index 61a39958c0ac0b48e62503cd6b02dad7fbf51b93..b2d1f279225dfa5b889cadb484b4aa0521253c04 100644 (file)
@@ -1439,7 +1439,7 @@ 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 and exc_text attributes, as they are no longer
+        # exc_info, exc_text and stack_info attributes, as they are no longer
         # needed and, if not None, will typically not be pickleable.
         msg = self.format(record)
         # bpo-35726: make copy of record to avoid affecting other handlers in the chain.
@@ -1449,6 +1449,7 @@ class QueueHandler(logging.Handler):
         record.args = None
         record.exc_info = None
         record.exc_text = None
+        record.stack_info = None
         return record
 
     def emit(self, record):
index bdb1e7588b20b29fa953ef5c38a68fbd7226255e..af68f2582040e6ddd9ee424d73da77c35f52041f 100644 (file)
@@ -3598,7 +3598,7 @@ class QueueHandlerTest(BaseTest):
     @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).
+        # Test that traceback and stack-info only appends once (bpo-34334, bpo-46755).
         listener = logging.handlers.QueueListener(self.queue, self.root_hdlr)
         listener.start()
         try:
@@ -3606,8 +3606,10 @@ class QueueHandlerTest(BaseTest):
         except ZeroDivisionError as e:
             exc = e
             self.que_logger.exception(self.next_message(), exc_info=exc)
+        self.que_logger.error(self.next_message(), stack_info=True)
         listener.stop()
         self.assertEqual(self.stream.getvalue().strip().count('Traceback'), 1)
+        self.assertEqual(self.stream.getvalue().strip().count('Stack'), 1)
 
     @unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'),
                          'logging.handlers.QueueListener required for this test')
diff --git a/Misc/NEWS.d/next/Library/2022-02-15-12-40-48.bpo-46755.zePJfx.rst b/Misc/NEWS.d/next/Library/2022-02-15-12-40-48.bpo-46755.zePJfx.rst
new file mode 100644 (file)
index 0000000..399caf7
--- /dev/null
@@ -0,0 +1,2 @@
+In :class:`QueueHandler`, clear ``stack_info`` from :class:`LogRecord` to
+prevent stack trace from being written twice.