diff options
author | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2022-07-05 15:04:29 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-05 15:04:29 (GMT) |
commit | 3287e45847a4d471e20425f0da5194ac5735e16c (patch) | |
tree | 527cf60e4b723a503f47c803c38599b01f9e5c7c | |
parent | 5bd56a030ddf19052f23194e7ff95b4b9144f94f (diff) | |
download | cpython-3287e45847a4d471e20425f0da5194ac5735e16c.zip cpython-3287e45847a4d471e20425f0da5194ac5735e16c.tar.gz cpython-3287e45847a4d471e20425f0da5194ac5735e16c.tar.bz2 |
[3.10] bpo-46755: Don't log stack info twice in QueueHandler (GH-31355) (GH-94565)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
-rw-r--r-- | Doc/library/logging.handlers.rst | 14 | ||||
-rw-r--r-- | Lib/logging/handlers.py | 3 | ||||
-rw-r--r-- | Lib/test/test_logging.py | 4 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2022-02-15-12-40-48.bpo-46755.zePJfx.rst | 2 |
4 files changed, 19 insertions, 4 deletions
diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index a5b181e..1447cab 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -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: diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 61a3995..b2d1f27 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -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): diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index bdb1e75..af68f25 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -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 index 0000000..399caf7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-02-15-12-40-48.bpo-46755.zePJfx.rst @@ -0,0 +1,2 @@ +In :class:`QueueHandler`, clear ``stack_info`` from :class:`LogRecord` to +prevent stack trace from being written twice. |