Skip to content

Commit 571c378

Browse files
authoredJan 26, 2022
(instrumentation-sqlite3): trace connections made with dbapi2.connect (#873)
* Change wrap_connect method * Wrap both connect defs * Add tests * Add CHANGELOG entry
1 parent ec5b73c commit 571c378

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed
 

‎CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3434

3535
- `opentelemetry-instrumentation-django` Django: fix issue preventing detection of MIDDLEWARE_CLASSES
3636

37+
- `opentelemetry-instrumentation-sqlite3` Instrumentation now works with `dbapi2.connect`
38+
3739
## [1.8.0-0.27b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.8.0-0.27b0) - 2021-12-17
3840

3941
### Added

‎instrumentation/opentelemetry-instrumentation-sqlite3/src/opentelemetry/instrumentation/sqlite3/__init__.py

+15-10
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"""
4141

4242
import sqlite3
43+
from sqlite3 import dbapi2
4344
from typing import Collection
4445

4546
from opentelemetry.instrumentation import dbapi
@@ -54,6 +55,8 @@
5455

5556

5657
class SQLite3Instrumentor(BaseInstrumentor):
58+
_TO_WRAP = [sqlite3, dbapi2]
59+
5760
def instrumentation_dependencies(self) -> Collection[str]:
5861
return _instruments
5962

@@ -63,19 +66,21 @@ def _instrument(self, **kwargs):
6366
"""
6467
tracer_provider = kwargs.get("tracer_provider")
6568

66-
dbapi.wrap_connect(
67-
__name__,
68-
sqlite3,
69-
"connect",
70-
_DATABASE_SYSTEM,
71-
_CONNECTION_ATTRIBUTES,
72-
version=__version__,
73-
tracer_provider=tracer_provider,
74-
)
69+
for module in self._TO_WRAP:
70+
dbapi.wrap_connect(
71+
__name__,
72+
module,
73+
"connect",
74+
_DATABASE_SYSTEM,
75+
_CONNECTION_ATTRIBUTES,
76+
version=__version__,
77+
tracer_provider=tracer_provider,
78+
)
7579

7680
def _uninstrument(self, **kwargs):
7781
""" "Disable SQLite3 instrumentation"""
78-
dbapi.unwrap_connect(sqlite3, "connect")
82+
for module in self._TO_WRAP:
83+
dbapi.unwrap_connect(module, "connect")
7984

8085
@staticmethod
8186
def instrument_connection(connection, tracer_provider=None):

‎instrumentation/opentelemetry-instrumentation-sqlite3/tests/test_sqlite3.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import sqlite3
16+
from sqlite3 import dbapi2
1617

1718
from opentelemetry import trace as trace_api
1819
from opentelemetry.instrumentation.sqlite3 import SQLite3Instrumentor
@@ -25,20 +26,29 @@ def setUpClass(cls):
2526
super().setUpClass()
2627
cls._connection = None
2728
cls._cursor = None
29+
cls._connection2 = None
30+
cls._cursor2 = None
2831
cls._tracer = cls.tracer_provider.get_tracer(__name__)
2932
SQLite3Instrumentor().instrument(tracer_provider=cls.tracer_provider)
3033
cls._connection = sqlite3.connect(":memory:")
3134
cls._cursor = cls._connection.cursor()
35+
cls._connection2 = dbapi2.connect(":memory:")
36+
cls._cursor2 = cls._connection2.cursor()
3237

3338
@classmethod
3439
def tearDownClass(cls):
3540
if cls._cursor:
3641
cls._cursor.close()
3742
if cls._connection:
3843
cls._connection.close()
44+
if cls._cursor2:
45+
cls._cursor2.close()
46+
if cls._connection2:
47+
cls._connection2.close()
3948

4049
def validate_spans(self, span_name):
4150
spans = self.memory_exporter.get_finished_spans()
51+
self.memory_exporter.clear()
4252
self.assertEqual(len(spans), 2)
4353
for span in spans:
4454
if span.name == "rootSpan":
@@ -62,14 +72,22 @@ def test_execute(self):
6272
self._cursor.execute(stmt)
6373
self.validate_spans("CREATE")
6474

75+
with self._tracer.start_as_current_span("rootSpan"):
76+
self._cursor2.execute(stmt)
77+
self.validate_spans("CREATE")
78+
6579
def test_executemany(self):
6680
"""Should create a child span for executemany"""
6781
stmt = "INSERT INTO test (id) VALUES (?)"
82+
data = [("1",), ("2",), ("3",)]
6883
with self._tracer.start_as_current_span("rootSpan"):
69-
data = [("1",), ("2",), ("3",)]
7084
self._cursor.executemany(stmt, data)
7185
self.validate_spans("INSERT")
7286

87+
with self._tracer.start_as_current_span("rootSpan"):
88+
self._cursor2.executemany(stmt, data)
89+
self.validate_spans("INSERT")
90+
7391
def test_callproc(self):
7492
"""Should create a child span for callproc"""
7593
with self._tracer.start_as_current_span("rootSpan"), self.assertRaises(

0 commit comments

Comments
 (0)
Please sign in to comment.