o
    ie5                     @   sn  d Z ddlmZ ddlmZmZmZmZmZ ddl	Z	er4ddl
mZ ddlmZ ddlmZ ddlmZ d	Zd
ZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(d Z)d!Z*d"Z+d#Z,d$Z-d%Z.d&Z/d'Z0G d(d) d)eZ1G d*d+ d+eZ2G d,d- d-eZ3G d.d/ d/eZ4G d0d1 d1eZ5G d2d3 d3Z6d4ed5 d6e7fd7d8Z8d9ed: fd;d<Z9dS )=a  
OpenTelemetry semantic convention attributes for Redis.

This module provides constants and helper functions for building OTel attributes
according to the semantic conventions for database clients.

Reference: https://opentelemetry.io/docs/specs/semconv/database/redis/
    )Enum)TYPE_CHECKINGAnyDictOptionalUnionN)ConnectionPool)AsyncDatabase)ConnectionPoolInterface)SyncDatabasez	db.systemzdb.namespacezdb.operation.namezdb.response.status_codezdb.stored_procedure.namez
error.typeznetwork.peer.addressznetwork.peer.portzserver.addresszserver.portzdb.client.connection.pool.namezdb.client.connection.statezdb.client.connection.namezdb.client.geofailover.fail_fromzdb.client.geofailover.fail_tozdb.client.geofailover.reasonzredis.client.libraryzredis.client.connection.pubsubz$redis.client.connection.close.reasonz$redis.client.connection.notificationz%redis.client.operation.retry_attemptszredis.client.operation.blockingz%redis.client.pubsub.message.directionzredis.client.pubsub.channelzredis.client.pubsub.shardedzredis.client.errors.internalzredis.client.errors.categoryzredis.client.stream.namezredis.client.consumer_groupzredis.client.csc.resultzredis.client.csc.reasonc                   @      e Zd ZdZdZdS )ConnectionStateidleusedN)__name__
__module____qualname__IDLEUSED r   r   R/home/ubuntu/.local/lib/python3.10/site-packages/redis/observability/attributes.pyr   C       r   c                   @   r   )PubSubDirectionpublishreceiveN)r   r   r   PUBLISHRECEIVEr   r   r   r   r   H   r   r   c                   @   r   )	CSCResulthitmissN)r   r   r   HITMISSr   r   r   r   r   M   r   r   c                   @   r   )	CSCReasonfullinvalidationN)r   r   r   FULLINVALIDATIONr   r   r   r   r"   R   r   r"   c                   @   r   )GeoFailoverReason	automaticmanualN)r   r   r   	AUTOMATICMANUALr   r   r   r   r'   W   r   r'   c                   @   s   e Zd ZdZe			d2dee dee dee deee	f fddZ
e							d3d	eeeef  d
ee dee dee dee dee dee deee	f fddZe				d4dee dee dee dee deee	f f
ddZe		d5dee dee deee	f fddZe		d5dedee dee deee	f fdd Ze			d2d!ee d"ee d#ee deee	f fd$d%Ze			d2dee d&ee d'ee deee	f fd(d)Zed*ed+ d,ed+ d'edeee	f fd-d.Ze	/d6dedededefd0d1ZdS )7AttributeBuilderzY
    Helper class to build OTel semantic convention attributes for Redis operations.
    Nserver_addressserver_portdb_namespacereturnc                 C   sL   t dtdtj i}| dur| |t< |dur||t< |dur$t||t< |S )a*  
        Build base attributes common to all Redis operations.

        Args:
            server_address: Redis server address (FQDN or IP)
            server_port: Redis server port
            db_namespace: Redis database index

        Returns:
            Dictionary of base attributes
        redisz
