Skip to content

Fix logger name misattribution by reading caller info from LogRecord - #678

Merged
pgetta merged 4 commits into
mainfrom
fix-intercept-handler-logrecord
Jul 23, 2026
Merged

Fix logger name misattribution by reading caller info from LogRecord#678
pgetta merged 4 commits into
mainfrom
fix-intercept-handler-logrecord

Conversation

@pgetta

@pgetta pgetta commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Problem

Since the Sentry integration (#667), every log emitted by third-party libraries through stdlib logging (httpx, uvicorn, ...) is attributed to sentry_sdk.integrations.logging instead of the real caller:

{"time":"...","level":"INFO","name":"sentry_sdk.integrations.logging","message":"HTTP Request: GET .../userinfo \"HTTP/1.1 200 OK\"","extra":{...}}

Cause

sentry-sdk's default LoggingIntegration monkeypatches logging.Logger.callHandlers, inserting a sentry_sdk frame into the call stack. InterceptHandler.emit re-derives the caller by walking frames and skipping only frames from the logging module, so the walk now stops at Sentry's wrapper frame, and loguru derives name/function/line from it. Same upstream report: Delgan/loguru#509.

Fix

Stop walking frames altogether. logging.Logger._log stamps record.name, record.funcName, and record.lineno via findCaller() before any handler — patched or not — runs, so emit now reads the caller off the LogRecord and applies it with L.patch(...):

  • Immune to any current or future patching of the handler chain (sentry-sdk, ddtrace, OpenTelemetry log instrumentation, ...), not just sentry_sdk.*.
  • Removes a per-record Python-level frame walk from the hot path of every intercepted log line.
  • No import-ordering constraint between configure_logging() and init_sentry().

The request-context patcher from configure_logging is unaffected: loguru applies the core patcher first and .patch() composes on top of it.

Tests

tests/test_logger.py adds regression coverage. Per review feedback, the tests do not call sentry_sdk.init (its callHandlers monkeypatch is global and never reverted, and sentry is already covered by test_sentry.py); instead, an autouse fixture wraps logging.Logger.callHandlers with an extra frame via pytest's monkeypatch, simulating exactly what sentry's LoggingIntegration.setup_once does. The simulated patch reproduces the misattribution under the old frame-walking implementation, so the tests fail on pre-fix code.

Alternative to #677 (closed in favor of this PR)

#677 fixed the same bug by extending the frame walk to also skip sentry_sdk.* frames. The tradeoff that led to picking this PR:

  • Fix logger name misattributed to sentry_sdk.integrations.logging #677 kept the exact pre-Add Sentry integration #667 semantics (name = calling module's __name__, e.g. httpx._client) but hardcodes one library into the frame walk; any other library that wraps the handler chain reproduces the bug and needs another clause.
  • This PR is robust by construction, but changes name to the stdlib logger name (e.g. httpx instead of httpx._client). The two coincide for the common logging.getLogger(__name__) idiom; the logger name is also the key used in LOG_STANDARD_LOGGER and log filtering. If you have saved log queries or alerts matching exact module-level name values, they may need updating.

@pgetta pgetta self-assigned this Jul 22, 2026
@pgetta pgetta added the enhancement New feature or request label Jul 22, 2026
@pgetta
pgetta requested a review from GianlucaFicarelli July 22, 2026 11:15
@pgetta

pgetta commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

@GianlucaFicarelli this is an alternative fix for the logging issue. Please let me know which one makes more sense to apply.

@pgetta
pgetta marked this pull request as ready for review July 22, 2026 11:16

@GianlucaFicarelli GianlucaFicarelli left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks Pavlo, this PR looks more generic than #677 so I think we can go with this.
The new behaviour for name described in the PR description looks good to me, maybe even clearer than the previous one.
I just commented about the tests and the global effect of sentry initialization.

Comment thread tests/test_logger.py Outdated
@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
pytest 97.85% <100.00%> (+0.06%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
app/logger.py 88.88% <100.00%> (+12.88%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@pgetta

pgetta commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

Thank you Gianluca

@pgetta
pgetta merged commit 178098e into main Jul 23, 2026
2 checks passed
@pgetta
pgetta deleted the fix-intercept-handler-logrecord branch July 23, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants