Skip to content

Commit d49159b

Browse files
[3.11] bpo-46755: Don't log stack info twice in QueueHandler (GH-31355) (GH-94564)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
1 parent 1bfe83a commit d49159b

File tree

4 files changed

+8
-3
lines changed

4 files changed

+8
-3
lines changed

Doc/library/logging.handlers.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -1034,7 +1034,7 @@ possible, while any potentially slow operations (such as sending an email via
10341034
method is enqueued.
10351035

10361036
The base implementation formats the record to merge the message,
1037-
arguments, and exception information, if present. It also removes
1037+
arguments, exception and stack information, if present. It also removes
10381038
unpickleable items from the record in-place. Specifically, it overwrites
10391039
the record's :attr:`msg` and :attr:`message` attributes with the merged
10401040
message (obtained by calling the handler's :meth:`format` method), and

Lib/logging/handlers.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1455,7 +1455,7 @@ def prepare(self, record):
14551455
# (if there's exception data), and also returns the formatted
14561456
# message. We can then use this to replace the original
14571457
# msg + args, as these might be unpickleable. We also zap the
1458-
# exc_info and exc_text attributes, as they are no longer
1458+
# exc_info, exc_text and stack_info attributes, as they are no longer
14591459
# needed and, if not None, will typically not be pickleable.
14601460
msg = self.format(record)
14611461
# bpo-35726: make copy of record to avoid affecting other handlers in the chain.
@@ -1465,6 +1465,7 @@ def prepare(self, record):
14651465
record.args = None
14661466
record.exc_info = None
14671467
record.exc_text = None
1468+
record.stack_info = None
14681469
return record
14691470

14701471
def emit(self, record):

Lib/test/test_logging.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -3665,16 +3665,18 @@ def test_queue_listener(self):
36653665
@unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'),
36663666
'logging.handlers.QueueListener required for this test')
36673667
def test_queue_listener_with_StreamHandler(self):
3668-
# Test that traceback only appends once (bpo-34334).
3668+
# Test that traceback and stack-info only appends once (bpo-34334, bpo-46755).
36693669
listener = logging.handlers.QueueListener(self.queue, self.root_hdlr)
36703670
listener.start()
36713671
try:
36723672
1 / 0
36733673
except ZeroDivisionError as e:
36743674
exc = e
36753675
self.que_logger.exception(self.next_message(), exc_info=exc)
3676+
self.que_logger.error(self.next_message(), stack_info=True)
36763677
listener.stop()
36773678
self.assertEqual(self.stream.getvalue().strip().count('Traceback'), 1)
3679+
self.assertEqual(self.stream.getvalue().strip().count('Stack'), 1)
36783680

36793681
@unittest.skipUnless(hasattr(logging.handlers, 'QueueListener'),
36803682
'logging.handlers.QueueListener required for this test')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
In :class:`QueueHandler`, clear ``stack_info`` from :class:`LogRecord` to
2+
prevent stack trace from being written twice.

0 commit comments

Comments
 (0)