open-telemetry / opentelemetry-python-contrib

OpenTelemetry instrumentation for Python modules
https://opentelemetry.io
Apache License 2.0
739 stars 614 forks source link

Redis instrumentation doesn't handle correctly connection info #1905

Open healfy opened 1 year ago

healfy commented 1 year ago

Describe your environment Python == 3.9.9 opentelemetry-instrumentation-redis==0.40b0 redis==4.6.0

Steps to reproduce

redis = await from_url(
        config.host,
        encoding="utf-8",
        decode_responses=True,
        port=config.port,
        db=None,
    )
 RedisInstrumentor().instrument()

What is the expected behavior? There are no warnings in logs

What is the actual behavior?

WARNI - opentelemetry.attributes - Invalid type NoneType for attribute 'db.redis.database_index' value. Expected one of ['bool', 'str', 'bytes', 'int', 'float'] or a sequence of those types

The issue is in this function:

def _extract_conn_attributes(conn_kwargs):
    """Transform redis conn info into dict"""
    attributes = {
        SpanAttributes.DB_SYSTEM: DbSystemValues.REDIS.value,
    }
    db = conn_kwargs.get("db", 0)
    attributes[SpanAttributes.DB_REDIS_DATABASE_INDEX] = db
    try:
        attributes[SpanAttributes.NET_PEER_NAME] = conn_kwargs.get(
            "host", "localhost"
        )
        attributes[SpanAttributes.NET_PEER_PORT] = conn_kwargs.get(
            "port", 6379
        )
        attributes[
            SpanAttributes.NET_TRANSPORT
        ] = NetTransportValues.IP_TCP.value
    except KeyError:
        attributes[SpanAttributes.NET_PEER_NAME] = conn_kwargs.get("path", "")
        attributes[
            SpanAttributes.NET_TRANSPORT
        ] = NetTransportValues.UNIX.value

    return attributes

the result of db = conn_kwargs.get("db", 0) is None, and it's common behaviour for python Just use

db = conn_kwargs.get("db", 0) or 0
pmcollins commented 1 year ago

Hi, just wondering -- is the code you want to instrument using the aioredis library and not the redis one?

healfy commented 1 year ago

Hi, You can see in the top that I use redis==4.6.0

pmcollins commented 1 year ago

Ok, thanks. I saw redis = await from_url which from searching around looks like aioredis.

adaamz commented 1 year ago

@pmcollins You can use async with redis-py https://redis.readthedocs.io/en/stable/examples/asyncio_examples.html