From 7c4a25a053ee26090adcfa83564955a8afefaa35 Mon Sep 17 00:00:00 2001 From: Mergepath Date: Sun, 2 Aug 2026 04:30:38 +0000 Subject: [PATCH] fix: address #4790 - `opentelemetry-instrumentation-mysqlclient`: expose `capture_parameters` Closes #4790 --- .../instrumentation/mysqlclient/__init__.py | 20 +++++++++++ .../tests/test_mysqlclient_integration.py | 33 +++++++++++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py index 98127ec3db..961fddc4e4 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/src/opentelemetry/instrumentation/mysqlclient/__init__.py @@ -119,6 +119,19 @@ Warning: Capture of sqlcomment in ``db.statement``/``db.query.text`` may have high cardinality without platform normalization. See `Semantic Conventions for database spans `_ for more information. +Capture parameters +****************** +By default, only statements are captured, without the associated query parameters. +To capture query parameters in span attributes, enable ``capture_parameters``. + +.. code:: python + + from opentelemetry.instrumentation.mysqlclient import MySQLClientInstrumentor + + MySQLClientInstrumentor().instrument( + capture_parameters=True, + ) + API --- """ @@ -155,6 +168,7 @@ def _instrument(self, **kwargs): # pylint: disable=no-self-use enable_attribute_commenter = kwargs.get( "enable_attribute_commenter", False ) + capture_parameters = kwargs.get("capture_parameters", False) dbapi.wrap_connect( __name__, @@ -167,6 +181,7 @@ def _instrument(self, **kwargs): # pylint: disable=no-self-use enable_commenter=enable_sqlcommenter, commenter_options=commenter_options, enable_attribute_commenter=enable_attribute_commenter, + capture_parameters=capture_parameters, ) def _uninstrument(self, **kwargs): # pylint: disable=no-self-use @@ -180,6 +195,7 @@ def instrument_connection( enable_commenter=None, commenter_options=None, enable_attribute_commenter=None, + capture_parameters=False, ): """Enable instrumentation in a mysqlclient connection. @@ -204,6 +220,9 @@ def instrument_connection( - `mysql_client_version`: Adds the MySQL client version. - `driver_paramstyle`: Adds the parameter style. - `opentelemetry_values`: Includes traceparent values. + capture_parameters: + A flag to enable capturing query parameters in span attributes. + Default is `False`. Returns: An instrumented MySQL connection with OpenTelemetry support enabled. """ @@ -219,6 +238,7 @@ def instrument_connection( commenter_options=commenter_options, connect_module=MySQLdb, enable_attribute_commenter=enable_attribute_commenter, + capture_parameters=capture_parameters, ) @staticmethod diff --git a/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py b/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py index a6dd9e7ebe..c85d12c5df 100644 --- a/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py +++ b/instrumentation/opentelemetry-instrumentation-mysqlclient/tests/test_mysqlclient_integration.py @@ -92,7 +92,7 @@ def test_instrument_connection(self, mock_connect): @mock.patch("opentelemetry.instrumentation.dbapi.instrument_connection") @mock.patch("MySQLdb.connect") # pylint: disable=unused-argument - def test_instrument_connection_enable_commenter_dbapi_kwargs( + def test_instrument_connection_dbapi_kwargs( self, mock_connect, mock_instrument_connection, @@ -103,6 +103,7 @@ def test_instrument_connection_enable_commenter_dbapi_kwargs( enable_commenter=True, commenter_options={"foo": True}, enable_attribute_commenter=True, + capture_parameters=True, ) cursor = cnx.cursor() cursor.execute("Select 1;") @@ -110,6 +111,20 @@ def test_instrument_connection_enable_commenter_dbapi_kwargs( self.assertEqual(kwargs["enable_commenter"], True) self.assertEqual(kwargs["commenter_options"], {"foo": True}) self.assertEqual(kwargs["enable_attribute_commenter"], True) + self.assertEqual(kwargs["capture_parameters"], True) + + @mock.patch("opentelemetry.instrumentation.dbapi.instrument_connection") + @mock.patch("MySQLdb.connect") + # pylint: disable=unused-argument + def test_instrument_connection_capture_parameters_default( + self, + mock_connect, + mock_instrument_connection, + ): + cnx = MySQLdb.connect(database="test") + MySQLClientInstrumentor().instrument_connection(cnx) + kwargs = mock_instrument_connection.call_args[1] + self.assertEqual(kwargs["capture_parameters"], False) def test_instrument_connection_with_dbapi_sqlcomment_enabled(self): mock_connect_module = mock.MagicMock( @@ -289,7 +304,7 @@ def test_instrument_connection_with_dbapi_sqlcomment_not_enabled_default( @mock.patch("opentelemetry.instrumentation.dbapi.wrap_connect") @mock.patch("MySQLdb.connect") # pylint: disable=unused-argument - def test_instrument_enable_commenter_dbapi_kwargs( + def test_instrument_dbapi_kwargs( self, mock_connect, mock_wrap_connect, @@ -298,11 +313,25 @@ def test_instrument_enable_commenter_dbapi_kwargs( enable_commenter=True, commenter_options={"foo": True}, enable_attribute_commenter=True, + capture_parameters=True, ) kwargs = mock_wrap_connect.call_args[1] self.assertEqual(kwargs["enable_commenter"], True) self.assertEqual(kwargs["commenter_options"], {"foo": True}) self.assertEqual(kwargs["enable_attribute_commenter"], True) + self.assertEqual(kwargs["capture_parameters"], True) + + @mock.patch("opentelemetry.instrumentation.dbapi.wrap_connect") + @mock.patch("MySQLdb.connect") + # pylint: disable=unused-argument + def test_instrument_capture_parameters_default( + self, + mock_connect, + mock_wrap_connect, + ): + MySQLClientInstrumentor()._instrument() + kwargs = mock_wrap_connect.call_args[1] + self.assertEqual(kwargs["capture_parameters"], False) def test_instrument_with_dbapi_sqlcomment_enabled( self,