Skip to content

Commit

Permalink
Fix sqlalchemy for postgres Unix sockets (#761)
Browse files Browse the repository at this point in the history
* Fix sqlalchemy for postgres unix sockets

The following bit of replaced code contained a type inconsistency:

```py
attrs[SpanAttributes.NET_PEER_PORT] = int(data.get("port"))
```

`data.get` returns `Optional[str]` but `int(None)` throws a `TypeError`.

When using postgresql via unix socket `dsn` looks something like this:

```py
'user=postgres host=/tmp/socket dbname=postgres'
```

The `parse_dsn` function returns this:

```py
{'user': 'postgres', 'dbname': 'postgres', 'host': '/tmp/socket'}
```

* Update CHANGELOG

* Conditionally set net.transport for psql tcp/unix

* Use .value properties of enums

* Improve postgresql attribute detection from cursor

* Fix formatting

Co-authored-by: Matt Oberle <[email protected]>
Co-authored-by: Srikanth Chekuri <[email protected]>
  • Loading branch information
3 people authored Nov 11, 2021
1 parent 2dd9bd1 commit 10d8e26
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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

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"))
info = getattr(getattr(cursor, "connection", None), "info", None)
if not info:
return attrs

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

0 comments on commit 10d8e26

Please sign in to comment.