Repository: open-telemetry/opentelemetry-python-contrib

Issue:
AsyncPG Instrumentation Span Names are too long when using query string
**Is your feature request related to a problem?**
Not a problem per se however, the `asyncpg` instrumentation uses sets span names as the query string which results in some very messing looking trace names in jaeger, datadog, etc and outright doesn't work with promscale due to long queries exhaust the available bytes for btree indexes.

**Describe the solution you'd like**
- The ability to change the name of the span with a hook or something similar. The `httpx` instrumentation provides hooks that receive the span and the name can be updated there.
- Just use a shorter or truncated version of the query as the name.

Which alternative solutions or features have you considered?
Not using the `asyncpg` instrumentation and manually instrumenting specific queries.



Discussion:
psycopg instrumentation uses only [the first word of the statement](https://github.com/open-telemetry/opentelemetry-python-contrib/blob/main/instrumentation/opentelemetry-instrumentation-psycopg2/src/opentelemetry/instrumentation/psycopg2/__init__.py#L218-L219). i think i can do the same with asyncpg.
span name shouldn't be a high cardinal value such as a statement. feel free to send a patch.

Resolving patch:
diff --git a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py
--- a/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py
+++ b/instrumentation/opentelemetry-instrumentation-asyncpg/src/opentelemetry/instrumentation/asyncpg/__init__.py
@@ -134,6 +134,11 @@ async def _do_execute(self, func, instance, args, kwargs):
         params = getattr(instance, "_params", {})
         name = args[0] if args[0] else params.get("database", "postgresql")
 
+        try:
+            name = name.split()[0]
+        except IndexError:
+            name = ""
+
         with self._tracer.start_as_current_span(
             name, kind=SpanKind.CLIENT
         ) as span:


Test patch:
diff --git a/tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py b/tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py
--- a/tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py
+++ b/tests/opentelemetry-docker-tests/tests/asyncpg/test_asyncpg_functional.py
@@ -62,7 +62,7 @@ def test_instrumented_execute_method_without_arguments(self, *_, **__):
         self.assertEqual(len(spans), 1)
         self.assertIs(StatusCode.UNSET, spans[0].status.status_code)
         self.check_span(spans[0])
-        self.assertEqual(spans[0].name, "SELECT 42;")
+        self.assertEqual(spans[0].name, "SELECT")
         self.assertEqual(
             spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT 42;"
         )
@@ -72,6 +72,7 @@ def test_instrumented_fetch_method_without_arguments(self, *_, **__):
         spans = self.memory_exporter.get_finished_spans()
         self.assertEqual(len(spans), 1)
         self.check_span(spans[0])
+        self.assertEqual(spans[0].name, "SELECT")
         self.assertEqual(
             spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT 42;"
         )
@@ -189,7 +190,7 @@ def test_instrumented_execute_method_with_arguments(self, *_, **__):
         self.assertIs(StatusCode.UNSET, spans[0].status.status_code)
 
         self.check_span(spans[0])
-        self.assertEqual(spans[0].name, "SELECT $1;")
+        self.assertEqual(spans[0].name, "SELECT")
         self.assertEqual(
             spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT $1;"
         )
@@ -203,6 +204,7 @@ def test_instrumented_fetch_method_with_arguments(self, *_, **__):
         self.assertEqual(len(spans), 1)
 
         self.check_span(spans[0])
+        self.assertEqual(spans[0].name, "SELECT")
         self.assertEqual(
             spans[0].attributes[SpanAttributes.DB_STATEMENT], "SELECT $1;"
         )