Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-91555: disable logger while handling log record#131812

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
vsajip merged 5 commits intopython:mainfromduaneg:gh-91555
May 8, 2025

Conversation

duaneg
Copy link
Contributor

@duanegduaneg commentedMar 27, 2025
edited by bedevere-appbot
Loading

Prevent the possibility of re-entrancy and deadlock or infinite recursion caused by logging triggered by logging by disabling logging while the logger is handling log messages.

Prevent the possibility of re-entrancy and deadlock or infinite recursioncaused by logging triggered by logging by disabling logging while the logger ishandling log messages.
@duanegduaneg requested a review fromvsajip as acode ownerMarch 27, 2025 23:13
@bedevere-app
Copy link

Most changes to Pythonrequire a NEWS entry. Add one using theblurb_it web app or theblurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply theskip news label instead.

return
maybe_record = self.filter(record)
if not maybe_record:
if self._is_disabled():
Copy link
Contributor

@graingertgraingertMar 29, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

rather than disabling the logging, can we instead append the record to aself._reentrant_records = collections.deque(), and then process all of the pending records:

maybe_record=self.filter(record)ifnotmaybe_record:returnifisinstance(maybe_record,LogRecord):record=maybe_recordwas_calling_handlers=set_calling_handlers()try:ifnotwas_calling_handlers:self.callHandlers(record)whileTrue:try:record=self._reentrant_records.popleft()exceptIndexError:returnself.callHandlers(record)else:self._reentrant_records.append(record)finally:set_not_calling_handlers()

pitrou reacted with thumbs up emoji
Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This will still produce a stack overflow if handling the deferred log message itself logs another message

gpshead reacted with thumbs up emoji
Copy link
Contributor

@graingertgraingertMar 30, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'm not following how this would cause a stack overflow, if handling the log message logs another message it would go onto the _reentrant_records queue, and then be processed later once the stack returns all the way back to whereset_calling_handlers() is first called.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'm not following how this would cause a stack overflow, if handling the log message logs another message it would go onto the _reentrant_records queue, and then be processed later once the stack returns all the way back to whereset_calling_handlers() is first called.

Sorry, I should have said deadlock with the current example. The stack overflow is from a different way of triggering this (see the second unit test added).

The trouble is that when the first recursive logging call exits thefinally block it clears the "calling handlers" flag, which means a subsequent (still recursive) one takes the wrong path and deadlocks/overflows.

That can be avoided for the original triggering example by only clearing the "handling" flag if it was initially unset (the deferred records collection also needs to be TLS not a member variable). It ends up looking something like this:

ifnothasattr(self._tls,'reentrant_records'):self._tls.reentrant_records=deque()deferred=self._tls.reentrant_recordswas_calling_handlers=self.set_calling_handlers()try:ifnotwas_calling_handlers:self.callHandlers(record)whiledeferred:self.callHandlers(deferred.popleft())else:deferred.append(record)finally:ifnotwas_calling_handlers:self.set_not_calling_handlers()

This fixes the two bugs, which only log thefirst time they try to process a log record (and means those recursive log messages are logged and not silently ignored, which is nice). However a different example which logsevery time (such as the second unit test) will still live-lock and never exit thatwhile loop.

Copy link
Contributor

@graingertgraingertMar 30, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

will still live-lock and never exit that while loop.

Does the system keep logging forever instead?

This seems acceptable as you'd easily track down this bug just by looking at the logs

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Does the system keep logging forever instead?

Yep, it will just sit in a tight loop spamming the log forever, or at least until/unless that exhausts disk space or wherever the logs are actually going.

This seems acceptable as you'd easily track down this bug just by looking at the logs

IMO it is not agreat failure mode, but it will certainly be obvious!

FWIW I think I prefer ignoring them: the code is much simpler and it prevents the issue in non-trivial handler implementations like Sentry's (that would otherwise trigger the live-lock failure). I was hoping this fix would mean they would be able to remove that nasty monkey-patching on supported versions.

OTOH it is definitely nice to actually handle instead of drop the recursive log messages, in cases where they don't always continue to recurse.

Copy link
Contributor

@graingertgraingertMar 30, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

we could have alogging.(_)N_RECURSIVE_CALLS constant to limit this so it's not forever

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

We could. Another alternative would be Victor Stinner's suggestion in the discourse discussion to raise an exception. That would bring it to the user's attention and force them to deal with it.

Ultimately, though, the way they will have to deal with it is by preventing, disabling, or otherwise intercepting and ignoring all such logging. That will be difficult to do reliably outside the core, will likely be overlooked unless/until it bites, and have to be done in every susceptible log handler or application that uses such.

IMO it would be better for us to do this once, centrally, with a small, simple, and robust fix.

