diff --git a/CHANGELOG.md b/CHANGELOG.md index 811e79242..a0871b7cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.6.2-0.25b2](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.6.2-0.25b2) - 2021-10-19 +- `opentelemetry-instrumentation-sqlalchemy` Fix PostgreSQL instrumentation for Unix sockets + ([#761](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/761)) + ### Changed - `opentelemetry-sdk-extension-aws` & `opentelemetry-propagator-aws` Release AWS Python SDK Extension as 2.0.1 and AWS Propagator as 1.0.1 diff --git a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py index 5af41b984..ea0589ca3 100644 --- a/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py +++ b/instrumentation/opentelemetry-instrumentation-sqlalchemy/src/opentelemetry/instrumentation/sqlalchemy/engine.py @@ -11,12 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import os from sqlalchemy.event import listen # pylint: disable=no-name-in-module from opentelemetry import trace from opentelemetry.instrumentation.sqlalchemy.version import __version__ -from opentelemetry.semconv.trace import SpanAttributes +from opentelemetry.semconv.trace import NetTransportValues, SpanAttributes from opentelemetry.trace.status import Status, StatusCode @@ -157,14 +158,25 @@ def _get_attributes_from_url(url): def _get_attributes_from_cursor(vendor, cursor, attrs): """Attempt to set db connection attributes by introspecting the cursor.""" if vendor == "postgresql": - # pylint: disable=import-outside-toplevel - from psycopg2.extensions import parse_dsn + info = getattr(getattr(cursor, "connection", None), "info", None) + if not info: + return attrs - if hasattr(cursor, "connection") and hasattr(cursor.connection, "dsn"): - dsn = getattr(cursor.connection, "dsn", None) - if dsn: - data = parse_dsn(dsn) - attrs[SpanAttributes.DB_NAME] = data.get("dbname") - attrs[SpanAttributes.NET_PEER_NAME] = data.get("host") - attrs[SpanAttributes.NET_PEER_PORT] = int(data.get("port")) + attrs[SpanAttributes.DB_NAME] = info.dbname + is_unix_socket = info.host and info.host.startswith("/") + + if is_unix_socket: + attrs[SpanAttributes.NET_TRANSPORT] = NetTransportValues.UNIX.value + if info.port: + # postgresql enforces this pattern on all socket names + attrs[SpanAttributes.NET_PEER_NAME] = os.path.join( + info.host, f".s.PGSQL.{info.port}" + ) + else: + attrs[ + SpanAttributes.NET_TRANSPORT + ] = NetTransportValues.IP_TCP.value + attrs[SpanAttributes.NET_PEER_NAME] = info.host + if info.port: + attrs[SpanAttributes.NET_PEER_PORT] = int(info.port) return attrs