redis-py:vN)	DB_SYSTEMREDIS_CLIENT_LIBRARYr1   __version__SERVER_ADDRESSSERVER_PORTstrDB_NAMESPACE)r-   r.   r/   attrsr   r   r   build_base_attributesa   s   z&AttributeBuilder.build_base_attributescommand_name
batch_sizenetwork_peer_addressnetwork_peer_portstored_procedure_nameretry_attemptsis_blockingc                 C   s   i }| durt | tr| jddd} |  |t< |dur ||t< |dur(||t< |dur0||t< |dur<|dkr<||t< |durD||t	< |S )aw  
        Build attributes for a Redis operation (command execution).

        Args:
            command_name: Redis command name (e.g., 'GET', 'SET', 'MULTI'), can be str or bytes
            batch_size: Number of commands in batch (for pipelines/transactions)
            network_peer_address: Resolved peer address
            network_peer_port: Peer port number
            stored_procedure_name: Lua script name or SHA1 digest
            retry_attempts: Number of retry attempts made
            is_blocking: Whether the operation is a blocking command

        Returns:
            Dictionary of operation attributes
        Nzutf-8replace)errorsr   )

isinstancebytesdecodeupperDB_OPERATION_NAMENETWORK_PEER_ADDRESSNETWORK_PEER_PORTDB_STORED_PROCEDURE_NAME%REDIS_CLIENT_OPERATION_RETRY_ATTEMPTSREDIS_CLIENT_OPERATION_BLOCKING)r;   r<   r=   r>   r?   r@   rA   r9   r   r   r   build_operation_attributes   s    
z+AttributeBuilder.build_operation_attributes	pool_nameconnection_stateconnection_name	is_pubsubc                 C   sN   t  }| dur| |t< |dur|j|t< |dur||t< |dur%||t< |S )ay  
        Build attributes for connection pool metrics.

        Args:
            pool_name: Unique connection pool name
            connection_state: Connection state ('idle' or 'used')
            is_pubsub: Whether this is a PubSub connection
            connection_name: Unique connection name

        Returns:
            Dictionary of connection pool attributes
        N)r,   r:   DB_CLIENT_CONNECTION_POOL_NAMEvalueDB_CLIENT_CONNECTION_STATEREDIS_CLIENT_CONNECTION_PUBSUBDB_CLIENT_CONNECTION_NAME)rO   rP   rQ   rR   r9   r   r   r   build_connection_attributes   s   
z,AttributeBuilder.build_connection_attributes
error_typeis_internalc                 C   s~   i }| dur5| j j|t< t| dr| jdur| j|t< nd|t< t| dr1| jdur1| jj|t< nd|t< |dur=||t	< |S )z
        Build error attributes.

        Args:
            is_internal: Whether the error is internal (e.g., timeout, network error)
            error_type: The exception that occurred

        Returns:
            Dictionary of error attributes
        Nstatus_codeerrorrY   other)
	__class__r   
ERROR_TYPEhasattrr[   DB_RESPONSE_STATUS_CODErY   rT   REDIS_CLIENT_ERROR_CATEGORYREDIS_CLIENT_ERROR_INTERNAL)rY   rZ   r9   r   r   r   build_error_attributes   s   
z'AttributeBuilder.build_error_attributes	directionchannelshardedc                 C   s6   t  }| j|t< |dur||t< |dur||t< |S )a.  
        Build attributes for a PubSub message.

        Args:
            direction: Message direction ('publish' or 'receive')
            channel: Pub/Sub channel name
            sharded: True if sharded Pub/Sub channel

        Returns:
            Dictionary of PubSub message attributes
        N)r,   r:   rT   %REDIS_CLIENT_PUBSUB_MESSAGE_DIRECTIONREDIS_CLIENT_PUBSUB_CHANNELREDIS_CLIENT_PUBSUB_SHARDED)re   rf   rg   r9   r   r   r   build_pubsub_message_attributes   s   
