Skip to content

Commit 18b8962

Browse files
authored
Merge branch 'main' into fix-asgi-middleware
2 parents 808d42a + ef2b546 commit 18b8962

File tree

3 files changed

+144
-148
lines changed

3 files changed

+144
-148
lines changed

instrumentation/opentelemetry-instrumentation-fastapi/src/opentelemetry/instrumentation/fastapi/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A
209209
from opentelemetry.instrumentation.fastapi.version import __version__
210210
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
211211
from opentelemetry.metrics import MeterProvider, get_meter
212+
from opentelemetry.semconv.attributes.http_attributes import HTTP_ROUTE
212213
from opentelemetry.semconv.trace import SpanAttributes
213214
from opentelemetry.trace import TracerProvider, get_tracer
214215
from opentelemetry.util.http import (
@@ -472,7 +473,7 @@ def _get_default_span_details(scope):
472473
if method == "_OTHER":
473474
method = "HTTP"
474475
if route:
475-
attributes[SpanAttributes.HTTP_ROUTE] = route
476+
attributes[HTTP_ROUTE] = route
476477
if method and route: # http
477478
span_name = f"{method} {route}"
478479
elif route: # websocket

instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py

Lines changed: 82 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,19 @@
4747
NumberDataPoint,
4848
)
4949
from opentelemetry.sdk.resources import Resource
50+
from opentelemetry.semconv._incubating.attributes.http_attributes import (
51+
HTTP_FLAVOR,
52+
HTTP_HOST,
53+
HTTP_METHOD,
54+
HTTP_SCHEME,
55+
HTTP_SERVER_NAME,
56+
HTTP_STATUS_CODE,
57+
HTTP_TARGET,
58+
HTTP_URL,
59+
)
60+
from opentelemetry.semconv._incubating.attributes.net_attributes import (
61+
NET_HOST_PORT,
62+
)
5063
from opentelemetry.semconv.attributes.http_attributes import (
5164
HTTP_REQUEST_METHOD,
5265
HTTP_RESPONSE_STATUS_CODE,
@@ -56,7 +69,6 @@
5669
NETWORK_PROTOCOL_VERSION,
5770
)
5871
from opentelemetry.semconv.attributes.url_attributes import URL_SCHEME
59-
from opentelemetry.semconv.trace import SpanAttributes
6072
from opentelemetry.test.globals_test import reset_trace_globals
6173
from opentelemetry.test.test_base import TestBase
6274
from opentelemetry.util._importlib_metadata import entry_points
@@ -86,15 +98,15 @@
8698
"http.server.active_requests": _server_active_requests_count_attrs_old,
8799
"http.server.duration": {
88100
*_server_duration_attrs_old,
89-
SpanAttributes.HTTP_TARGET,
101+
HTTP_TARGET,
90102
},
91103
"http.server.response.size": {
92104
*_server_duration_attrs_old,
93-
SpanAttributes.HTTP_TARGET,
105+
HTTP_TARGET,
94106
},
95107
"http.server.request.size": {
96108
*_server_duration_attrs_old,
97-
SpanAttributes.HTTP_TARGET,
109+
HTTP_TARGET,
98110
},
99111
}
100112

@@ -279,23 +291,18 @@ def test_sub_app_fastapi_call(self):
279291
spans_with_http_attributes = [
280292
span
281293
for span in spans
282-
if (
283-
SpanAttributes.HTTP_URL in span.attributes
284-
or SpanAttributes.HTTP_TARGET in span.attributes
285-
)
294+
if (HTTP_URL in span.attributes or HTTP_TARGET in span.attributes)
286295
]
287296

288297
# We expect only one span to have the HTTP attributes set (the SERVER span from the app itself)
289298
# the sub app is not instrumented with manual instrumentation tests.
290299
self.assertEqual(1, len(spans_with_http_attributes))
291300

292301
for span in spans_with_http_attributes:
293-
self.assertEqual(
294-
"/sub/home", span.attributes[SpanAttributes.HTTP_TARGET]
295-
)
302+
self.assertEqual("/sub/home", span.attributes[HTTP_TARGET])
296303
self.assertEqual(
297304
"https://testserver:443/sub/home",
298-
span.attributes[SpanAttributes.HTTP_URL],
305+
span.attributes[HTTP_URL],
299306
)
300307

