Fix Django span finalization for StreamingHttpResponse - #4919
Open
saisharan0103 wants to merge 1 commit into
Open
Conversation
…e prematurely for StreamingHttpResponse Closes open-telemetry#4681
|
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.
Fixes #4681.
The Django middleware currently starts the server span in
process_requestwith ause_spanactivation that ends on exit, then exits that activation inprocess_response. ForStreamingHttpResponse,process_responseruns before Django consumes the response iterator, and Django only callsresponse.close()after streaming finishes. That causes the span end time, request duration metrics, and active request decrement to be recorded before the actual response lifecycle is complete.This changes the middleware so
process_responsedetaches the span context without ending the span there. It wrapsresponse.closeso the original close always runs first, then OpenTelemetry finalization runs in afinallyblock after the response is closed. The existing duration metric recording, active request decrement, andspan.end()call now live in a small once-only finalizer used by the close wrapper.process_responsestill handles response attributes, propagator injection, hooks, and exception recording.Regression coverage adds streaming response views and tests for WSGI and ASGI middleware paths. The tests assert that no server span is exported until the streaming response is consumed and closed, then assert the exported span has the expected HTTP attributes.
ruff check instrumentation/opentelemetry-instrumentation-django/src/opentelemetry/instrumentation/django/middleware/otel_middleware.py instrumentation/opentelemetry-instrumentation-django/tests/test_middleware.py instrumentation/opentelemetry-instrumentation-django/tests/test_middleware_asgi.py instrumentation/opentelemetry-instrumentation-django/tests/views.pyreports no new findings on the changed files.Ran
pytest -xlocally with no new failures.