diff --git a/CHANGELOG.md b/CHANGELOG.md index b63232109b..5a24a589ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,10 +16,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - `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)) - ## Version 1.37.0/0.58b0 (2025-09-11) ### 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 a2d63c20e3..8e5752aefa 100644 --- a/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-dbapi/src/opentelemetry/instrumentation/dbapi/__init__.py @@ -79,6 +79,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/ @@ -97,6 +98,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__, @@ -110,6 +112,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 9a7a4a7d12..223d07e2b7 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"