Repository: open-telemetry/opentelemetry-python-contrib

Issue:
Expand sqlalchemy pool.name to follow the semantic conventions
Spec ref: https://github.com/open-telemetry/opentelemetry-specification/pull/3050


Discussion:

Resolving patch:
diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py
--- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py
+++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py
@@ -118,8 +118,17 @@ def __init__(
         self._register_event_listener(engine, "checkin", self._pool_checkin)
         self._register_event_listener(engine, "checkout", self._pool_checkout)
 
+    def _get_connection_string(self):
+        drivername = self.engine.url.drivername or ""
+        host = self.engine.url.host or ""
+        port = self.engine.url.port or ""
+        database = self.engine.url.database or ""
+        return f"{drivername}://{host}:{port}/{database}"
+
     def _get_pool_name(self):
-        return self.engine.pool.logging_name or ""
+        if self.engine.pool.logging_name is not None:
+            return self.engine.pool.logging_name
+        return self._get_connection_string()
 
     def _add_idle_to_connection_usage(self, value):
         self.connections_usage.add(


Test patch:
diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy_metrics.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy_metrics.py
--- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy_metrics.py
+++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/tests/test_sqlalchemy_metrics.py
@@ -70,11 +70,12 @@ def test_metrics_one_connection(self):
         )
 
     def test_metrics_without_pool_name(self):
-        pool_name = ""
+        pool_name = "pool_test_name"
         engine = sqlalchemy.create_engine(
             "sqlite:///:memory:",
             pool_size=5,
             poolclass=QueuePool,
+            pool_logging_name=pool_name,
         )
 
         metrics = self.get_sorted_metrics()
diff --git a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_postgres.py b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_postgres.py
--- a/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_postgres.py
+++ b/tests/opentelemetry-docker-tests/tests/sqlalchemy_tests/test_postgres.py
@@ -95,3 +95,40 @@ class PostgresCreatorTestCase(PostgresTestCase):
         "url": "postgresql://",
         "creator": lambda: psycopg2.connect(**POSTGRES_CONFIG),
     }
+
+
+class PostgresMetricsTestCase(PostgresTestCase):
+    __test__ = True
+
+    VENDOR = "postgresql"
+    SQL_DB = "opentelemetry-tests"
+    ENGINE_ARGS = {
+        "url": "postgresql://%(user)s:%(password)s@%(host)s:%(port)s/%(dbname)s"
+        % POSTGRES_CONFIG
+    }
+
+    def test_metrics_pool_name(self):
+        with self.connection() as conn:
+            conn.execute("SELECT 1 + 1").fetchall()
+
+        pool_name = "{}://{}:{}/{}".format(
+            self.VENDOR,
+            POSTGRES_CONFIG["host"],
+            POSTGRES_CONFIG["port"],
+            self.SQL_DB,
+        )
+        metrics = self.get_sorted_metrics()
+        self.assertEqual(len(metrics), 1)
+        self.assert_metric_expected(
+            metrics[0],
+            [
+                self.create_number_data_point(
+                    value=0,
+                    attributes={"pool.name": pool_name, "state": "idle"},
+                ),
+                self.create_number_data_point(
+                    value=0,
+                    attributes={"pool.name": pool_name, "state": "used"},
+                ),
+            ],
+        )