Re-add `http.target` to Django old sem conv server duration metric (#2746)
This commit is contained in:
parent
35cc6f2854
commit
b65f67ded5
|
|
@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- `opentelemetry-instrumentation-django` Fix regression - `http.target` re-added back to old semconv duration metrics
|
||||||
|
([#2746](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2746))
|
||||||
|
|
||||||
## Version 1.26.0/0.47b0 (2024-07-23)
|
## Version 1.26.0/0.47b0 (2024-07-23)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
||||||
|
|
@ -333,6 +333,7 @@ class _DjangoMiddleware(MiddlewareMixin):
|
||||||
|
|
||||||
# pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
|
# pylint: disable=too-many-statements
|
||||||
def process_response(self, request, response):
|
def process_response(self, request, response):
|
||||||
if self._excluded_urls.url_disabled(request.build_absolute_uri("?")):
|
if self._excluded_urls.url_disabled(request.build_absolute_uri("?")):
|
||||||
return response
|
return response
|
||||||
|
|
@ -426,6 +427,10 @@ class _DjangoMiddleware(MiddlewareMixin):
|
||||||
duration_attrs_old = _parse_duration_attrs(
|
duration_attrs_old = _parse_duration_attrs(
|
||||||
duration_attrs, _HTTPStabilityMode.DEFAULT
|
duration_attrs, _HTTPStabilityMode.DEFAULT
|
||||||
)
|
)
|
||||||
|
# http.target to be included in old semantic conventions
|
||||||
|
target = duration_attrs.get(SpanAttributes.HTTP_TARGET)
|
||||||
|
if target:
|
||||||
|
duration_attrs_old[SpanAttributes.HTTP_TARGET] = target
|
||||||
self._duration_histogram_old.record(
|
self._duration_histogram_old.record(
|
||||||
max(round(duration_s * 1000), 0), duration_attrs_old
|
max(round(duration_s * 1000), 0), duration_attrs_old
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,6 @@ from opentelemetry import trace
|
||||||
from opentelemetry.instrumentation._semconv import (
|
from opentelemetry.instrumentation._semconv import (
|
||||||
OTEL_SEMCONV_STABILITY_OPT_IN,
|
OTEL_SEMCONV_STABILITY_OPT_IN,
|
||||||
_OpenTelemetrySemanticConventionStability,
|
_OpenTelemetrySemanticConventionStability,
|
||||||
_server_active_requests_count_attrs_new,
|
|
||||||
_server_active_requests_count_attrs_old,
|
|
||||||
_server_duration_attrs_new,
|
|
||||||
_server_duration_attrs_old,
|
|
||||||
)
|
)
|
||||||
from opentelemetry.instrumentation.django import (
|
from opentelemetry.instrumentation.django import (
|
||||||
DjangoInstrumentor,
|
DjangoInstrumentor,
|
||||||
|
|
@ -48,24 +44,6 @@ from opentelemetry.sdk.metrics.export import (
|
||||||
)
|
)
|
||||||
from opentelemetry.sdk.trace import Span
|
from opentelemetry.sdk.trace import Span
|
||||||
from opentelemetry.sdk.trace.id_generator import RandomIdGenerator
|
from opentelemetry.sdk.trace.id_generator import RandomIdGenerator
|
||||||
from opentelemetry.semconv.attributes.client_attributes import CLIENT_ADDRESS
|
|
||||||
from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE
|
|
||||||
from opentelemetry.semconv.attributes.exception_attributes import (
|
|
||||||
EXCEPTION_MESSAGE,
|
|
||||||
EXCEPTION_TYPE,
|
|
||||||
)
|
|
||||||
from opentelemetry.semconv.attributes.http_attributes import (
|
|
||||||
HTTP_REQUEST_METHOD,
|
|
||||||
HTTP_REQUEST_METHOD_ORIGINAL,
|
|
||||||
HTTP_RESPONSE_STATUS_CODE,
|
|
||||||
HTTP_ROUTE,
|
|
||||||
)
|
|
||||||
from opentelemetry.semconv.attributes.network_attributes import (
|
|
||||||
NETWORK_PROTOCOL_VERSION,
|
|
||||||
)
|
|
||||||
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.wsgitestutil import WsgiTestBase
|
from opentelemetry.test.wsgitestutil import WsgiTestBase
|
||||||
from opentelemetry.trace import (
|
from opentelemetry.trace import (
|
||||||
SpanKind,
|
SpanKind,
|
||||||
|
|
@ -197,18 +175,18 @@ class TestMiddleware(WsgiTestBase):
|
||||||
)
|
)
|
||||||
self.assertEqual(span.kind, SpanKind.SERVER)
|
self.assertEqual(span.kind, SpanKind.SERVER)
|
||||||
self.assertEqual(span.status.status_code, StatusCode.UNSET)
|
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(
|
self.assertEqual(
|
||||||
span.attributes[SpanAttributes.HTTP_URL],
|
span.attributes["http.url"],
|
||||||
"http://testserver/route/2020/template/",
|
"http://testserver/route/2020/template/",
|
||||||
)
|
)
|
||||||
if DJANGO_2_2:
|
if DJANGO_2_2:
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
span.attributes[SpanAttributes.HTTP_ROUTE],
|
span.attributes["http.route"],
|
||||||
"^route/(?P<year>[0-9]{4})/template/$",
|
"^route/(?P<year>[0-9]{4})/template/$",
|
||||||
)
|
)
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
|
self.assertEqual(span.attributes["http.scheme"], "http")
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200)
|
self.assertEqual(span.attributes["http.status_code"], 200)
|
||||||
|
|
||||||
def test_traced_get(self):
|
def test_traced_get(self):
|
||||||
Client().get("/traced/")
|
Client().get("/traced/")
|
||||||
|
|
@ -221,17 +199,15 @@ class TestMiddleware(WsgiTestBase):
|
||||||
self.assertEqual(span.name, "GET ^traced/" if DJANGO_2_2 else "GET")
|
self.assertEqual(span.name, "GET ^traced/" if DJANGO_2_2 else "GET")
|
||||||
self.assertEqual(span.kind, SpanKind.SERVER)
|
self.assertEqual(span.kind, SpanKind.SERVER)
|
||||||
self.assertEqual(span.status.status_code, StatusCode.UNSET)
|
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(
|
self.assertEqual(
|
||||||
span.attributes[SpanAttributes.HTTP_URL],
|
span.attributes["http.url"],
|
||||||
"http://testserver/traced/",
|
"http://testserver/traced/",
|
||||||
)
|
)
|
||||||
if DJANGO_2_2:
|
if DJANGO_2_2:
|
||||||
self.assertEqual(
|
self.assertEqual(span.attributes["http.route"], "^traced/")
|
||||||
span.attributes[SpanAttributes.HTTP_ROUTE], "^traced/"
|
self.assertEqual(span.attributes["http.scheme"], "http")
|
||||||
)
|
self.assertEqual(span.attributes["http.status_code"], 200)
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
|
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200)
|
|
||||||
|
|
||||||
def test_traced_get_new_semconv(self):
|
def test_traced_get_new_semconv(self):
|
||||||
Client().get("/traced/")
|
Client().get("/traced/")
|
||||||
|
|
@ -244,14 +220,14 @@ class TestMiddleware(WsgiTestBase):
|
||||||
self.assertEqual(span.name, "GET ^traced/" if DJANGO_2_2 else "GET")
|
self.assertEqual(span.name, "GET ^traced/" if DJANGO_2_2 else "GET")
|
||||||
self.assertEqual(span.kind, SpanKind.SERVER)
|
self.assertEqual(span.kind, SpanKind.SERVER)
|
||||||
self.assertEqual(span.status.status_code, StatusCode.UNSET)
|
self.assertEqual(span.status.status_code, StatusCode.UNSET)
|
||||||
self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET")
|
self.assertEqual(span.attributes["http.request.method"], "GET")
|
||||||
self.assertEqual(span.attributes[URL_SCHEME], "http")
|
self.assertEqual(span.attributes["url.scheme"], "http")
|
||||||
self.assertEqual(span.attributes[SERVER_PORT], 80)
|
self.assertEqual(span.attributes["server.port"], 80)
|
||||||
self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1")
|
self.assertEqual(span.attributes["client.address"], "127.0.0.1")
|
||||||
self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1")
|
self.assertEqual(span.attributes["network.protocol.version"], "1.1")
|
||||||
if DJANGO_2_2:
|
if DJANGO_2_2:
|
||||||
self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/")
|
self.assertEqual(span.attributes["http.route"], "^traced/")
|
||||||
self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200)
|
self.assertEqual(span.attributes["http.response.status_code"], 200)
|
||||||
|
|
||||||
def test_traced_get_both_semconv(self):
|
def test_traced_get_both_semconv(self):
|
||||||
Client().get("/traced/")
|
Client().get("/traced/")
|
||||||
|
|
@ -264,25 +240,23 @@ class TestMiddleware(WsgiTestBase):
|
||||||
self.assertEqual(span.name, "GET ^traced/" if DJANGO_2_2 else "GET")
|
self.assertEqual(span.name, "GET ^traced/" if DJANGO_2_2 else "GET")
|
||||||
self.assertEqual(span.kind, SpanKind.SERVER)
|
self.assertEqual(span.kind, SpanKind.SERVER)
|
||||||
self.assertEqual(span.status.status_code, StatusCode.UNSET)
|
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(
|
self.assertEqual(
|
||||||
span.attributes[SpanAttributes.HTTP_URL],
|
span.attributes["http.url"],
|
||||||
"http://testserver/traced/",
|
"http://testserver/traced/",
|
||||||
)
|
)
|
||||||
if DJANGO_2_2:
|
if DJANGO_2_2:
|
||||||
self.assertEqual(
|
self.assertEqual(span.attributes["http.route"], "^traced/")
|
||||||
span.attributes[SpanAttributes.HTTP_ROUTE], "^traced/"
|
self.assertEqual(span.attributes["http.scheme"], "http")
|
||||||
)
|
self.assertEqual(span.attributes["http.status_code"], 200)
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
|
self.assertEqual(span.attributes["http.request.method"], "GET")
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200)
|
self.assertEqual(span.attributes["url.scheme"], "http")
|
||||||
self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET")
|
self.assertEqual(span.attributes["server.port"], 80)
|
||||||
self.assertEqual(span.attributes[URL_SCHEME], "http")
|
self.assertEqual(span.attributes["client.address"], "127.0.0.1")
|
||||||
self.assertEqual(span.attributes[SERVER_PORT], 80)
|
self.assertEqual(span.attributes["network.protocol.version"], "1.1")
|
||||||
self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1")
|
|
||||||
self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1")
|
|
||||||
if DJANGO_2_2:
|
if DJANGO_2_2:
|
||||||
self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/")
|
self.assertEqual(span.attributes["http.route"], "^traced/")
|
||||||
self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200)
|
self.assertEqual(span.attributes["http.response.status_code"], 200)
|
||||||
|
|
||||||
def test_not_recording(self):
|
def test_not_recording(self):
|
||||||
mock_tracer = Mock()
|
mock_tracer = Mock()
|
||||||
|
|
@ -318,17 +292,15 @@ class TestMiddleware(WsgiTestBase):
|
||||||
self.assertEqual(span.name, "POST ^traced/" if DJANGO_2_2 else "POST")
|
self.assertEqual(span.name, "POST ^traced/" if DJANGO_2_2 else "POST")
|
||||||
self.assertEqual(span.kind, SpanKind.SERVER)
|
self.assertEqual(span.kind, SpanKind.SERVER)
|
||||||
self.assertEqual(span.status.status_code, StatusCode.UNSET)
|
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(
|
self.assertEqual(
|
||||||
span.attributes[SpanAttributes.HTTP_URL],
|
span.attributes["http.url"],
|
||||||
"http://testserver/traced/",
|
"http://testserver/traced/",
|
||||||
)
|
)
|
||||||
if DJANGO_2_2:
|
if DJANGO_2_2:
|
||||||
self.assertEqual(
|
self.assertEqual(span.attributes["http.route"], "^traced/")
|
||||||
span.attributes[SpanAttributes.HTTP_ROUTE], "^traced/"
|
self.assertEqual(span.attributes["http.scheme"], "http")
|
||||||
)
|
self.assertEqual(span.attributes["http.status_code"], 200)
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
|
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200)
|
|
||||||
|
|
||||||
def test_traced_post_new_semconv(self):
|
def test_traced_post_new_semconv(self):
|
||||||
Client().post("/traced/")
|
Client().post("/traced/")
|
||||||
|
|
@ -341,14 +313,14 @@ class TestMiddleware(WsgiTestBase):
|
||||||
self.assertEqual(span.name, "POST ^traced/" if DJANGO_2_2 else "POST")
|
self.assertEqual(span.name, "POST ^traced/" if DJANGO_2_2 else "POST")
|
||||||
self.assertEqual(span.kind, SpanKind.SERVER)
|
self.assertEqual(span.kind, SpanKind.SERVER)
|
||||||
self.assertEqual(span.status.status_code, StatusCode.UNSET)
|
self.assertEqual(span.status.status_code, StatusCode.UNSET)
|
||||||
self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "POST")
|
self.assertEqual(span.attributes["http.request.method"], "POST")
|
||||||
self.assertEqual(span.attributes[URL_SCHEME], "http")
|
self.assertEqual(span.attributes["url.scheme"], "http")
|
||||||
self.assertEqual(span.attributes[SERVER_PORT], 80)
|
self.assertEqual(span.attributes["server.port"], 80)
|
||||||
self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1")
|
self.assertEqual(span.attributes["client.address"], "127.0.0.1")
|
||||||
self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1")
|
self.assertEqual(span.attributes["network.protocol.version"], "1.1")
|
||||||
if DJANGO_2_2:
|
if DJANGO_2_2:
|
||||||
self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/")
|
self.assertEqual(span.attributes["http.route"], "^traced/")
|
||||||
self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200)
|
self.assertEqual(span.attributes["http.response.status_code"], 200)
|
||||||
|
|
||||||
def test_traced_post_both_semconv(self):
|
def test_traced_post_both_semconv(self):
|
||||||
Client().post("/traced/")
|
Client().post("/traced/")
|
||||||
|
|
@ -361,21 +333,21 @@ class TestMiddleware(WsgiTestBase):
|
||||||
self.assertEqual(span.name, "POST ^traced/" if DJANGO_2_2 else "POST")
|
self.assertEqual(span.name, "POST ^traced/" if DJANGO_2_2 else "POST")
|
||||||
self.assertEqual(span.kind, SpanKind.SERVER)
|
self.assertEqual(span.kind, SpanKind.SERVER)
|
||||||
self.assertEqual(span.status.status_code, StatusCode.UNSET)
|
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(
|
self.assertEqual(
|
||||||
span.attributes[SpanAttributes.HTTP_URL],
|
span.attributes["http.url"],
|
||||||
"http://testserver/traced/",
|
"http://testserver/traced/",
|
||||||
)
|
)
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
|
self.assertEqual(span.attributes["http.scheme"], "http")
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 200)
|
self.assertEqual(span.attributes["http.status_code"], 200)
|
||||||
self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "POST")
|
self.assertEqual(span.attributes["http.request.method"], "POST")
|
||||||
self.assertEqual(span.attributes[URL_SCHEME], "http")
|
self.assertEqual(span.attributes["url.scheme"], "http")
|
||||||
self.assertEqual(span.attributes[SERVER_PORT], 80)
|
self.assertEqual(span.attributes["server.port"], 80)
|
||||||
self.assertEqual(span.attributes[CLIENT_ADDRESS], "127.0.0.1")
|
self.assertEqual(span.attributes["client.address"], "127.0.0.1")
|
||||||
self.assertEqual(span.attributes[NETWORK_PROTOCOL_VERSION], "1.1")
|
self.assertEqual(span.attributes["network.protocol.version"], "1.1")
|
||||||
if DJANGO_2_2:
|
if DJANGO_2_2:
|
||||||
self.assertEqual(span.attributes[HTTP_ROUTE], "^traced/")
|
self.assertEqual(span.attributes["http.route"], "^traced/")
|
||||||
self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 200)
|
self.assertEqual(span.attributes["http.response.status_code"], 200)
|
||||||
|
|
||||||
def test_error(self):
|
def test_error(self):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
|
|
@ -389,27 +361,21 @@ class TestMiddleware(WsgiTestBase):
|
||||||
self.assertEqual(span.name, "GET ^error/" if DJANGO_2_2 else "GET")
|
self.assertEqual(span.name, "GET ^error/" if DJANGO_2_2 else "GET")
|
||||||
self.assertEqual(span.kind, SpanKind.SERVER)
|
self.assertEqual(span.kind, SpanKind.SERVER)
|
||||||
self.assertEqual(span.status.status_code, StatusCode.ERROR)
|
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(
|
self.assertEqual(
|
||||||
span.attributes[SpanAttributes.HTTP_URL],
|
span.attributes["http.url"],
|
||||||
"http://testserver/error/",
|
"http://testserver/error/",
|
||||||
)
|
)
|
||||||
if DJANGO_2_2:
|
if DJANGO_2_2:
|
||||||
self.assertEqual(
|
self.assertEqual(span.attributes["http.route"], "^error/")
|
||||||
span.attributes[SpanAttributes.HTTP_ROUTE], "^error/"
|
self.assertEqual(span.attributes["http.scheme"], "http")
|
||||||
)
|
self.assertEqual(span.attributes["http.status_code"], 500)
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
|
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 500)
|
|
||||||
|
|
||||||
self.assertEqual(len(span.events), 1)
|
self.assertEqual(len(span.events), 1)
|
||||||
event = span.events[0]
|
event = span.events[0]
|
||||||
self.assertEqual(event.name, "exception")
|
self.assertEqual(event.name, "exception")
|
||||||
self.assertEqual(
|
self.assertEqual(event.attributes["exception.type"], "ValueError")
|
||||||
event.attributes[SpanAttributes.EXCEPTION_TYPE], "ValueError"
|
self.assertEqual(event.attributes["exception.message"], "error")
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
event.attributes[SpanAttributes.EXCEPTION_MESSAGE], "error"
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_error_new_semconv(self):
|
def test_error_new_semconv(self):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
|
|
@ -423,18 +389,18 @@ class TestMiddleware(WsgiTestBase):
|
||||||
self.assertEqual(span.name, "GET ^error/" if DJANGO_2_2 else "GET")
|
self.assertEqual(span.name, "GET ^error/" if DJANGO_2_2 else "GET")
|
||||||
self.assertEqual(span.kind, SpanKind.SERVER)
|
self.assertEqual(span.kind, SpanKind.SERVER)
|
||||||
self.assertEqual(span.status.status_code, StatusCode.ERROR)
|
self.assertEqual(span.status.status_code, StatusCode.ERROR)
|
||||||
self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET")
|
self.assertEqual(span.attributes["http.request.method"], "GET")
|
||||||
if DJANGO_2_2:
|
if DJANGO_2_2:
|
||||||
self.assertEqual(span.attributes[HTTP_ROUTE], "^error/")
|
self.assertEqual(span.attributes["http.route"], "^error/")
|
||||||
self.assertEqual(span.attributes[URL_SCHEME], "http")
|
self.assertEqual(span.attributes["url.scheme"], "http")
|
||||||
self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 500)
|
self.assertEqual(span.attributes["http.response.status_code"], 500)
|
||||||
|
|
||||||
self.assertEqual(len(span.events), 1)
|
self.assertEqual(len(span.events), 1)
|
||||||
event = span.events[0]
|
event = span.events[0]
|
||||||
self.assertEqual(event.name, "exception")
|
self.assertEqual(event.name, "exception")
|
||||||
self.assertEqual(event.attributes[EXCEPTION_TYPE], "ValueError")
|
self.assertEqual(event.attributes["exception.type"], "ValueError")
|
||||||
self.assertEqual(event.attributes[EXCEPTION_MESSAGE], "error")
|
self.assertEqual(event.attributes["exception.message"], "error")
|
||||||
self.assertEqual(span.attributes[ERROR_TYPE], "500")
|
self.assertEqual(span.attributes["error.type"], "500")
|
||||||
|
|
||||||
def test_error_both_semconv(self):
|
def test_error_both_semconv(self):
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
|
|
@ -448,29 +414,27 @@ class TestMiddleware(WsgiTestBase):
|
||||||
self.assertEqual(span.name, "GET ^error/" if DJANGO_2_2 else "GET")
|
self.assertEqual(span.name, "GET ^error/" if DJANGO_2_2 else "GET")
|
||||||
self.assertEqual(span.kind, SpanKind.SERVER)
|
self.assertEqual(span.kind, SpanKind.SERVER)
|
||||||
self.assertEqual(span.status.status_code, StatusCode.ERROR)
|
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(
|
self.assertEqual(
|
||||||
span.attributes[SpanAttributes.HTTP_URL],
|
span.attributes["http.url"],
|
||||||
"http://testserver/error/",
|
"http://testserver/error/",
|
||||||
)
|
)
|
||||||
if DJANGO_2_2:
|
if DJANGO_2_2:
|
||||||
self.assertEqual(
|
self.assertEqual(span.attributes["http.route"], "^error/")
|
||||||
span.attributes[SpanAttributes.HTTP_ROUTE], "^error/"
|
self.assertEqual(span.attributes["http.scheme"], "http")
|
||||||
)
|
self.assertEqual(span.attributes["http.status_code"], 500)
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_SCHEME], "http")
|
self.assertEqual(span.attributes["http.request.method"], "GET")
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_STATUS_CODE], 500)
|
|
||||||
self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "GET")
|
|
||||||
if DJANGO_2_2:
|
if DJANGO_2_2:
|
||||||
self.assertEqual(span.attributes[HTTP_ROUTE], "^error/")
|
self.assertEqual(span.attributes["http.route"], "^error/")
|
||||||
self.assertEqual(span.attributes[URL_SCHEME], "http")
|
self.assertEqual(span.attributes["url.scheme"], "http")
|
||||||
self.assertEqual(span.attributes[HTTP_RESPONSE_STATUS_CODE], 500)
|
self.assertEqual(span.attributes["http.response.status_code"], 500)
|
||||||
|
|
||||||
self.assertEqual(len(span.events), 1)
|
self.assertEqual(len(span.events), 1)
|
||||||
event = span.events[0]
|
event = span.events[0]
|
||||||
self.assertEqual(event.name, "exception")
|
self.assertEqual(event.name, "exception")
|
||||||
self.assertEqual(event.attributes[EXCEPTION_TYPE], "ValueError")
|
self.assertEqual(event.attributes["exception.type"], "ValueError")
|
||||||
self.assertEqual(event.attributes[EXCEPTION_MESSAGE], "error")
|
self.assertEqual(event.attributes["exception.message"], "error")
|
||||||
self.assertEqual(span.attributes[ERROR_TYPE], "500")
|
self.assertEqual(span.attributes["error.type"], "500")
|
||||||
|
|
||||||
def test_exclude_lists(self):
|
def test_exclude_lists(self):
|
||||||
client = Client()
|
client = Client()
|
||||||
|
|
@ -545,7 +509,7 @@ class TestMiddleware(WsgiTestBase):
|
||||||
|
|
||||||
span = span_list[0]
|
span = span_list[0]
|
||||||
self.assertEqual(span.name, "HTTP")
|
self.assertEqual(span.name, "HTTP")
|
||||||
self.assertEqual(span.attributes[SpanAttributes.HTTP_METHOD], "_OTHER")
|
self.assertEqual(span.attributes["http.method"], "_OTHER")
|
||||||
|
|
||||||
def test_nonstandard_http_method_span_name_new_semconv(self):
|
def test_nonstandard_http_method_span_name_new_semconv(self):
|
||||||
Client().request(
|
Client().request(
|
||||||
|
|
@ -556,9 +520,9 @@ class TestMiddleware(WsgiTestBase):
|
||||||
|
|
||||||
span = span_list[0]
|
span = span_list[0]
|
||||||
self.assertEqual(span.name, "HTTP")
|
self.assertEqual(span.name, "HTTP")
|
||||||
self.assertEqual(span.attributes[HTTP_REQUEST_METHOD], "_OTHER")
|
self.assertEqual(span.attributes["http.request.method"], "_OTHER")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
span.attributes[HTTP_REQUEST_METHOD_ORIGINAL], "NONSTANDARD"
|
span.attributes["http.request.method_original"], "NONSTANDARD"
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_nonstandard_http_method_span_name_both_semconv(self):
|
def test_nonstandard_http_method_span_name_both_semconv(self):
|
||||||
|
|
@ -570,10 +534,10 @@ class TestMiddleware(WsgiTestBase):
|
||||||
|
|
||||||
span = span_list[0]
|
span = span_list[0]
|
||||||
self.assertEqual(span.name, "HTTP")
|
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"], "_OTHER")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
span.attributes[HTTP_REQUEST_METHOD_ORIGINAL], "NONSTANDARD"
|
span.attributes["http.request.method_original"], "NONSTANDARD"
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_traced_request_attrs(self):
|
def test_traced_request_attrs(self):
|
||||||
|
|
@ -711,9 +675,20 @@ class TestMiddleware(WsgiTestBase):
|
||||||
"http.server.active_requests",
|
"http.server.active_requests",
|
||||||
"http.server.duration",
|
"http.server.duration",
|
||||||
]
|
]
|
||||||
_recommended_attrs = {
|
expected_duration_attributes = {
|
||||||
"http.server.active_requests": _server_active_requests_count_attrs_old,
|
"http.method": "GET",
|
||||||
"http.server.duration": _server_duration_attrs_old,
|
"http.scheme": "http",
|
||||||
|
"http.flavor": "1.1",
|
||||||
|
"http.server_name": "testserver",
|
||||||
|
"net.host.port": 80,
|
||||||
|
"http.status_code": 200,
|
||||||
|
"http.target": "^span_name/([0-9]{4})/$",
|
||||||
|
}
|
||||||
|
expected_requests_count_attributes = {
|
||||||
|
"http.method": "GET",
|
||||||
|
"http.scheme": "http",
|
||||||
|
"http.flavor": "1.1",
|
||||||
|
"http.server_name": "testserver",
|
||||||
}
|
}
|
||||||
start = default_timer()
|
start = default_timer()
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
|
|
@ -740,12 +715,16 @@ class TestMiddleware(WsgiTestBase):
|
||||||
self.assertAlmostEqual(
|
self.assertAlmostEqual(
|
||||||
duration, point.sum, delta=100
|
duration, point.sum, delta=100
|
||||||
)
|
)
|
||||||
|
self.assertDictEqual(
|
||||||
|
expected_duration_attributes,
|
||||||
|
dict(point.attributes),
|
||||||
|
)
|
||||||
if isinstance(point, NumberDataPoint):
|
if isinstance(point, NumberDataPoint):
|
||||||
number_data_point_seen = True
|
number_data_point_seen = True
|
||||||
self.assertEqual(point.value, 0)
|
self.assertEqual(point.value, 0)
|
||||||
for attr in point.attributes:
|
self.assertDictEqual(
|
||||||
self.assertIn(
|
expected_requests_count_attributes,
|
||||||
attr, _recommended_attrs[metric.name]
|
dict(point.attributes),
|
||||||
)
|
)
|
||||||
self.assertTrue(histrogram_data_point_seen and number_data_point_seen)
|
self.assertTrue(histrogram_data_point_seen and number_data_point_seen)
|
||||||
|
|
||||||
|
|
@ -755,9 +734,16 @@ class TestMiddleware(WsgiTestBase):
|
||||||
"http.server.active_requests",
|
"http.server.active_requests",
|
||||||
"http.server.request.duration",
|
"http.server.request.duration",
|
||||||
]
|
]
|
||||||
_recommended_attrs = {
|
expected_duration_attributes = {
|
||||||
"http.server.active_requests": _server_active_requests_count_attrs_new,
|
"http.request.method": "GET",
|
||||||
"http.server.request.duration": _server_duration_attrs_new,
|
"url.scheme": "http",
|
||||||
|
"network.protocol.version": "1.1",
|
||||||
|
"http.response.status_code": 200,
|
||||||
|
"http.route": "^span_name/([0-9]{4})/$",
|
||||||
|
}
|
||||||
|
expected_requests_count_attributes = {
|
||||||
|
"http.request.method": "GET",
|
||||||
|
"url.scheme": "http",
|
||||||
}
|
}
|
||||||
start = default_timer()
|
start = default_timer()
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
|
|
@ -784,12 +770,16 @@ class TestMiddleware(WsgiTestBase):
|
||||||
self.assertAlmostEqual(
|
self.assertAlmostEqual(
|
||||||
duration_s, point.sum, places=1
|
duration_s, point.sum, places=1
|
||||||
)
|
)
|
||||||
|
self.assertDictEqual(
|
||||||
|
expected_duration_attributes,
|
||||||
|
dict(point.attributes),
|
||||||
|
)
|
||||||
if isinstance(point, NumberDataPoint):
|
if isinstance(point, NumberDataPoint):
|
||||||
number_data_point_seen = True
|
number_data_point_seen = True
|
||||||
self.assertEqual(point.value, 0)
|
self.assertEqual(point.value, 0)
|
||||||
for attr in point.attributes:
|
self.assertDictEqual(
|
||||||
self.assertIn(
|
expected_requests_count_attributes,
|
||||||
attr, _recommended_attrs[metric.name]
|
dict(point.attributes),
|
||||||
)
|
)
|
||||||
self.assertTrue(histrogram_data_point_seen and number_data_point_seen)
|
self.assertTrue(histrogram_data_point_seen and number_data_point_seen)
|
||||||
|
|
||||||
|
|
@ -801,12 +791,29 @@ class TestMiddleware(WsgiTestBase):
|
||||||
"http.server.active_requests",
|
"http.server.active_requests",
|
||||||
"http.server.request.duration",
|
"http.server.request.duration",
|
||||||
]
|
]
|
||||||
active_count_both_attrs = list(_server_active_requests_count_attrs_new)
|
expected_duration_attributes_old = {
|
||||||
active_count_both_attrs.extend(_server_active_requests_count_attrs_old)
|
"http.method": "GET",
|
||||||
_recommended_attrs = {
|
"http.scheme": "http",
|
||||||
"http.server.active_requests": active_count_both_attrs,
|
"http.flavor": "1.1",
|
||||||
"http.server.request.duration": _server_duration_attrs_new,
|
"http.server_name": "testserver",
|
||||||
"http.server.duration": _server_duration_attrs_old,
|
"net.host.port": 80,
|
||||||
|
"http.status_code": 200,
|
||||||
|
"http.target": "^span_name/([0-9]{4})/$",
|
||||||
|
}
|
||||||
|
expected_duration_attributes_new = {
|
||||||
|
"http.request.method": "GET",
|
||||||
|
"url.scheme": "http",
|
||||||
|
"network.protocol.version": "1.1",
|
||||||
|
"http.response.status_code": 200,
|
||||||
|
"http.route": "^span_name/([0-9]{4})/$",
|
||||||
|
}
|
||||||
|
expected_requests_count_attributes = {
|
||||||
|
"http.method": "GET",
|
||||||
|
"http.scheme": "http",
|
||||||
|
"http.flavor": "1.1",
|
||||||
|
"http.server_name": "testserver",
|
||||||
|
"http.request.method": "GET",
|
||||||
|
"url.scheme": "http",
|
||||||
}
|
}
|
||||||
start = default_timer()
|
start = default_timer()
|
||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
|
|
@ -835,16 +842,24 @@ class TestMiddleware(WsgiTestBase):
|
||||||
self.assertAlmostEqual(
|
self.assertAlmostEqual(
|
||||||
duration_s, point.sum, places=1
|
duration_s, point.sum, places=1
|
||||||
)
|
)
|
||||||
|
self.assertDictEqual(
|
||||||
|
expected_duration_attributes_new,
|
||||||
|
dict(point.attributes),
|
||||||
|
)
|
||||||
elif metric.name == "http.server.duration":
|
elif metric.name == "http.server.duration":
|
||||||
self.assertAlmostEqual(
|
self.assertAlmostEqual(
|
||||||
duration, point.sum, delta=100
|
duration, point.sum, delta=100
|
||||||
)
|
)
|
||||||
|
self.assertDictEqual(
|
||||||
|
expected_duration_attributes_old,
|
||||||
|
dict(point.attributes),
|
||||||
|
)
|
||||||
if isinstance(point, NumberDataPoint):
|
if isinstance(point, NumberDataPoint):
|
||||||
number_data_point_seen = True
|
number_data_point_seen = True
|
||||||
self.assertEqual(point.value, 0)
|
self.assertEqual(point.value, 0)
|
||||||
for attr in point.attributes:
|
self.assertDictEqual(
|
||||||
self.assertIn(
|
expected_requests_count_attributes,
|
||||||
attr, _recommended_attrs[metric.name]
|
dict(point.attributes),
|
||||||
)
|
)
|
||||||
self.assertTrue(histrogram_data_point_seen and number_data_point_seen)
|
self.assertTrue(histrogram_data_point_seen and number_data_point_seen)
|
||||||
|
|
||||||
|
|
@ -911,9 +926,7 @@ class TestMiddlewareWithTracerProvider(WsgiTestBase):
|
||||||
Client().get("/span_name/1234/")
|
Client().get("/span_name/1234/")
|
||||||
span_list = self.exporter.get_finished_spans()
|
span_list = self.exporter.get_finished_spans()
|
||||||
print(span_list)
|
print(span_list)
|
||||||
self.assertEqual(
|
self.assertEqual(span_list[0].attributes["http.status_code"], 200)
|
||||||
span_list[0].attributes[SpanAttributes.HTTP_STATUS_CODE], 200
|
|
||||||
)
|
|
||||||
self.assertEqual(trace.SpanKind.INTERNAL, span_list[0].kind)
|
self.assertEqual(trace.SpanKind.INTERNAL, span_list[0].kind)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
parent_span.get_span_context().span_id,
|
parent_span.get_span_context().span_id,
|
||||||
|
|
|
||||||
|
|
@ -395,6 +395,7 @@ def _rewrapped_app(
|
||||||
)
|
)
|
||||||
|
|
||||||
if request_route:
|
if request_route:
|
||||||
|
# http.target to be included in old semantic conventions
|
||||||
duration_attrs_old[SpanAttributes.HTTP_TARGET] = str(
|
duration_attrs_old[SpanAttributes.HTTP_TARGET] = str(
|
||||||
request_route
|
request_route
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue