Skip to content

Django Instrumentation: Spans close prematurely for StreamingHttpResponse #4681

@hartungstenio

Description

@hartungstenio

What problem do you want to solve?

The current Django instrumentation uses a Middleware to open and close spans. While this works perfectly for standard HTTP responses, it falls short for StreamingHttpResponse.

Because streaming responses continue to process and send data after the middleware chain has finished executing, the request lifecycle is not properly traced, leading to incomplete or inaccurate span durations.

Describe the solution you'd like

A way to solve this is to hook into the response's close() method, which Django guarantees will be called after the stream finishes. We can wrap the original close method to ensure the span is ended at the very end of the response lifecycle.

This approach would gracefully handle both regular and StreamingHttpResponse objects.

Here is a conceptual implementation:

original_close = response.close

def close_span():
    try:
        original_close()
    finally:
        # TODO: End the span here

response.close = close_span

Note: I haven't fully tested this with async responses under ASGI yet, where response.close might be executed via sync_to_async.

Describe alternatives you've considered

Another option would be listening to Django's built-in request_finished signal. However, this signal doesn't always carry the exact context of the specific request/response object as cleanly as wrapping the response itself, and might make correlation trickier in concurrent environments.

Additional Context

No response

Would you like to implement a fix?

Yes

Tip

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions