Repository navigation
Attach the OpenTelemetry logging handler - #295
Merged
Merged
Conversation
The `opentelemetry-instrumentation-logging` package requires Python 3.9, and its last release supporting 3.9 pins the OpenTelemetry stack to versions that no longer move. Requiring 3.10 puts every supported Python version on the same OpenTelemetry release. Python 3.13 and 3.14 join the test matrix and the classifiers. Ruff reads `requires-python` to decide which rewrites apply, so raising the floor turns on the pyupgrade rules that account for the rest of this change.
|
鉁旓笍 All good! |
unflxw
marked this pull request as ready for review
September 30, 2026 15:10
unflxw
force-pushed
the
contrib-logging-handler
branch
from
September 30, 2026 15:13
d5b62c9 to
e4e36b8
Compare
The log handler attached to the root logger comes from `opentelemetry.sdk._logs`, which is deprecated, and configuring the logging module removes it, so a Django application's `LOGGING` setting stops logs being sent. The handler in `opentelemetry-instrumentation-logging` wraps `dictConfig`, `fileConfig` and `basicConfig` so that it survives them. It records the file, function and line a log line came from only when asked, so `log_code_attributes` is passed to keep those attributes. Wrapping `basicConfig` means the level it is given now applies, because Python skips that call when the root logger already has a handler. An application that calls it with a level below `WARNING` starts sending those log lines.
An application that attached an OpenTelemetry log handler of its own now has two handlers sending to the same place, so every log line reaching both is sent twice. Our documentation told Django applications to attach one. Only a handler sending to the logger provider started here is warned about, and only when the records it handles reach the root logger, where the handler attached here receives them too. A handler from `opentelemetry.sdk._logs` is warned about separately, whether or not it duplicates anything, because it is deprecated and is removed in a future release. It raises a `DeprecationWarning` about itself, which Python hides unless it comes from `__main__`, so an application that attaches it from its settings never sees it.
The `appsignal` and `opentelemetry` loggers are stopped from propagating to the root logger when the log handler is attached here, so an application that attaches the handler itself, through the `disable_default_instrumentations` option, sends what AppSignal and the OpenTelemetry SDK log about themselves as its own logs. Stopping the two loggers when logging starts covers a handler attached either way.
unflxw
force-pushed
the
contrib-logging-handler
branch
from
September 30, 2026 15:20
e4e36b8 to
3ca65d0
Compare
bjacquet
approved these changes
Oct 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Require Python 3.10
The
opentelemetry-instrumentation-loggingpackage requires Python 3.9,and its last release supporting 3.9 pins the OpenTelemetry stack to
versions that no longer move. Requiring 3.10 puts every supported Python
version on the same OpenTelemetry release.
Python 3.13 and 3.14 join the test matrix and the classifiers. Ruff
reads
requires-pythonto decide which rewrites apply, so raising thefloor turns on the pyupgrade rules that account for the rest of this
change.
Attach the OpenTelemetry logging handler
The log handler attached to the root logger comes from
opentelemetry.sdk._logs, which is deprecated, and configuring thelogging module removes it, so a Django application's
LOGGINGsettingstops logs being sent. The handler in
opentelemetry-instrumentation-loggingwrapsdictConfig,fileConfigand
basicConfigso that it survives them. It records the file,function and line a log line came from only when asked, so
log_code_attributesis passed to keep those attributes.Wrapping
basicConfigmeans the level it is given now applies, becausePython skips that call when the root logger already has a handler. An
application that calls it with a level below
WARNINGstarts sendingthose log lines.
Warn about log handlers the application attached
An application that attached an OpenTelemetry log handler of its own now
has two handlers sending to the same place, so every log line reaching
both is sent twice. Our documentation told Django applications to attach
one. Only a handler sending to the logger provider started here is
warned about, and only when the records it handles reach the root
logger, where the handler attached here receives them too.
A handler from
opentelemetry.sdk._logsis warned about separately,whether or not it duplicates anything, because it is deprecated and is
removed in a future release. It raises a
DeprecationWarningaboutitself, which Python hides unless it comes from
__main__, so anapplication that attaches it from its settings never sees it.
Keep internal logs out of an application's logs
The
appsignalandopentelemetryloggers are stopped from propagatingto the root logger when the log handler is attached here, so an
application that attaches the handler itself, through the
disable_default_instrumentationsoption, sends what AppSignal and theOpenTelemetry SDK log about themselves as its own logs. Stopping the two
loggers when logging starts covers a handler attached either way.
Documented in appsignal/appsignal-docs#342. The
/logs/route inappsignal/test-setups#389 exercises the structured log line; the
python-logs-handler-warningsbranch adds routes that trigger each warning, and is not for merging.