Skip to content

Commit ec7fde4

Browse files
rbagdemdnetoxrmx
committed
Remove references to disposed SQLAlchemy engines from instrumentation singleton (open-telemetry#3053)
* Remove references to SQLAlchemy engines which are disposed of EngineTracer in SQLAlchemy keeps weak references to a traced engine forever which can cause a noticeable memory leak if engines are constantly getting creating. * Updated changelog --------- Co-authored-by: Emídio Neto <[email protected]> Co-authored-by: Riccardo Magliocchetti <[email protected]>
1 parent 510f596 commit ec7fde4

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4646
([#3022](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3022))
4747
- Replace all instrumentor unit test `assertEqualSpanInstrumentationInfo` calls with `assertEqualSpanInstrumentationScope` calls
4848
([#3037](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3037))
49+
- `opentelemetry-instrumentation-sqlalchemy`: Fix a remaining memory leak in EngineTracer
50+
([#3053](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3053))
4951

5052
### Breaking changes
5153

instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py

+13
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,26 @@ def _pool_checkout(
167167
self._add_idle_to_connection_usage(-1)
168168
self._add_used_to_connection_usage(1)
169169

170+
@classmethod
171+
def _dispose_of_event_listener(cls, obj):
172+
try:
173+
cls._remove_event_listener_params.remove(obj)
174+
except ValueError:
175+
pass
176+
170177
@classmethod
171178
def _register_event_listener(cls, target, identifier, func, *args, **kw):
172179
listen(target, identifier, func, *args, **kw)
173180
cls._remove_event_listener_params.append(
174181
(weakref.ref(target), identifier, func)
175182
)
176183

184+
weakref.finalize(
185+
target,
186+
cls._dispose_of_event_listener,
187+
(weakref.ref(target), identifier, func),
188+
)
189+
177190
@classmethod
178191
def remove_all_event_listeners(cls):
179192
for (

instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy.py

+5
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,10 @@ def test_no_memory_leakage_if_engine_diposed(self):
417417

418418
from sqlalchemy import create_engine
419419

420+
from opentelemetry.instrumentation.sqlalchemy.engine import (
421+
EngineTracer,
422+
)
423+
420424
callback = mock.Mock()
421425

422426
def make_shortlived_engine():
@@ -432,3 +436,4 @@ def make_shortlived_engine():
432436

433437
gc.collect()
434438
assert callback.call_count == 5
439+
assert len(EngineTracer._remove_event_listener_params) == 0

0 commit comments

Comments
 (0)