301308

@@ -343,22 +350,17 @@ def test_sub_app_fastapi_call(self):
343350
spans_with_http_attributes = [
344351
span
345352
for span in spans
346-
if (
347-
SpanAttributes.HTTP_URL in span.attributes
348-
or SpanAttributes.HTTP_TARGET in span.attributes
349-
)
353+
if (HTTP_URL in span.attributes or HTTP_TARGET in span.attributes)
350354
]
351355

352356
# We now expect spans with attributes from both the app and its sub app
353357
self.assertEqual(2, len(spans_with_http_attributes))
354358

355359
for span in spans_with_http_attributes:
356-
self.assertEqual(
357-
"/sub/home", span.attributes[SpanAttributes.HTTP_TARGET]
358-
)
360+
self.assertEqual("/sub/home", span.attributes[HTTP_TARGET])
359361
self.assertEqual(
360362
"https://testserver:443/sub/home",
361-
span.attributes[SpanAttributes.HTTP_URL],
363+
span.attributes[HTTP_URL],
362364
)
363365

364366

@@ -416,14 +418,10 @@ def test_fastapi_route_attribute_added(self):
416418
self.assertEqual(len(spans), 3)
417419
for span in spans:
418420
self.assertIn("GET /user/{username}", span.name)
419-
self.assertEqual(
420-
spans[-1].attributes[SpanAttributes.HTTP_ROUTE], "/user/{username}"
421-
)
421+
self.assertEqual(spans[-1].attributes[HTTP_ROUTE], "/user/{username}")
422422
# ensure that at least one attribute that is populated by
423423
# the asgi instrumentation is successfully feeding though.
424-
self.assertEqual(
425-
spans[-1].attributes[SpanAttributes.HTTP_FLAVOR], "1.1"
426-
)
424+
self.assertEqual(spans[-1].attributes[HTTP_FLAVOR], "1.1")
427425

