Skip to content

Commit de9c77c

Browse files
committed
Merge remote-tracking branch 'upstream/main' into fix/GH-3642-fastapi-exceptions
2 parents 5946f92 + 032d6c6 commit de9c77c

File tree

42 files changed

+4324
-2466
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+4324
-2466
lines changed

.github/component_owners.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,11 @@ components:
3333
- dorkolog
3434

3535
propagator/opentelemetry-propagator-aws-xray:
36-
- NathanielRN
36+
- jj22ee
3737

3838
sdk-extension/opentelemetry-sdk-extension-aws:
39-
- NathanielRN
40-
- Kausik-A
4139
- srprash
40+
- jj22ee
4241

4342
instrumentation/opentelemetry-instrumentation-tortoiseorm:
4443
- tonybaloney

CHANGELOG.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
([#3664](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3664))
1818
- `opentelemetry-instrumentation-asgi`: Make all user hooks failsafe and record exceptions in hooks.
1919
([#3664](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3664))
20+
- `opentelemetry-instrumentation-fastapi`: Fix memory leak in `uninstrument_app()` by properly removing apps from the tracking set
21+
([#3688](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3688)
22+
- `opentelemetry-instrumentation-tornado` Fix server (request) duration metric calculation
23+
([#3679](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3679))
2024
- `opentelemetry-instrumentation`: Avoid calls to `context.detach` with `None` token.
2125
([#3673](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3673))
2226

27+
### Added
28+
29+
- `opentelemetry-instrumentation-confluent-kafka` Add support for confluent-kafka <=2.11.0
30+
([#3685](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3685))
31+
- `opentelemetry-instrumentation-system-metrics`: Add `cpython.gc.collected_objects` and `cpython.gc.uncollectable_objects` metrics
32+
([#3666](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3666))
33+
- `opentelemetry-sdk-extension-aws` Add AWS X-Ray Remote Sampler with initial Rules Poller implementation
34+
([#3366](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3366))
35+
2336
## Version 1.36.0/0.57b0 (2025-07-29)
2437

2538
### Fixed
@@ -120,7 +133,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
120133
### Deprecated
121134

122135
- Drop support for Python 3.8, bump baseline to Python 3.9.
123-
([#3399](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3399))
136+
([#3399](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3399))
124137

125138
## Version 1.33.0/0.54b0 (2025-05-09)
126139

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,12 @@ Meeting notes are available as a public [Google doc](https://docs.google.com/doc
116116
- [Aaron Abbott](https://github.com/aabmass), Google
117117
- [Leighton Chen](https://github.com/lzchen), Microsoft
118118
- [Riccardo Magliocchetti](https://github.com/xrmx), Elastic
119-
- [Shalev Roda](https://github.com/shalevr), Cisco
120119

121120
For more information about the maintainer role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#maintainer).
122121

123122
### Approvers
124123

124+
- [Dylan Russell](https://github.com/dylanrussell), Google
125125
- [Emídio Neto](https://github.com/emdneto), PicPay
126126
- [Jeremy Voss](https://github.com/jeremydvoss), Microsoft
127127
- [Owais Lone](https://github.com/owais), Splunk
@@ -137,6 +137,7 @@ For more information about the approver role, see the [community repository](htt
137137
- [Alex Boten](https://github.com/codeboten)
138138
- [Diego Hurtado](https://github.com/ocelotl)
139139
- [Owais Lone](https://github.com/owais)
140+
- [Shalev Roda](https://github.com/shalevr)
140141
- [Yusuke Tsutsumi](https://github.com/toumorokoshi)
141142

142143
For more information about the emeritus role, see the [community repository](https://github.com/open-telemetry/community/blob/main/guides/contributor/membership.md#emeritus-maintainerapprovertriager).

docs-requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ botocore~=1.0
2121
boto3~=1.0
2222
cassandra-driver~=3.25
2323
celery>=4.0
24-
confluent-kafka>= 1.8.2,<= 2.4.0
24+
confluent-kafka>= 1.8.2,<= 2.11.0
2525
elasticsearch>=6.0,<9.0
2626
flask~=2.0
2727
falcon~=2.0

instrumentation/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
| [opentelemetry-instrumentation-cassandra](./opentelemetry-instrumentation-cassandra) | cassandra-driver ~= 3.25,scylla-driver ~= 3.25 | No | development
1818
| [opentelemetry-instrumentation-celery](./opentelemetry-instrumentation-celery) | celery >= 4.0, < 6.0 | No | development
1919
| [opentelemetry-instrumentation-click](./opentelemetry-instrumentation-click) | click >= 8.1.3, < 9.0.0 | No | development
20-
| [opentelemetry-instrumentation-confluent-kafka](./opentelemetry-instrumentation-confluent-kafka) | confluent-kafka >= 1.8.2, <= 2.7.0 | No | development
20+
| [opentelemetry-instrumentation-confluent-kafka](./opentelemetry-instrumentation-confluent-kafka) | confluent-kafka >= 1.8.2, <= 2.11.0 | No | development
2121
| [opentelemetry-instrumentation-dbapi](./opentelemetry-instrumentation-dbapi) | dbapi | No | development
2222
| [opentelemetry-instrumentation-django](./opentelemetry-instrumentation-django) | django >= 1.10 | Yes | development
2323
| [opentelemetry-instrumentation-elasticsearch](./opentelemetry-instrumentation-elasticsearch) | elasticsearch >= 6.0 | No | development

instrumentation/opentelemetry-instrumentation-confluent-kafka/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ dependencies = [
3232

3333
[project.optional-dependencies]
3434
instruments = [
35-
"confluent-kafka >= 1.8.2, <= 2.7.0",
35+
"confluent-kafka >= 1.8.2, <= 2.11.0",
3636
]
3737

3838
[project.entry-points.opentelemetry_instrumentor]

instrumentation/opentelemetry-instrumentation-confluent-kafka/src/opentelemetry/instrumentation/confluent_kafka/package.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
# limitations under the License.
1414

1515

16-
_instruments = ("confluent-kafka >= 1.8.2, <= 2.7.0",)
16+
_instruments = ("confluent-kafka >= 1.8.2, <= 2.11.0",)

instrumentation/opentelemetry-instrumentation-confluent-kafka/test-requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
asgiref==3.8.1
2-
confluent-kafka==2.6.1
2+
confluent-kafka==2.11.0
33
Deprecated==1.2.14
44
iniconfig==2.0.0
55
packaging==24.0

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ def client_response_hook(span: Span, scope: dict[str, Any], message: dict[str, A
186186
import logging
187187
import types
188188
from typing import Collection, Literal
189+
from weakref import WeakSet as _WeakSet
189190

190191
import fastapi
191192
from starlette.applications import Starlette
@@ -415,6 +416,11 @@ def uninstrument_app(app: fastapi.FastAPI):
415416
app.middleware_stack = app.build_middleware_stack()
416417
app._is_instrumented_by_opentelemetry = False
417418

419+
# Remove the app from the set of instrumented apps to avoid calling uninstrument twice
420+
# if the instrumentation is later disabled or such
421+
# Use discard to avoid KeyError if already GC'ed
422+
_InstrumentedFastAPI._instrumented_fastapi_apps.discard(app)
423+
418424
def instrumentation_dependencies(self) -> Collection[str]:
419425
return _instruments
420426

@@ -445,7 +451,11 @@ def _instrument(self, **kwargs):
445451
fastapi.FastAPI = _InstrumentedFastAPI
446452

447453
def _uninstrument(self, **kwargs):
448-
for instance in _InstrumentedFastAPI._instrumented_fastapi_apps:
454+
# Create a copy of the set to avoid RuntimeError during iteration
455+
instances_to_uninstrument = list(
456+
_InstrumentedFastAPI._instrumented_fastapi_apps
457+
)
458+
for instance in instances_to_uninstrument:
449459
self.uninstrument_app(instance)
450460
_InstrumentedFastAPI._instrumented_fastapi_apps.clear()
451461
fastapi.FastAPI = self._original_fastapi
@@ -463,7 +473,8 @@ class _InstrumentedFastAPI(fastapi.FastAPI):
463473
_http_capture_headers_sanitize_fields: list[str] | None = None
464474
_exclude_spans: list[Literal["receive", "send"]] | None = None
465475

466-
_instrumented_fastapi_apps = set()
476+
# Track instrumented app instances using weak references to avoid GC leaks
477+
_instrumented_fastapi_apps = _WeakSet()
467478
_sem_conv_opt_in_mode = _StabilityMode.DEFAULT
468479

469480
def __init__(self, *args, **kwargs):
@@ -483,10 +494,6 @@ def __init__(self, *args, **kwargs):
483494
)
484495
_InstrumentedFastAPI._instrumented_fastapi_apps.add(self)
485496

486-
def __del__(self):
487-
if self in _InstrumentedFastAPI._instrumented_fastapi_apps:
488-
_InstrumentedFastAPI._instrumented_fastapi_apps.remove(self)
489-
490497

491498
def _get_route_details(scope):
492499
"""

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414

1515
# pylint: disable=too-many-lines
1616

17+
import gc as _gc
1718
import logging
1819
import unittest
20+
import weakref as _weakref
1921
from contextlib import ExitStack
2022
from timeit import default_timer
2123
from unittest.mock import Mock, call, patch
@@ -1404,6 +1406,16 @@ def test_mark_span_internal_in_presence_of_span_from_other_framework(self):
14041406
)
14051407

14061408

1409+
class TestFastAPIGarbageCollection(unittest.TestCase):
1410+
def test_fastapi_app_is_collected_after_instrument(self):
1411+
app = fastapi.FastAPI()
1412+
otel_fastapi.FastAPIInstrumentor().instrument_app(app)
1413+
app_ref = _weakref.ref(app)
1414+
del app
1415+
_gc.collect()
1416+
self.assertIsNone(app_ref())
1417+
1418+
14071419
@patch.dict(
14081420
"os.environ",
14091421
{

0 commit comments

Comments
 (0)