Skip to content

Commit 5b84128

Browse files
authored
Do not use asgi name and version for tracer/meter for instrumentations using Asgi Middleware (#2580)
1 parent bb9eebb commit 5b84128

File tree

8 files changed

+77
-9
lines changed

8 files changed

+77
-9
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
### Breaking changes
11+
12+
- `opentelemetry-instrumentation-asgi`, `opentelemetry-instrumentation-fastapi`, `opentelemetry-instrumentation-starlette` Use `tracer` and `meter` of originating components instead of one from `asgi` middleware
13+
([#2580](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2580))
14+
1015
### Fixed
1116

1217
- `opentelemetry-instrumentation-httpx` Ensure httpx.get or httpx.request like methods are instrumented

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

+12-5
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,8 @@ class OpenTelemetryMiddleware:
461461
scope and event which are sent as dictionaries for when the method send is called.
462462
tracer_provider: The optional tracer provider to use. If omitted
463463
the current globally configured one is used.
464+
meter_provider: The optional meter provider to use. If omitted
465+
the current globally configured one is used.
464466
"""
465467

466468
# pylint: disable=too-many-branches
@@ -474,17 +476,22 @@ def __init__(
474476
client_response_hook: ClientResponseHook = None,
475477
tracer_provider=None,
476478
meter_provider=None,
479+
tracer=None,
477480
meter=None,
478481
http_capture_headers_server_request: list[str] | None = None,
479482
http_capture_headers_server_response: list[str] | None = None,
480483
http_capture_headers_sanitize_fields: list[str] | None = None,
481484
):
482485
self.app = guarantee_single_callable(app)
483-
self.tracer = trace.get_tracer(
484-
__name__,
485-
__version__,
486-
tracer_provider,
487-
schema_url="https://opentelemetry.io/schemas/1.11.0",
486+
self.tracer = (
487+
trace.get_tracer(
488+
__name__,
489+
__version__,
490+
tracer_provider,
491+
schema_url="https://opentelemetry.io/schemas/1.11.0",
492+
)
493+
if tracer is None
494+
else tracer
488495
)
489496
self.meter = (
490497
get_meter(

instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py

+8
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,10 @@ def validate_outputs(self, outputs, error=None, modifiers=None):
309309
self.assertEqual(span.name, expected["name"])
310310
self.assertEqual(span.kind, expected["kind"])
311311
self.assertDictEqual(dict(span.attributes), expected["attributes"])
312+
self.assertEqual(
313+
span.instrumentation_scope.name,
314+
"opentelemetry.instrumentation.asgi",
315+
)
312316

313317
def test_basic_asgi_call(self):
314318
"""Test that spans are emitted as expected."""
@@ -728,6 +732,10 @@ def test_asgi_metrics(self):
728732
self.assertTrue(len(resource_metric.scope_metrics) != 0)
729733
for scope_metric in resource_metric.scope_metrics:
730734
self.assertTrue(len(scope_metric.metrics) != 0)
735+
self.assertEqual(
736+
scope_metric.scope.name,
737+
"opentelemetry.instrumentation.asgi",
738+
)
731739
for metric in scope_metric.metrics:
732740
self.assertIn(metric.name, _expected_metric_names)
733741
data_points = list(metric.data.data_points)

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

+17-2
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A
188188
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
189189
from opentelemetry.metrics import get_meter
190190
from opentelemetry.semconv.trace import SpanAttributes
191+
from opentelemetry.trace import get_tracer
191192
from opentelemetry.util.http import get_excluded_urls, parse_excluded_urls
192193

193194
_excluded_urls_from_env = get_excluded_urls("FASTAPI")
@@ -221,6 +222,12 @@ def instrument_app(
221222
excluded_urls = _excluded_urls_from_env
222223
else:
223224
excluded_urls = parse_excluded_urls(excluded_urls)
225+
tracer = get_tracer(
226+
__name__,
227+
__version__,
228+
tracer_provider,
229+
schema_url="https://opentelemetry.io/schemas/1.11.0",
230+
)
224231
meter = get_meter(
225232
__name__,
226233
__version__,
@@ -235,7 +242,8 @@ def instrument_app(
235242
server_request_hook=server_request_hook,
236243
client_request_hook=client_request_hook,
237244
client_response_hook=client_response_hook,
238-
tracer_provider=tracer_provider,
245+
# Pass in tracer/meter to get __name__and __version__ of fastapi instrumentation
246+
tracer=tracer,
239247
meter=meter,
240248
)
241249
app._is_instrumented_by_opentelemetry = True
@@ -298,6 +306,12 @@ class _InstrumentedFastAPI(fastapi.FastAPI):
298306

299307
def __init__(self, *args, **kwargs):
300308
super().__init__(*args, **kwargs)
309+
tracer = get_tracer(
310+
__name__,
311+
__version__,
312+
_InstrumentedFastAPI._tracer_provider,
313+
schema_url="https://opentelemetry.io/schemas/1.11.0",
314+
)
301315
meter = get_meter(
302316
__name__,
303317
__version__,
@@ -311,7 +325,8 @@ def __init__(self, *args, **kwargs):
311325
server_request_hook=_InstrumentedFastAPI._server_request_hook,
312326
client_request_hook=_InstrumentedFastAPI._client_request_hook,
313327
client_response_hook=_InstrumentedFastAPI._client_response_hook,
314-
tracer_provider=_InstrumentedFastAPI._tracer_provider,
328+
# Pass in tracer/meter to get __name__and __version__ of fastapi instrumentation
329+
tracer=tracer,
315330
meter=meter,
316331
)
317332
self._is_instrumented_by_opentelemetry = True

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

+8
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ def test_instrument_app_with_instrument(self):
117117
self.assertEqual(len(spans), 3)
118118
for span in spans:
119119
self.assertIn("GET /foobar", span.name)
120+
self.assertEqual(
121+
span.instrumentation_scope.name,
122+
"opentelemetry.instrumentation.fastapi",
123+
)
120124

121125
def test_uninstrument_app(self):
122126
self._client.get("/foobar")
@@ -197,6 +201,10 @@ def test_fastapi_metrics(self):
197201
for resource_metric in metrics_list.resource_metrics:
198202
self.assertTrue(len(resource_metric.scope_metrics) == 1)
199203
for scope_metric in resource_metric.scope_metrics:
204+
self.assertEqual(
205+
scope_metric.scope.name,
206+
"opentelemetry.instrumentation.fastapi",
207+
)
200208
self.assertTrue(len(scope_metric.metrics) == 3)
201209
for metric in scope_metric.metrics:
202210
self.assertIn(metric.name, _expected_metric_names)

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

+17-2
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A
185185
from opentelemetry.instrumentation.starlette.version import __version__
186186
from opentelemetry.metrics import get_meter
187187
from opentelemetry.semconv.trace import SpanAttributes
188+
from opentelemetry.trace import get_tracer
188189
from opentelemetry.util.http import get_excluded_urls
189190

190191
_excluded_urls = get_excluded_urls("STARLETTE")
@@ -208,6 +209,12 @@ def instrument_app(
208209
tracer_provider=None,
209210
):
210211
"""Instrument an uninstrumented Starlette application."""
212+
tracer = get_tracer(
213+
__name__,
214+
__version__,
215+
tracer_provider,
216+
schema_url="https://opentelemetry.io/schemas/1.11.0",
217+
)
211218
meter = get_meter(
212219
__name__,
213220
__version__,
@@ -222,7 +229,8 @@ def instrument_app(
222229
server_request_hook=server_request_hook,
223230
client_request_hook=client_request_hook,
224231
client_response_hook=client_response_hook,
225-
tracer_provider=tracer_provider,
232+
# Pass in tracer/meter to get __name__and __version__ of starlette instrumentation
233+
tracer=tracer,
226234
meter=meter,
227235
)
228236
app.is_instrumented_by_opentelemetry = True
@@ -278,6 +286,12 @@ class _InstrumentedStarlette(applications.Starlette):
278286

279287
def __init__(self, *args, **kwargs):
280288
super().__init__(*args, **kwargs)
289+
tracer = get_tracer(
290+
__name__,
291+
__version__,
292+
_InstrumentedStarlette._tracer_provider,
293+
schema_url="https://opentelemetry.io/schemas/1.11.0",
294+
)
281295
meter = get_meter(
282296
__name__,
283297
__version__,
@@ -291,7 +305,8 @@ def __init__(self, *args, **kwargs):
291305
server_request_hook=_InstrumentedStarlette._server_request_hook,
292306
client_request_hook=_InstrumentedStarlette._client_request_hook,
293307
client_response_hook=_InstrumentedStarlette._client_response_hook,
294-
tracer_provider=_InstrumentedStarlette._tracer_provider,
308+
# Pass in tracer/meter to get __name__and __version__ of starlette instrumentation
309+
tracer=tracer,
295310
meter=meter,
296311
)
297312
self._is_instrumented_by_opentelemetry = True

instrumentation/opentelemetry-instrumentation-starlette/tests/test_starlette_instrumentation.py

+8
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ def test_basic_starlette_call(self):
9898
self.assertEqual(len(spans), 3)
9999
for span in spans:
100100
self.assertIn("GET /foobar", span.name)
101+
self.assertEqual(
102+
span.instrumentation_scope.name,
103+
"opentelemetry.instrumentation.starlette",
104+
)
101105

102106
def test_starlette_route_attribute_added(self):
103107
"""Ensure that starlette routes are used as the span name."""
@@ -132,6 +136,10 @@ def test_starlette_metrics(self):
132136
for resource_metric in metrics_list.resource_metrics:
133137
self.assertTrue(len(resource_metric.scope_metrics) == 1)
134138
for scope_metric in resource_metric.scope_metrics:
139+
self.assertEqual(
140+
scope_metric.scope.name,
141+
"opentelemetry.instrumentation.starlette",
142+
)
135143
self.assertTrue(len(scope_metric.metrics) == 3)
136144
for metric in scope_metric.metrics:
137145
self.assertIn(metric.name, _expected_metric_names)

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

+2
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,8 @@ class OpenTelemetryMiddleware:
533533
incoming request.
534534
tracer_provider: Optional tracer provider to use. If omitted the current
535535
globally configured one is used.
536+
meter_provider: Optional meter provider to use. If omitted the current
537+
globally configured one is used.
536538
"""
537539

538540
def __init__(

0 commit comments

Comments
 (0)