@gpshead
Copy link
Member

TODO list:

  • unit test(s) for the errant behavior would be helpful while working on this and are needed to prevent future regression.
duaneg reacted with thumbs up emoji

@bedevere-app
Copy link

Most changes to Pythonrequire a NEWS entry. Add one using theblurb_it web app or theblurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply theskip news label instead.

@duaneg
Copy link
ContributorAuthor

Would a news entry be appropriate for this?

@graingert
Copy link
Contributor

Would a news entry be appropriate for this?

yes this needs a news entry

duaneg reacted with thumbs up emoji

@vsajipvsajip added the 🔨 test-with-buildbotsTest PR w/ buildbots; report in status section labelApr 14, 2025
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by@vsajip for commit7b68d12 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F131812%2Fmerge

If you want to schedule another build, you need to add the🔨 test-with-buildbots label again.

@bedevere-botbedevere-bot removed the 🔨 test-with-buildbotsTest PR w/ buildbots; report in status section labelApr 14, 2025
Copy link
Member

@vsajipvsajip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@duaneg, from the issue:

It disables logging on a per-thread basis and only while the thread runs the message handlers (+filters). Which is to say, it is disabled only while running code that would trigger this bug if it logged a message. Or at least, that is my intent: if I've overlooked anything or there is a bug, please let me know!

It doesn't stop other threads from logging to the same logger and/or handlers.

I think a test with logging from multiple threads and other handlers should be added to confirm this.

duaneg reacted with thumbs up emoji
@bedevere-app
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phraseI have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

…andles amessage does not block a different thread from handling a message on the samelogger.
@duaneg
Copy link
ContributorAuthor

I think a test with logging from multiple threads and other handlers should be added to confirm this.

Good idea, will add, thanks!

@duanegduaneg requested a review fromvsajipApril 17, 2025 11:48
@vsajipvsajip added the 🔨 test-with-buildbotsTest PR w/ buildbots; report in status section labelApr 18, 2025
@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by@vsajip for commit99788f7 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F131812%2Fmerge

If you want to schedule another build, you need to add the🔨 test-with-buildbots label again.

@bedevere-botbedevere-bot removed the 🔨 test-with-buildbotsTest PR w/ buildbots; report in status section labelApr 18, 2025
@vsajipvsajip merged commit2561e14 intopython:mainMay 8, 2025
122 of 126 checks passed
@vsajipvsajip added needs backport to 3.13bugs and security fixes needs backport to 3.14bugs and security fixes labelsMay 11, 2025
@miss-islington-app
Copy link

Thanks@duaneg for the PR, and@vsajip for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13.
🐍🍒⛏🤖

@miss-islington-app
Copy link

Thanks@duaneg for the PR, and@vsajip for merging it 🌮🎉.. I'm working now to backport this PR to: 3.14.
🐍🍒⛏🤖

miss-islington pushed a commit to miss-islington/cpython that referenced this pull requestMay 11, 2025
…1812)Prevent the possibility of re-entrancy leading to deadlock or infinite recursion (caused by logging triggered by logging), by disabling logging while the logger is handling log messages.(cherry picked from commit2561e14)Co-authored-by: Duane Griffin <duaneg@dghda.com>
miss-islington pushed a commit to miss-islington/cpython that referenced this pull requestMay 11, 2025
…1812)Prevent the possibility of re-entrancy leading to deadlock or infinite recursion (caused by logging triggered by logging), by disabling logging while the logger is handling log messages.(cherry picked from commit2561e14)Co-authored-by: Duane Griffin <duaneg@dghda.com>
@bedevere-app
Copy link

GH-133898 is a backport of this pull request to the3.13 branch.

@bedevere-appbedevere-appbot removed the needs backport to 3.13bugs and security fixes labelMay 11, 2025
@bedevere-app
Copy link

GH-133899 is a backport of this pull request to the3.14 branch.

@bedevere-appbedevere-appbot removed the needs backport to 3.14bugs and security fixes labelMay 11, 2025
vsajip pushed a commit that referenced this pull requestMay 12, 2025
vsajip pushed a commit that referenced this pull requestMay 12, 2025
…GH-133899)Prevent the possibility of re-entrancy leading to deadlock or infinite recursion (caused by logging triggered by logging), by disabling logging while the logger is handling log messages.(cherry picked from commit2561e14)Co-authored-by: Duane Griffin <duaneg@dghda.com>
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@gpsheadgpsheadgpshead left review comments

@graingertgraingertgraingert left review comments

@vsajipvsajipvsajip approved these changes

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

5 participants
@duaneg@gpshead@graingert@bedevere-bot@vsajip

[8]ページ先頭

©2009-2025 Movatter.jp