Skip to content

Commit 42554e1

Browse files
committed
feat(asyncpg): replace db.statement.parameters with db.query.parameter.<key>
asyncpg has its own parameter capture implementation independent of dbapi. Update it to use the shared `db_query_parameter_attributes` helper and emit individual `db.query.parameter.<key>` attributes. Update docker-based functional tests accordingly.
1 parent 926f682 commit 42554e1

2 files changed

Lines changed: 21 additions & 9 deletions

File tree

instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ async def main():
5959
from opentelemetry.instrumentation.asyncpg.package import _instruments
6060
from opentelemetry.instrumentation.asyncpg.version import __version__
6161
from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
62-
from opentelemetry.instrumentation.utils import unwrap
62+
from opentelemetry.instrumentation.utils import (
63+
db_query_parameter_attributes,
64+
unwrap,
65+
)
6366
from opentelemetry.semconv._incubating.attributes.db_attributes import (
6467
DB_NAME,
6568
DB_STATEMENT,
@@ -107,7 +110,7 @@ def _hydrate_span_from_args(connection, query, parameters) -> dict:
107110
span_attributes[DB_STATEMENT] = query
108111

109112
if parameters is not None and len(parameters) > 0:
110-
span_attributes["db.statement.parameters"] = str(parameters)
113+
span_attributes.update(db_query_parameter_attributes(parameters))
111114

112115
return span_attributes
113116

tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
1313
InMemorySpanExporter,
1414
)
15+
from opentelemetry.semconv._incubating.attributes.db_attributes import (
16+
DB_QUERY_PARAMETER_TEMPLATE,
17+
)
1518
from opentelemetry.semconv.trace import SpanAttributes
1619
from opentelemetry.test.test_base import TestBase
1720
from opentelemetry.trace import StatusCode
@@ -360,7 +363,7 @@ def test_instrumented_execute_method_with_arguments(self, *_, **__):
360363
spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT $1;"
361364
)
362365
self.assertEqual(
363-
spans[0].attributes["db.statement.parameters"], "('1',)"
366+
spans[0].attributes[f"{DB_QUERY_PARAMETER_TEMPLATE}.0"], "'1'"
364367
)
365368

366369
def test_instrumented_fetch_method_with_arguments(self, *_, **__):
@@ -375,7 +378,7 @@ def test_instrumented_fetch_method_with_arguments(self, *_, **__):
375378
spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT $1;"
376379
)
377380
self.assertEqual(
378-
spans[0].attributes["db.statement.parameters"], "('1',)"
381+
spans[0].attributes[f"{DB_QUERY_PARAMETER_TEMPLATE}.0"], "'1'"
379382
)
380383

381384
def test_instrumented_executemany_method_with_arguments(self, *_, **__):
@@ -389,7 +392,7 @@ def test_instrumented_executemany_method_with_arguments(self, *_, **__):
389392
spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT $1;"
390393
)
391394
self.assertEqual(
392-
spans[0].attributes["db.statement.parameters"], "([['1'], ['2']],)"
395+
spans[0].attributes[f"{DB_QUERY_PARAMETER_TEMPLATE}.0"], "[['1'], ['2']]"
393396
)
394397

395398
def test_instrumented_execute_interface_error_method(self, *_, **__):
@@ -404,7 +407,13 @@ def test_instrumented_execute_interface_error_method(self, *_, **__):
404407
spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT 42;"
405408
)
406409
self.assertEqual(
407-
spans[0].attributes["db.statement.parameters"], "(1, 2, 3)"
410+
spans[0].attributes[f"{DB_QUERY_PARAMETER_TEMPLATE}.0"], "'1'"
411+
)
412+
self.assertEqual(
413+
spans[0].attributes[f"{DB_QUERY_PARAMETER_TEMPLATE}.1"], "2"
414+
)
415+
self.assertEqual(
416+
spans[0].attributes[f"{DB_QUERY_PARAMETER_TEMPLATE}.2"], "3"
408417
)
409418

410419
def test_instrumented_executemany_method_empty_query(self, *_, **__):
@@ -417,7 +426,7 @@ def test_instrumented_executemany_method_empty_query(self, *_, **__):
417426
self.assertEqual(spans[0].name, POSTGRES_DB_NAME)
418427
self.assertEqual(spans[0].attributes[SpanAttributes.DB_STATEMENT], "")
419428
self.assertEqual(
420-
spans[0].attributes["db.statement.parameters"], "([],)"
429+
spans[0].attributes[f"{DB_QUERY_PARAMETER_TEMPLATE}.0"], "[]"
421430
)
422431

423432
def test_instrumented_fetch_method_broken_asyncpg(self, *_, **__):
@@ -489,7 +498,7 @@ async def _fake_execute(*args, **kwargs):
489498
SpanAttributes.NET_PEER_PORT: 5432,
490499
SpanAttributes.NET_TRANSPORT: "ip_tcp",
491500
SpanAttributes.DB_STATEMENT: "SELECT $1",
492-
"db.statement.parameters": "('42',)",
501+
f"{DB_QUERY_PARAMETER_TEMPLATE}.0": "'42'",
493502
},
494503
)
495504
self.assertEqual(span.kind, trace.SpanKind.CLIENT)
@@ -523,7 +532,7 @@ async def _fake_cursor_execute(*args, **kwargs):
523532
SpanAttributes.NET_PEER_PORT: 5432,
524533
SpanAttributes.NET_TRANSPORT: "ip_tcp",
525534
SpanAttributes.DB_STATEMENT: "SELECT $1",
526-
"db.statement.parameters": "('99',)",
535+
f"{DB_QUERY_PARAMETER_TEMPLATE}.0": "'99'",
527536
},
528537
)
529538
self.assertEqual(span.kind, trace.SpanKind.CLIENT)

0 commit comments

Comments
 (0)