Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
([#3956](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3956))
- `opentelemetry-instrumentation-dbapi`: Replace SpanAttributes with semconv constants where applicable
([#4058](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4058))
- `opentelemetry-instrumentation-django`: Replace SpanAttributes with semconv constants where applicable
([#4059](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/4059))

## Version 1.39.0/0.60b0 (2025-12-03)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@
from opentelemetry.instrumentation.wsgi import (
collect_request_attributes as wsgi_collect_request_attributes,
)
from opentelemetry.semconv._incubating.attributes.http_attributes import (
HTTP_TARGET,
)
from opentelemetry.semconv.attributes.http_attributes import HTTP_ROUTE
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.trace import Span, SpanKind, use_span
from opentelemetry.util.http import (
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS,
Expand Down Expand Up @@ -320,12 +322,12 @@ def process_view(self, request, view_func, *args, **kwargs):
if route:
if span.is_recording():
# http.route is present for both old and new semconv
span.set_attribute(SpanAttributes.HTTP_ROUTE, route)
span.set_attribute(HTTP_ROUTE, route)
duration_attrs = request.META[
self._environ_duration_attr_key
]
if _report_old(self._sem_conv_opt_in_mode):
duration_attrs[SpanAttributes.HTTP_TARGET] = route
duration_attrs[HTTP_TARGET] = route
if _report_new(self._sem_conv_opt_in_mode):
duration_attrs[HTTP_ROUTE] = route

Expand Down Expand Up @@ -424,9 +426,9 @@ def process_response(self, request, response):
duration_attrs, _StabilityMode.DEFAULT
)
# http.target to be included in old semantic conventions
target = duration_attrs.get(SpanAttributes.HTTP_TARGET)
target = duration_attrs.get(HTTP_TARGET)
if target:
duration_attrs_old[SpanAttributes.HTTP_TARGET] = target
duration_attrs_old[HTTP_TARGET] = target
self._duration_histogram_old.record(
max(round(duration_s * 1000), 0),
duration_attrs_old,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@
from opentelemetry.sdk import resources
from opentelemetry.sdk.trace import Span
from opentelemetry.sdk.trace.id_generator import RandomIdGenerator
from opentelemetry.semconv._incubating.attributes.http_attributes import (
HTTP_METHOD,
HTTP_SCHEME,
HTTP_STATUS_CODE,
HTTP_URL,
)
from opentelemetry.semconv.attributes.client_attributes import CLIENT_ADDRESS
from opentelemetry.semconv.attributes.exception_attributes import (
EXCEPTION_MESSAGE,
Expand All @@ -55,7 +61,6 @@
)
from opentelemetry.semconv.attributes.server_attributes import SERVER_PORT
from opentelemetry.semconv.attributes.url_attributes import URL_SCHEME
from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.test.test_base import TestBase
from opentelemetry.trace import (
SpanKind,
Expand Down Expand Up @@ -171,17 +176,17 @@ async def test_templated_route_get(self):
self.assertEqual(span.name, "GET ^route/(?P<year>[0-9]{4})/template/$")
self.assertEqual(span.kind, SpanKind.SERVER)
self.assertEqual(span.status.status_code, StatusCode.UNSET)
self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET")
self.assertEqual(span.attributes[HTTP_METHOD], "GET")
self.assertEqual(
span.attributes[SpanAttributes.HTTP_URL],
span.attributes[HTTP_URL],
"http://testserver/route/2020/template/",
)
self.assertEqual(
span.attributes[SpanAttributes.HTTP_ROUTE],
span.attributes[HTTP_ROUTE],
"^route/(?P<year>[0-9]{4})/template/$",
)
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200)
self.assertEqual(span.attributes[HTTP_SCHEME], "http")
self.assertEqual(span.attributes[HTTP_STATUS_CODE], 200)

async def test_templated_route_get_new_semconv(self):
await self.async_client.get("/route/2020/template/")
Expand Down Expand Up @@ -216,13 +221,13 @@ async def test_templated_route_get_both_semconv(self):
self.assertEqual(span.name, "GET ^route/(?P<year>[0-9]{4})/template/$")
self.assertEqual(span.kind, SpanKind.SERVER)
self.assertEqual(span.status.status_code, StatusCode.UNSET)
self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET")
self.assertEqual(span.attributes[HTTP_METHOD], "GET")
self.assertEqual(
span.attributes[SpanAttributes.HTTP_URL],
span.attributes[HTTP_URL],
"http://testserver/route/2020/template/",
)
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200)
self.assertEqual(span.attributes[HTTP_SCHEME], "http")
self.assertEqual(span.attributes[HTTP_STATUS_CODE], 200)
self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET")
self.assertEqual(span.attributes[SERVER_PORT], 80)
self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1")
Expand All @@ -245,16 +250,14 @@ async def test_traced_get(self):
self.assertEqual(span.name, "GET ^traced/")
self.assertEqual(span.kind, SpanKind.SERVER)
self.assertEqual(span.status.status_code, StatusCode.UNSET)
self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET")
self.assertEqual(span.attributes[HTTP_METHOD], "GET")
self.assertEqual(
span.attributes[SpanAttributes.HTTP_URL],
span.attributes[HTTP_URL],
"http://testserver/traced/",
)
self.assertEqual(
span.attributes[SpanAttributes.HTTP_ROUTE], "^traced/"
)
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200)
self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/")
self.assertEqual(span.attributes[HTTP_SCHEME], "http")
self.assertEqual(span.attributes[HTTP_STATUS_CODE], 200)

async def test_traced_get_new_semconv(self):
await self.async_client.get("/traced/")
Expand Down Expand Up @@ -286,13 +289,13 @@ async def test_traced_get_both_semconv(self):
self.assertEqual(span.name, "GET ^traced/")
self.assertEqual(span.kind, SpanKind.SERVER)
self.assertEqual(span.status.status_code, StatusCode.UNSET)
self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET")
self.assertEqual(span.attributes[HTTP_METHOD], "GET")
self.assertEqual(
span.attributes[SpanAttributes.HTTP_URL],
span.attributes[HTTP_URL],
"http://testserver/traced/",
)
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200)
self.assertEqual(span.attributes[HTTP_SCHEME], "http")
self.assertEqual(span.attributes[HTTP_STATUS_CODE], 200)
self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET")
self.assertEqual(span.attributes[URL_SCHEME], "http")
self.assertEqual(span.attributes[SERVER_PORT], 80)
Expand Down Expand Up @@ -325,16 +328,14 @@ async def test_traced_post(self):
self.assertEqual(span.name, "POST ^traced/")
self.assertEqual(span.kind, SpanKind.SERVER)
self.assertEqual(span.status.status_code, StatusCode.UNSET)
self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "POST")
self.assertEqual(span.attributes[HTTP_METHOD], "POST")
self.assertEqual(
span.attributes[SpanAttributes.HTTP_URL],
span.attributes[HTTP_URL],
"http://testserver/traced/",
)
self.assertEqual(
span.attributes[SpanAttributes.HTTP_ROUTE], "^traced/"
)
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200)
self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/")
self.assertEqual(span.attributes[HTTP_SCHEME], "http")
self.assertEqual(span.attributes[HTTP_STATUS_CODE], 200)

async def test_traced_post_new_semconv(self):
await self.async_client.post("/traced/")
Expand Down Expand Up @@ -366,13 +367,13 @@ async def test_traced_post_both_semconv(self):
self.assertEqual(span.name, "POST ^traced/")
self.assertEqual(span.kind, SpanKind.SERVER)
self.assertEqual(span.status.status_code, StatusCode.UNSET)
self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "POST")
self.assertEqual(span.attributes[HTTP_METHOD], "POST")
self.assertEqual(
span.attributes[SpanAttributes.HTTP_URL],
span.attributes[HTTP_URL],
"http://testserver/traced/",
)
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200)
self.assertEqual(span.attributes[HTTP_SCHEME], "http")
self.assertEqual(span.attributes[HTTP_STATUS_CODE], 200)
self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "POST")
self.assertEqual(span.attributes[URL_SCHEME], "http")
self.assertEqual(span.attributes[SERVER_PORT], 80)
Expand All @@ -393,24 +394,20 @@ async def test_error(self):
self.assertEqual(span.name, "GET ^error/")
self.assertEqual(span.kind, SpanKind.SERVER)
self.assertEqual(span.status.status_code, StatusCode.ERROR)
self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET")
self.assertEqual(span.attributes[HTTP_METHOD], "GET")
self.assertEqual(
span.attributes[SpanAttributes.HTTP_URL],
span.attributes[HTTP_URL],
"http://testserver/error/",
)
self.assertEqual(span.attributes[SpanAttributes.HTTP_ROUTE], "^error/")
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 500)
self.assertEqual(span.attributes[HTTP_ROUTE], "^error/")
self.assertEqual(span.attributes[HTTP_SCHEME], "http")
self.assertEqual(span.attributes[HTTP_STATUS_CODE], 500)

