diff --git a/CHANGELOG.md b/CHANGELOG.md index cc71d38d2c..a94eaf935b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#1424](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1424)) - `opentelemetry-instrumentation-fastapi` Add support for regular expression matching and sanitization of HTTP headers. ([#1403](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1403)) +- `opentelemetry-instrumentation-dbapi` Strip leading comments from SQL queries when generating the span name. + ([#1434](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1434)) ### Fixed diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py index c2ee79e811..87b1a8d656 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py @@ -39,6 +39,7 @@ import functools import logging +import re import typing import wrapt @@ -368,6 +369,7 @@ def __init__(self, db_api_integration: DatabaseApiIntegration) -> None: else {} ) self._connect_module = self._db_api_integration.connect_module + self._leading_comment_remover = re.compile(r"^/\*.*?\*/") def _populate_span( self, @@ -397,7 +399,8 @@ def _populate_span( def get_operation_name(self, cursor, args): # pylint: disable=no-self-use if args and isinstance(args[0], str): - return args[0].split()[0] + # Strip leading comments so we get the operation name. + return self._leading_comment_remover.sub("", args[0]).split()[0] return "" def get_statement(self, cursor, args): # pylint: disable=no-self-use diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py index 8502bd46ee..9f9371ad66 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py @@ -88,11 +88,17 @@ def test_span_name(self): query""" ) cursor.execute("tab\tseparated query") + cursor.execute("/* leading comment */ query") + cursor.execute("/* leading comment */ query /* trailing comment */") + cursor.execute("query /* trailing comment */") spans_list = self.memory_exporter.get_finished_spans() - self.assertEqual(len(spans_list), 3) + self.assertEqual(len(spans_list), 6) self.assertEqual(spans_list[0].name, "Test") self.assertEqual(spans_list[1].name, "multi") self.assertEqual(spans_list[2].name, "tab") + self.assertEqual(spans_list[3].name, "query") + self.assertEqual(spans_list[4].name, "query") + self.assertEqual(spans_list[5].name, "query") def test_span_succeeded_with_capture_of_statement_parameters(self): connection_props = { diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py index ebad55cf2a..de2e49f4c3 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py @@ -216,7 +216,8 @@ def get_operation_name(self, cursor, args): statement = statement.as_string(cursor) if isinstance(statement, str): - return statement.split()[0] + # Strip leading comments so we get the operation name. + return self._leading_comment_remover.sub("", statement).split()[0] return "" diff --git a/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py b/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py index f516a07882..5eff8b444f 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg2/tests/test_psycopg2_integration.py @@ -116,6 +116,32 @@ def test_instrumentor(self): spans_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans_list), 1) + def test_span_name(self): + Psycopg2Instrumentor().instrument() + + cnx = psycopg2.connect(database="test") + + cursor = cnx.cursor() + + cursor.execute("Test query", ("param1Value", False)) + cursor.execute( + """multi + line + query""" + ) + cursor.execute("tab\tseparated query") + cursor.execute("/* leading comment */ query") + cursor.execute("/* leading comment */ query /* trailing comment */") + cursor.execute("query /* trailing comment */") + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 6) + self.assertEqual(spans_list[0].name, "Test") + self.assertEqual(spans_list[1].name, "multi") + self.assertEqual(spans_list[2].name, "tab") + self.assertEqual(spans_list[3].name, "query") + self.assertEqual(spans_list[4].name, "query") + self.assertEqual(spans_list[5].name, "query") + # pylint: disable=unused-argument def test_not_recording(self): mock_tracer = mock.Mock()