z0AttributeBuilder.build_pubsub_message_attributesstream_nameconsumer_groupconsumer_namec                 C   s,   t  }| dur| |t< |dur||t< |S )a   
        Build attributes for a streaming operation.

        Args:
            stream_name: Name of the stream
            consumer_group: Name of the consumer group
            consumer_name: Name of the consumer

        Returns:
            Dictionary of streaming attributes
        N)r,   r:   REDIS_CLIENT_STREAM_NAMEREDIS_CLIENT_CONSUMER_GROUP)rl   rm   rn   r9   r   r   r   build_streaming_attributes  s   z+AttributeBuilder.build_streaming_attributesresultreasonc                 C   s@   t  }| dur| |t< |dur|j|t< |dur|j|t< |S )a\  
        Build attributes for a Client Side Caching (CSC) operation.

        Args:
            pool_name: Connection pool name (used only for csc_items metric)
            result: CSC result ('hit' or 'miss')
            reason: Reason for CSC eviction ('full' or 'invalidation')

        Returns:
            Dictionary of CSC attributes
        N)r,   r:   rS   rT   REDIS_CLIENT_CSC_RESULTREDIS_CLIENT_CSC_REASON)rO   rr   rs   r9   r   r   r   build_csc_attributes4  s   

z%AttributeBuilder.build_csc_attributes	fail_fromr   r	   fail_toc                 C   s.   t  }t| |t< t||t< |j|t< |S )a	  
        Build attributes for a geo failover.

        Args:
            fail_from: Database failed from
            fail_to: Database failed to
            reason: Reason for the failover

        Returns:
            Dictionary of geo failover attributes
        )r,   r:   get_db_nameDB_CLIENT_GEOFAILOVER_FAIL_FROMDB_CLIENT_GEOFAILOVER_FAIL_TOrT   DB_CLIENT_GEOFAILOVER_REASON)rw   ry   rs   r9   r   r   r   build_geo_failover_attributesR  s
   
z.AttributeBuilder.build_geo_failover_attributesr   c                 C   s   |  d| d| S )a  
        Build a unique connection pool name.

        Args:
            server_address: Redis server address
            server_port: Redis server port
            db_namespace: Redis database index

        Returns:
            Unique pool name in format "address:port/db"
        :/r   )r-   r.   r/   r   r   r   build_pool_namek  s   z AttributeBuilder.build_pool_name)NNN)NNNNNNN)NNNN)NN)r   )r   r   r   __doc__staticmethodr   r7   intr   r   r:   r   rE   boolrN   r   rX   	Exceptionrd   r   rk   rq   r   r"   rv   r'   r~   r   r   r   r   r   r,   \   s    
 
1
"
%



r,   pool)r
   r   r0   c                 C   sN   | j dd}| j dd}t| dd}|r | d| d| S | d| S )	a  
    Get a short string representation of a connection pool for observability.

    This provides a concise pool identifier suitable for use as a metric attribute,
    in the format: host:port_uniqueID (matching go-redis format)

    Args:
        pool: Connection pool instance

    Returns:
        Short pool name in format "host:port_uniqueID"

    Example:
        >>> pool = ConnectionPool(host='localhost', port=6379, db=0)
        >>> get_pool_name(pool)
        'localhost:6379_a1b2c3d4'
    hostunknownporti  _pool_id r   _)connection_kwargsgetgetattr)r   r   r   pool_idr   r   r   get_pool_name  s   r   databaserx   c                 C   s6   | j  d }| j  d }| j}| d| d| S )z
    Get a short string representation of a database for observability.

    Args:
        database: Database instance

    Returns:
        Short database name in format "{host}:{port}/{weight}"
    r   r   r   r   )clientget_connection_kwargsweight)r   r   r   r   r   r   r   rz     s   rz   ):r   enumr   typingr   r   r   r   r   r1   redis.asyncio.connectionr   redis.asyncio.multidb.databaser	   redis.connectionr
   redis.multidb.databaser   r2   r8   rH   ra   rK   r_   rI   rJ   r5   r6   rS   rU   rW   r{   r|   r}   r3   rV   $REDIS_CLIENT_CONNECTION_CLOSE_REASON$REDIS_CLIENT_CONNECTION_NOTIFICATIONrL   rM   rh   ri   rj   rc   rb   ro   rp   rt   ru   r   r   r   r"   r'   r,   r7   r   rz   r   r   r   r   <module>   sd    	  %