self.assertEqual(len(span.events), 1)
event = span.events[0]
self.assertEqual(event.name, "exception")
self.assertEqual(
event.attributes[SpanAttributes.EXCEPTION_TYPE], "ValueError"
)
self.assertEqual(
event.attributes[SpanAttributes.EXCEPTION_MESSAGE], "error"
)
self.assertEqual(event.attributes[EXCEPTION_TYPE], "ValueError")
self.assertEqual(event.attributes[EXCEPTION_MESSAGE], "error")

async def test_error_new_semconv(self):
with self.assertRaises(ValueError):
Expand Down Expand Up @@ -447,14 +444,14 @@ async def test_error_both_semconv(self):
self.assertEqual(span.name, "GET ^error/")
self.assertEqual(span.kind, SpanKind.SERVER)
self.assertEqual(span.status.status_code, StatusCode.ERROR)
self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "GET")
self.assertEqual(span.attributes[HTTP_METHOD], "GET")
self.assertEqual(
span.attributes[SpanAttributes.HTTP_URL],
span.attributes[HTTP_URL],
"http://testserver/error/",
)
self.assertEqual(span.attributes[SpanAttributes.HTTP_ROUTE], "^error/")
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 500)
self.assertEqual(span.attributes[HTTP_ROUTE], "^error/")
self.assertEqual(span.attributes[HTTP_SCHEME], "http")
self.assertEqual(span.attributes[HTTP_STATUS_CODE], 500)
self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET")
self.assertEqual(span.attributes[HTTP_ROUTE], "^error/")
self.assertEqual(span.attributes[URL_SCHEME], "http")
Expand Down Expand Up @@ -544,7 +541,7 @@ async def test_nonstandard_http_method_span_name_both_semconv(self):

span = span_list[0]
self.assertEqual(span.name, "HTTP")
self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "_OTHER")
self.assertEqual(span.attributes[HTTP_METHOD], "_OTHER")
self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "_OTHER")
self.assertEqual(
span.attributes[HTTP_REQUEST_METHOD_ORIGINAL], "NONSTANDARD"
Expand Down