diff --git a/CHANGELOG.md b/CHANGELOG.md index e8fd5fdca2..9061fdeb1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `opentelemetry-instrumentation-botocore`: Add support for AWS Secrets Manager semantic convention attribute ([#3765](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3765)) +- `opentelemetry-instrumentation-dbapi`: Add support for `commenter_options` in `trace_integration` function to control SQLCommenter behavior + ([#3743](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3743)) - Add `rstcheck` to pre-commit to stop introducing invalid RST ([#3777](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3777)) - `opentelemetry-exporter-credential-provider-gcp`: create this package which provides support for supplying your machine's Application Default 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 03ef92ec57..ec088e1aa5 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py @@ -208,6 +208,7 @@ def trace_integration( enable_commenter: bool = False, db_api_integration_factory: type[DatabaseApiIntegration] | None = None, enable_attribute_commenter: bool = False, + commenter_options: dict[str, Any] | None = None, ): """Integrate with DB API library. https://www.python.org/dev/peps/pep-0249/ @@ -226,6 +227,7 @@ def trace_integration( db_api_integration_factory: The `DatabaseApiIntegration` to use. If none is passed the default one is used. enable_attribute_commenter: Flag to enable/disable sqlcomment inclusion in `db.statement` span attribute. Only available if enable_commenter=True. + commenter_options: Configurations for tags to be appended at the sql query. """ wrap_connect( __name__, @@ -239,6 +241,7 @@ def trace_integration( enable_commenter=enable_commenter, db_api_integration_factory=db_api_integration_factory, enable_attribute_commenter=enable_attribute_commenter, + commenter_options=commenter_options, ) diff --git a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py index b1a871a605..7d3396353a 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/tests/test_dbapi_integration.py @@ -259,6 +259,45 @@ def test_suppress_instrumentation(self): spans_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans_list), 0) + def test_commenter_options_propagation(self): + db_integration = dbapi.DatabaseApiIntegration( + "instrumenting_module_test_name", + "testcomponent", + commenter_options={"opentelemetry_values": False}, + ) + mock_connection = db_integration.wrapped_connection( + mock_connect, {}, {} + ) + cursor = mock_connection.cursor() + with self.assertRaises(Exception): + cursor.execute("SELECT 1", throw_exception=True) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + span = spans_list[0] + self.assertEqual(span.attributes.get("db.system"), "testcomponent") + self.assertIn("opentelemetry_values", db_integration.commenter_options) + self.assertFalse( + db_integration.commenter_options["opentelemetry_values"] + ) + + @mock.patch("opentelemetry.instrumentation.dbapi.wrap_connect") + def test_trace_integration_passes_commenter_options( + self, mock_wrap_connect + ): + fake_connect_module = mock.Mock() + fake_options = {"opentelemetry_values": False, "foo": "bar"} + dbapi.trace_integration( + connect_module=fake_connect_module, + connect_method_name="connect", + database_system="testdb", + commenter_options=fake_options, + ) + mock_wrap_connect.assert_called_once() + _, _, kwargs = mock_wrap_connect.mock_calls[0] + + self.assertIn("commenter_options", kwargs) + self.assertEqual(kwargs["commenter_options"], fake_options) + def test_executemany(self): db_integration = dbapi.DatabaseApiIntegration( "instrumenting_module_test_name", "testcomponent"