428426
def test_fastapi_excluded_urls(self):
429427
"""Ensure that given fastapi routes are excluded."""
@@ -546,21 +544,21 @@ def test_basic_metric_success(self):
546544
self._client.get("/foobar")
547545
duration = max(round((default_timer() - start) * 1000), 0)
548546
expected_duration_attributes = {
549-
SpanAttributes.HTTP_METHOD: "GET",
550-
SpanAttributes.HTTP_HOST: "testserver:443",
551-
SpanAttributes.HTTP_SCHEME: "https",
552-
SpanAttributes.HTTP_FLAVOR: "1.1",
553-
SpanAttributes.HTTP_SERVER_NAME: "testserver",
554-
SpanAttributes.NET_HOST_PORT: 443,
555-
SpanAttributes.HTTP_STATUS_CODE: 200,
556-
SpanAttributes.HTTP_TARGET: "/foobar",
547+
HTTP_METHOD: "GET",
548+
HTTP_HOST: "testserver:443",
549+
HTTP_SCHEME: "https",
550+
HTTP_FLAVOR: "1.1",
551+
HTTP_SERVER_NAME: "testserver",
552+
NET_HOST_PORT: 443,
553+
HTTP_STATUS_CODE: 200,
554+
HTTP_TARGET: "/foobar",
557555
}
558556
expected_requests_count_attributes = {
559-
SpanAttributes.HTTP_METHOD: "GET",
560-
SpanAttributes.HTTP_HOST: "testserver:443",
561-
SpanAttributes.HTTP_SCHEME: "https",
562-
SpanAttributes.HTTP_FLAVOR: "1.1",
563-
SpanAttributes.HTTP_SERVER_NAME: "testserver",
557+
HTTP_METHOD: "GET",
558+
HTTP_HOST: "testserver:443",
559+
HTTP_SCHEME: "https",
560+
HTTP_FLAVOR: "1.1",
561+
HTTP_SERVER_NAME: "testserver",
564562
}
565563
metrics_list = self.memory_metrics_reader.get_metrics_data()
566564
for metric in (
@@ -628,14 +626,14 @@ def test_basic_metric_success_both_semconv(self):
628626
duration = max(round((default_timer() - start) * 1000), 0)
629627
duration_s = max(default_timer() - start, 0)
630628
expected_duration_attributes_old = {
631-
SpanAttributes.HTTP_METHOD: "GET",
632-
SpanAttributes.HTTP_HOST: "testserver:443",
633-
SpanAttributes.HTTP_SCHEME: "https",
634-
SpanAttributes.HTTP_FLAVOR: "1.1",
635-
SpanAttributes.HTTP_SERVER_NAME: "testserver",
636-
SpanAttributes.NET_HOST_PORT: 443,
637-
SpanAttributes.HTTP_STATUS_CODE: 200,
638-
SpanAttributes.HTTP_TARGET: "/foobar",
629+
HTTP_METHOD: "GET",
630+
HTTP_HOST: "testserver:443",
631+
HTTP_SCHEME: "https",
632+
HTTP_FLAVOR: "1.1",
633+
HTTP_SERVER_NAME: "testserver",
634+
NET_HOST_PORT: 443,
635+
HTTP_STATUS_CODE: 200,
636+
HTTP_TARGET: "/foobar",
639637
}
640638
expected_duration_attributes_new = {
641639
HTTP_REQUEST_METHOD: "GET",
@@ -645,11 +643,11 @@ def test_basic_metric_success_both_semconv(self):
645643
HTTP_ROUTE: "/foobar",
646644
}
647645
expected_requests_count_attributes = {
648-
SpanAttributes.HTTP_METHOD: "GET",
649-
SpanAttributes.HTTP_HOST: "testserver:443",
650-
SpanAttributes.HTTP_SCHEME: "https",
651-
SpanAttributes.HTTP_FLAVOR: "1.1",
652-
SpanAttributes.HTTP_SERVER_NAME: "testserver",
646+
HTTP_METHOD: "GET",
647+
HTTP_HOST: "testserver:443",
648+
HTTP_SCHEME: "https",
649+
HTTP_FLAVOR: "1.1",
650+
HTTP_SERVER_NAME: "testserver",
653651
HTTP_REQUEST_METHOD: "GET",
654652
URL_SCHEME: "https",
655653
}
@@ -711,21 +709,21 @@ def test_basic_metric_nonstandard_http_method_success(self):
711709
self._client.request("NONSTANDARD", "/foobar")
712710
duration = max(round((default_timer() - start) * 1000), 0)
713711
expected_duration_attributes = {
714-
SpanAttributes.HTTP_METHOD: "_OTHER",
715-
SpanAttributes.HTTP_HOST: "testserver:443",
716-
SpanAttributes.HTTP_SCHEME: "https",
717-
SpanAttributes.HTTP_FLAVOR: "1.1",
718-
SpanAttributes.HTTP_SERVER_NAME: "testserver",
719-
SpanAttributes.NET_HOST_PORT: 443,
720-
SpanAttributes.HTTP_STATUS_CODE: 405,
721-
SpanAttributes.HTTP_TARGET: "/foobar",
712+
HTTP_METHOD: "_OTHER",
713+
HTTP_HOST: "testserver:443",
714+
HTTP_SCHEME: "https",
715+
HTTP_FLAVOR: "1.1",
716+
HTTP_SERVER_NAME: "testserver",
717+
NET_HOST_PORT: 443,
718+
HTTP_STATUS_CODE: 405,
719+
HTTP_TARGET: "/foobar",
722720
}
723721
expected_requests_count_attributes = {
724-
SpanAttributes.HTTP_METHOD: "_OTHER",
725-
SpanAttributes.HTTP_HOST: "testserver:443",
726-
SpanAttributes.HTTP_SCHEME: "https",
727-
SpanAttributes.HTTP_FLAVOR: "1.1",
728-
SpanAttributes.HTTP_SERVER_NAME: "testserver",
722+
HTTP_METHOD: "_OTHER",
723+
HTTP_HOST: "testserver:443",
724+
HTTP_SCHEME: "https",
725+
HTTP_FLAVOR: "1.1",
726+
HTTP_SERVER_NAME: "testserver",
729727
}
730728
metrics_list = self.memory_metrics_reader.get_metrics_data()
731729
for metric in (
@@ -793,14 +791,14 @@ def test_basic_metric_nonstandard_http_method_success_both_semconv(self):
793791
duration = max(round((default_timer() - start) * 1000), 0)
794792
duration_s = max(default_timer() - start, 0)
795793
expected_duration_attributes_old = {
796-
SpanAttributes.HTTP_METHOD: "_OTHER",
797-
SpanAttributes.HTTP_HOST: "testserver:443",
798-
SpanAttributes.HTTP_SCHEME: "https",
799-
SpanAttributes.HTTP_FLAVOR: "1.1",
800-
SpanAttributes.HTTP_SERVER_NAME: "testserver",
801-
SpanAttributes.NET_HOST_PORT: 443,
802-
SpanAttributes.HTTP_STATUS_CODE: 405,
803-
SpanAttributes.HTTP_TARGET: "/foobar",
794+
HTTP_METHOD: "_OTHER",
795+
HTTP_HOST: "testserver:443",
796+
HTTP_SCHEME: "https",
797+
HTTP_FLAVOR: "1.1",
798+
HTTP_SERVER_NAME: "testserver",
799+
NET_HOST_PORT: 443,
800+
HTTP_STATUS_CODE: 405,
801+
HTTP_TARGET: "/foobar",
804802
}
805803
expected_duration_attributes_new = {
806804
HTTP_REQUEST_METHOD: "_OTHER",
@@ -810,11 +808,11 @@ def test_basic_metric_nonstandard_http_method_success_both_semconv(self):
810808
HTTP_ROUTE: "/foobar",
811809
}
812810
expected_requests_count_attributes = {
813-
SpanAttributes.HTTP_METHOD: "_OTHER",
814-
SpanAttributes.HTTP_HOST: "testserver:443",
815-
SpanAttributes.HTTP_SCHEME: "https",
816-
SpanAttributes.HTTP_FLAVOR: "1.1",
817-
SpanAttributes.HTTP_SERVER_NAME: "testserver",
811+
HTTP_METHOD: "_OTHER",
812+
HTTP_HOST: "testserver:443",
813+
HTTP_SCHEME: "https",
814+
HTTP_FLAVOR: "1.1",
815+
HTTP_SERVER_NAME: "testserver",
818816
HTTP_REQUEST_METHOD: "_OTHER",
819817
URL_SCHEME: "https",
820818
}
@@ -1244,22 +1242,17 @@ def test_sub_app_fastapi_call(self):
12441242
spans_with_http_attributes = [
12451243
span
12461244
for span in spans
1247-
if (
1248-
SpanAttributes.HTTP_URL in span.attributes
1249-
or SpanAttributes.HTTP_TARGET in span.attributes
1250-
)
1245+
if (HTTP_URL in span.attributes or HTTP_TARGET in span.attributes)
12511246
]
12521247

12531248
# We now expect spans with attributes from both the app and its sub app
12541249
self.assertEqual(2, len(spans_with_http_attributes))
12551250

12561251
for span in spans_with_http_attributes:
1257-
self.assertEqual(
1258-
"/sub/home", span.attributes[SpanAttributes.HTTP_TARGET]
1259-
)
1252+
self.assertEqual("/sub/home", span.attributes[HTTP_TARGET])
12601253
self.assertEqual(
12611254
"https://testserver:443/sub/home",
1262-
span.attributes[SpanAttributes.HTTP_URL],
1255+
span.attributes[HTTP_URL],
12631256
)
12641257

12651258

@@ -1337,22 +1330,17 @@ def test_sub_app_fastapi_call(self):
13371330
spans_with_http_attributes = [
13381331
span
13391332
for span in spans
1340-
if (
1341-
SpanAttributes.HTTP_URL in span.attributes
1342-
or SpanAttributes.HTTP_TARGET in span.attributes
1343-
)
1333+
if (HTTP_URL in span.attributes or HTTP_TARGET in span.attributes)
13441334
]
13451335

13461336
# We now expect spans with attributes from both the app and its sub app
13471337
self.assertEqual(2, len(spans_with_http_attributes))
13481338

13491339
for span in spans_with_http_attributes:
1350-
self.assertEqual(
1351-
"/sub/home", span.attributes[SpanAttributes.HTTP_TARGET]
1352-
)
1340+
self.assertEqual("/sub/home", span.attributes[HTTP_TARGET])
13531341
self.assertEqual(
13541342
"https://testserver:443/sub/home",
1355-
span.attributes[SpanAttributes.HTTP_URL],
1343+
span.attributes[HTTP_URL],
13561344
)
13571345

13581346

0 commit comments

Comments
 (0)