open-telemetry / open-telemetry/opentelemetry-python-contrib

Django instrumentation doesn't include http.route attribute in http.server.duration metrics

Open
#3,553 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
1.1k
Forks
1.1k
Avg merge
4d 15h
Merged PRs (30d)
16

Description

Describe your environment

OS: macOS
Python version: 3.12.7
Package version: 0.53b1

What happened?

Django instrumentation doesn't set http.route attribute on metrics.

Steps to Reproduce

Sample instrumentation setup:

from opentelemetry import metrics
from opentelemetry.instrumentation.django import DjangoInstrumentor
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import ConsoleMetricExporter
from opentelemetry.sdk.metrics.view import View

# Set up console exporter to see metrics
exporter = ConsoleMetricExporter()
reader = PeriodicExportingMetricReader(exporter=exporter, export_interval_millis=5000)

# View expecting http.route
view = View(
    instrument_name="http.server.duration",
    attribute_keys={"http.method", "http.status_code", "http.route"}
)

meter_provider = MeterProvider(
    metric_readers=[reader],
    views=[view]
)
metrics.set_meter_provider(meter_provider)

DjangoInstrumentor().instrument(is_middleware=True)
Expected Result

Console output should show a metric that includes http.route, compared to the actual console output below.

Actual Result

Console output:

...
                            "name": "http.server.duration",
                            "description": "Measures the duration of inbound HTTP requests.",
                            "unit": "ms",
                            "data": {
                                "data_points": [
                                    {
                                        "attributes": {
                                            "http.method": "GET",
                                            "http.status_code": 200
                                        },
...
Additional context

Note that I AM able to see the http.route in the response hook and set it on a span, like so:

    def set_http_route_attribute_response_hook(span, request, response):
        if hasattr(request, "resolver_match") and request.resolver_match:
            route = request.resolver_match.route
            span.set_attribute("http.route", str(route))

    DjangoInstrumentor().instrument(
        is_middleware=True,
        response_hook=set_http_route_attribute_response_hook,
    )

I can also see http.target correctly, just not http.route.

Would you like to implement a fix?

Probably not

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at the DjangoInstrumentor entry point and trace how the http.server.duration metric is recorded alongside the response hook that can read request.resolver_match.route. Reproduce the provided View and console-exporter setup, then verify that completed metric data includes http.route for routed requests without relying on the span hook.

Written by the indexing model from the issue text.

Assessment

Tech stack
django, python
Domain
backend, observability
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.