From b6d0942cf28ad43e05912e296b3a3d5cdc7e696d Mon Sep 17 00:00:00 2001 From: StefanoOvus <19593841+StefanoOvus@users.noreply.github.com> Date: Tue, 5 Aug 2025 12:03:58 +0200 Subject: [PATCH 1/3] missing capture_parameters in instrumentation psycopg --- .../src/opentelemetry/instrumentation/psycopg/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py index ede035e079..680f31bf4c 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/src/opentelemetry/instrumentation/psycopg/__init__.py @@ -183,6 +183,7 @@ def _instrument(self, **kwargs: Any): enable_attribute_commenter = kwargs.get( "enable_attribute_commenter", False ) + capture_parameters = kwargs.get("capture_parameters", False) dbapi.wrap_connect( __name__, psycopg, @@ -195,6 +196,7 @@ def _instrument(self, **kwargs: Any): enable_commenter=enable_sqlcommenter, commenter_options=commenter_options, enable_attribute_commenter=enable_attribute_commenter, + capture_parameters=capture_parameters, ) dbapi.wrap_connect( @@ -209,6 +211,7 @@ def _instrument(self, **kwargs: Any): enable_commenter=enable_sqlcommenter, commenter_options=commenter_options, enable_attribute_commenter=enable_attribute_commenter, + capture_parameters=capture_parameters, ) dbapi.wrap_connect( __name__, @@ -222,6 +225,7 @@ def _instrument(self, **kwargs: Any): enable_commenter=enable_sqlcommenter, commenter_options=commenter_options, enable_attribute_commenter=enable_attribute_commenter, + capture_parameters=capture_parameters, ) def _uninstrument(self, **kwargs: Any): From 6eabb2925828ccd0ef7f24c31917c4b2a2e01929 Mon Sep 17 00:00:00 2001 From: StefanoOvus <19593841+StefanoOvus@users.noreply.github.com> Date: Tue, 5 Aug 2025 14:37:25 +0200 Subject: [PATCH 2/3] added tests for psycopg capture params --- .../tests/test_psycopg_integration.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py b/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py index 0987d3e932..b6facb92c3 100644 --- a/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py +++ b/instrumentation/opentelemetry-instrumentation-psycopg/tests/test_psycopg_integration.py @@ -264,6 +264,25 @@ def test_span_name(self): self.assertEqual(spans_list[6].name, "postgresql") self.assertEqual(spans_list[7].name, "--") + def test_span_params_attribute(self): + PsycopgInstrumentor().instrument(capture_parameters=True) + cnx = psycopg.connect(database="test") + query = "SELECT * FROM mytable WHERE myparam1 = %s AND myparam2 = %s" + params = ("test", 42) + + cursor = cnx.cursor() + + cursor.execute(query, params) + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + self.assertEqual(spans_list[0].name, "SELECT") + assert spans_list[0].attributes is not None + self.assertEqual(spans_list[0].attributes["db.statement"], query) + self.assertEqual( + spans_list[0].attributes["db.statement.parameters"], + str(params) + ) + # pylint: disable=unused-argument def test_not_recording(self): mock_tracer = mock.Mock() @@ -479,6 +498,25 @@ async def test_span_name_async(self): self.assertEqual(spans_list[4].name, "query") self.assertEqual(spans_list[5].name, "query") + async def test_span_params_attribute(self): + PsycopgInstrumentor().instrument(capture_parameters=True) + cnx = await psycopg.AsyncConnection.connect("test") + query = "SELECT * FROM mytable WHERE myparam1 = %s AND myparam2 = %s" + params = ("test", 42) + async with cnx.cursor() as cursor: + + await cursor.execute(query, params) + + spans_list = self.memory_exporter.get_finished_spans() + self.assertEqual(len(spans_list), 1) + self.assertEqual(spans_list[0].name, "SELECT") + assert spans_list[0].attributes is not None + self.assertEqual(spans_list[0].attributes["db.statement"], query) + self.assertEqual( + spans_list[0].attributes["db.statement.parameters"], + str(params) + ) + # pylint: disable=unused-argument async def test_not_recording_async(self): mock_tracer = mock.Mock() From dc4da8f425d0f35c40140a2d59c14ac42b94f4fe Mon Sep 17 00:00:00 2001 From: StefanoOvus <19593841+StefanoOvus@users.noreply.github.com> Date: Mon, 25 Aug 2025 17:34:41 +0200 Subject: [PATCH 3/3] add changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70f55ad4e4..21232958fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3666](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3666)) - `opentelemetry-sdk-extension-aws` Add AWS X-Ray Remote Sampler with initial Rules Poller implementation ([#3366](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3366)) +- `opentelemetry-instrumentation-psycopg` Add missing parameter `capture_parameters` to instrumentor. + ([#3676](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3676)) ## Version 1.36.0/0.57b0 (2025-07-29)