Skip to content

Commit 2b7a005

Browse files
authored
uninstruemnt existing instances before uninstrumenting fastapi class (#1258)
1 parent 156203c commit 2b7a005

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2929
- ([#1246](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1246))
3030
- Add _is_openetlemetry_instrumented check in _InstrumentedFastAPI class
3131
([#1313](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1313))
32+
- Fix uninstrumentation of existing app instances in FastAPI
33+
([#1258](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1258))
3234

3335
## [1.12.0-0.33b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.12.0-0.33b0) - 2022-08-08
3436

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

+11
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ def instrument_app(
192192
meter=meter,
193193
)
194194
app._is_instrumented_by_opentelemetry = True
195+
if app not in _InstrumentedFastAPI._instrumented_fastapi_apps:
196+
_InstrumentedFastAPI._instrumented_fastapi_apps.add(app)
195197
else:
196198
_logger.warning(
197199
"Attempting to instrument FastAPI app while already instrumented"
@@ -232,6 +234,9 @@ def _instrument(self, **kwargs):
232234
fastapi.FastAPI = _InstrumentedFastAPI
233235

234236
def _uninstrument(self, **kwargs):
237+
for instance in _InstrumentedFastAPI._instrumented_fastapi_apps:
238+
self.uninstrument_app(instance)
239+
_InstrumentedFastAPI._instrumented_fastapi_apps.clear()
235240
fastapi.FastAPI = self._original_fastapi
236241

237242

@@ -242,6 +247,7 @@ class _InstrumentedFastAPI(fastapi.FastAPI):
242247
_server_request_hook: _ServerRequestHookT = None
243248
_client_request_hook: _ClientRequestHookT = None
244249
_client_response_hook: _ClientResponseHookT = None
250+
_instrumented_fastapi_apps = set()
245251

246252
def __init__(self, *args, **kwargs):
247253
super().__init__(*args, **kwargs)
@@ -259,6 +265,11 @@ def __init__(self, *args, **kwargs):
259265
meter=meter,
260266
)
261267
self._is_instrumented_by_opentelemetry = True
268+
_InstrumentedFastAPI._instrumented_fastapi_apps.add(self)
269+
270+
def __del__(self):
271+
if self in _InstrumentedFastAPI._instrumented_fastapi_apps:
272+
_InstrumentedFastAPI._instrumented_fastapi_apps.remove(self)
262273

263274

264275
def _get_route_details(scope):

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

+13-9
Original file line numberDiff line numberDiff line change
@@ -274,16 +274,11 @@ def test_metric_uninstruemnt_app(self):
274274
self.assertEqual(point.value, 0)
275275

276276
def test_metric_uninstrument(self):
277-
# instrumenting class and creating app to send request
278-
self._instrumentor.instrument()
279-
app = self._create_fastapi_app()
280-
client = TestClient(app)
281-
client.get("/foobar")
282-
# uninstrumenting class and creating the app again
277+
if not isinstance(self, TestAutoInstrumentation):
278+
self._instrumentor.instrument()
279+
self._client.get("/foobar")
283280
self._instrumentor.uninstrument()
284-
app = self._create_fastapi_app()
285-
client = TestClient(app)
286-
client.get("/foobar")
281+
self._client.get("/foobar")
287282

288283
metrics_list = self.memory_metrics_reader.get_metrics_data()
289284
for metric in (
@@ -416,6 +411,15 @@ def test_mulitple_way_instrumentation(self):
416411
count += 1
417412
self.assertEqual(count, 1)
418413

414+
def test_uninstrument_after_instrument(self):
415+
app = self._create_fastapi_app()
416+
client = TestClient(app)
417+
client.get("/foobar")
418+
self._instrumentor.uninstrument()
419+
client.get("/foobar")
420+
spans = self.memory_exporter.get_finished_spans()
421+
self.assertEqual(len(spans), 3)
422+
419423
def tearDown(self):
420424
self._instrumentor.uninstrument()
421425
super().tearDown()

0 commit comments

Comments
 (0)