diff --git a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/__init__.py b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/__init__.py index d88dffde2b..0528e9a576 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-mysql/src/opentelemetry/instrumentation/mysql/__init__.py @@ -34,6 +34,75 @@ cursor.close() cnx.close() +SQLCOMMENTER +***************************************** +You can optionally configure mysql-connector instrumentation to enable sqlcommenter which enriches +the query with contextual information. + +Usage +----- + +.. code:: python + + import mysql.connector + from opentelemetry.instrumentation.mysql import MySQLInstrumentor + + MySQLInstrumentor().instrument(enable_commenter=True, commenter_options={}) + + cnx = mysql.connector.connect(database="MySQL_Database") + cursor = cnx.cursor() + cursor.execute("INSERT INTO test (testField) VALUES (123)") + cursor.close() + cnx.close() + + +For example, +:: + + Invoking cursor.execute("INSERT INTO test (testField) VALUES (123)") will lead to sql query "INSERT INTO test (testField) VALUES (123)" but when SQLCommenter is enabled + the query will get appended with some configurable tags like "INSERT INTO test (testField) VALUES (123) /*tag=value*/;" + + +SQLCommenter Configurations +*************************** +We can configure the tags to be appended to the sqlquery log by adding configuration inside commenter_options(default:{}) keyword + +db_driver = True(Default) or False + +For example, +:: +Enabling this flag will add mysql.connector and its version, e.g. /*mysql.connector%%3A1.2.3*/ + +dbapi_threadsafety = True(Default) or False + +For example, +:: +Enabling this flag will add threadsafety /*dbapi_threadsafety=2*/ + +dbapi_level = True(Default) or False + +For example, +:: +Enabling this flag will add dbapi_level /*dbapi_level='2.0'*/ + +mysql_client_version = True(Default) or False + +For example, +:: +Enabling this flag will add mysql_client_version /*mysql_client_version='123'*/ + +driver_paramstyle = True(Default) or False + +For example, +:: +Enabling this flag will add driver_paramstyle /*driver_paramstyle='pyformat'*/ + +opentelemetry_values = True(Default) or False + +For example, +:: +Enabling this flag will add traceparent values /*traceparent='00-03afa25236b8cd948fa853d67038ac79-405ff022e8247c46-01'*/ + API --- """ @@ -66,6 +135,8 @@ def _instrument(self, **kwargs): https://dev.mysql.com/doc/connector-python/en/ """ tracer_provider = kwargs.get("tracer_provider") + enable_sqlcommenter = kwargs.get("enable_commenter", False) + commenter_options = kwargs.get("commenter_options", {}) dbapi.wrap_connect( __name__, @@ -75,6 +146,8 @@ def _instrument(self, **kwargs): self._CONNECTION_ATTRIBUTES, version=__version__, tracer_provider=tracer_provider, + enable_commenter=enable_sqlcommenter, + commenter_options=commenter_options, ) def _uninstrument(self, **kwargs): @@ -82,7 +155,13 @@ def _uninstrument(self, **kwargs): dbapi.unwrap_connect(mysql.connector, "connect") # pylint:disable=no-self-use - def instrument_connection(self, connection, tracer_provider=None): + def instrument_connection( + self, + connection, + tracer_provider=None, + enable_commenter=None, + commenter_options=None, + ): """Enable instrumentation in a MySQL connection. Args: @@ -100,6 +179,8 @@ def instrument_connection(self, connection, tracer_provider=None): self._CONNECTION_ATTRIBUTES, version=__version__, tracer_provider=tracer_provider, + enable_commenter=enable_commenter, + commenter_options=commenter_options, ) def uninstrument_connection(self, connection): diff --git a/instrumentation/opentelemetry-instrumentation-mysql/tests/test_mysql_integration.py b/instrumentation/opentelemetry-instrumentation-mysql/tests/test_mysql_integration.py index 3614febffd..04b4f9e3d6 100644 --- a/instrumentation/opentelemetry-instrumentation-mysql/tests/test_mysql_integration.py +++ b/instrumentation/opentelemetry-instrumentation-mysql/tests/test_mysql_integration.py @@ -102,6 +102,42 @@ def test_instrument_connection_no_op_tracer_provider(self, mock_connect): spans_list = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans_list), 0) + @mock.patch("opentelemetry.instrumentation.dbapi.instrument_connection") + @mock.patch("mysql.connector.connect") + # pylint: disable=unused-argument + def test_instrument_connection_enable_commenter( + self, + mock_connect, + mock_instrument_connection, + ): + cnx, query = connect_and_execute_query() + cnx = MySQLInstrumentor().instrument_connection( + cnx, + enable_commenter=True, + commenter_options={"foo": True}, + ) + cursor = cnx.cursor() + cursor.execute(query) + kwargs = mock_instrument_connection.call_args[1] + self.assertEqual(kwargs["enable_commenter"], True) + self.assertEqual(kwargs["commenter_options"], {"foo": True}) + + @mock.patch("opentelemetry.instrumentation.dbapi.wrap_connect") + @mock.patch("mysql.connector.connect") + # pylint: disable=unused-argument + def test__instrument_enable_commenter( + self, + mock_connect, + mock_wrap_connect, + ): + MySQLInstrumentor()._instrument( + enable_commenter=True, + commenter_options={"foo": True}, + ) + kwargs = mock_wrap_connect.call_args[1] + self.assertEqual(kwargs["enable_commenter"], True) + self.assertEqual(kwargs["commenter_options"], {"foo": True}) + @mock.patch("mysql.connector.connect") # pylint: disable=unused-argument def test_uninstrument_connection(self, mock_connect):