
    Kid                     B   U d Z ddlmZ ddlmZmZmZmZ ddlmZm	Z	m
Z
mZmZmZ ddlmZmZ ddlmZ ddlmZ ddlmZmZmZ erdd	lmZ dd
lmZ ddlmZ daee   e d<   dZ!dZ" edgdd      	 	 	 	 	 	 	 dXde#de$dee#   dee%   dee#   dee&   dee'   dee%   dee%   ddfd       Z(ddde$ddfd Z)	 dYd!e#d"e	d#e%ddfd$Z* ed%d&'      dZd(       Z+ ed%d&'      d)ed   ddfd*       Z,d!e#ddfd+Z-d!e#de$ddfd,Z.	 	 d[d-ee   d.ee&   ddfd/Z/d0e#d1e#d2e'ddfd3Z0d!e#ddfd4Z1	 	 	 	 	 	 	 d\dee#   dee%   d5ee#   d6ee%   d.ee&   dee%   d7e'ddfd8Z2	 	 d[d9ed:ee#   d;ee'   ddfd<Z3 ed=gd>d      	 	 	 d]d?e$d@ee#   dAee#   d=ee#   ddf
dB       Z4 ed=gd>d      	 	 d[dAee#   d=ee#   ddfdC       Z5de#de%d5e#d6e%d1e#ddfdDZ6	 d^dEee   fdFZ7dZdGZ8	 d^dHed!ee#   ddfdIZ9	 d^dJe%dKee
   ddfdLZ:dMe%ddfdNZ;dOdPdQdPdKeddfdRZ<dee   fdSZ=dedT   fdUZ>dZdVZ?de'fdWZ@y)_aT  
Simple, clean API for recording observability metrics.

This module provides a straightforward interface for Redis core code to record
metrics without needing to know about OpenTelemetry internals.

Usage in Redis core code:
    from redis.observability.recorder import record_operation_duration

    start_time = time.monotonic()
    # ... execute Redis command ...
    record_operation_duration(
        command_name='SET',
        duration_seconds=time.monotonic() - start_time,
        server_address='localhost',
        server_port=6379,
        db_namespace='0',
        error=None
    )
    )datetime)TYPE_CHECKINGCallableListOptional)AttributeBuilderConnectionState	CSCReason	CSCResultGeoFailoverReasonPubSubDirection)CloseReasonRedisMetricsCollector)get_observability_instance)!get_observables_registry_instance)deprecated_argsdeprecated_functionstr_if_bytes)ConnectionPoolInterface)SyncDatabase)
OTelConfigN_metrics_collector	csc_itemsconnection_count
batch_sizezXThe batch_size argument is no longer used and will be removed in the next major version.z7.2.1)args_to_warnreasonversioncommand_nameduration_secondsserver_addressserver_portdb_namespaceerroris_blockingretry_attemptsreturnc	                     t         t               a t         y	 t         j                  | |||||||||
       y# t        $ r Y yw xY w)a  
    Record a Redis command execution duration.

    This is a simple, clean API that Redis core code can call directly.
    If observability is not enabled, this returns immediately with zero overhead.

    Args:
        command_name: Redis command name (e.g., 'GET', 'SET')
        duration_seconds: Command execution time in seconds
        server_address: Redis server address
        server_port: Redis server port
        db_namespace: Redis database index
        error: Exception if command failed, None if successful
        is_blocking: Whether the operation is a blocking command
        batch_size: Number of commands in batch (for pipelines/transactions)
        retry_attempts: Number of retry attempts made

    Example:
        >>> start = time.monotonic()
        >>> # ... execute command ...
        >>> record_operation_duration('SET', time.monotonic() - start, 'localhost', 6379, '0')
    N)
r   r    r!   r"   r#   
error_typenetwork_peer_addressnetwork_peer_portr%   r&   )r   _get_or_create_collectorrecord_operation_duration	Exception)	r   r    r!   r"   r#   r$   r%   r   r&   s	            h/home/jay/workspace/scripts/.codegraph-venv/lib/python3.12/site-packages/redis/observability/recorder.pyr-   r-   2   sg    R !57%44%-)#%!/)#) 	5 	
  s   9 	AAconnection_poolr   c                     t         t               a t         y	 t         j                  | |       y# t        $ r Y yw xY w)as  
    Record connection creation time.

    Args:
        connection_pool: Connection pool implementation
        duration_seconds: Time taken to create connection in seconds

    Example:
        >>> start = time.monotonic()
        >>> # ... create connection ...
        >>> record_connection_create_time('ConnectionPool<localhost:6379>', time.monotonic() - start)
    Nr0   r    )r   r,   record_connection_create_timer.   r2   s     r/   r3   r3   t   sN    & !57%88+- 	9 	
     1 	==	pool_nameconnection_statecounterc                     t         t               a t         y	 t         j                  | ||       y# t        $ r Y yw xY w)a  
    Record a connection count change for a single state.

    Args:
        pool_name: Connection pool identifier
        connection_state: State to update (IDLE or USED)
        counter: Number to add (positive) or subtract (negative)

    Example:
        # New connection created (goes to IDLE first)
        >>> record_connection_count('pool_abc123', ConnectionState.IDLE, 1)

        # Acquire from pool (transition)
        >>> record_connection_count('pool_abc123', ConnectionState.IDLE, -1)
        >>> record_connection_count('pool_abc123', ConnectionState.USED, 1)

        # Release to pool (transition)
        >>> record_connection_count('pool_abc123', ConnectionState.USED, -1)
        >>> record_connection_count('pool_abc123', ConnectionState.IDLE, 1)

        # Pool disconnect 5 idle connections
        >>> record_connection_count('pool_abc123', ConnectionState.IDLE, -5)
    Nr5   r6   r7   )r   r,   record_connection_countr.   r9   s      r/   r:   r:      sQ    < !57%22- 	3 	

     2 	>>z{Connection count is now tracked via record_connection_count(). This functionality will be removed in the next major versionz7.4.0)r   r   c                  h    t               } | yd }	 | j                  |       y# t        $ r Y yw xY w)zB
    Initialize observable gauge for connection count metric.
    Nc                     t               }|j                  t              }g }|D ]  }|j                   |               |S N)r   getCONNECTION_COUNT_REGISTRY_KEYextend__observables_registry	callbacksobservationscallbacks        r/   observable_callbackz2init_connection_count.<locals>.observable_callback   sH    @B(,,-JK	! 	,H
+	,     rG   )r,   init_connection_countr.   )	collectorrH   s     r/   rK   rK      sI     )*I''( 	( 	
  s   % 	11connection_poolsc                      t               }|y	 ddlm  fd}t               }|j	                  t
        |       y# t        $ r Y yw xY w)zG
    Add connection pools to connection count observable registry.
    Nr   Observationc                  |    g } D ]3  }|j                         D ]  \  }}| j                   ||               5 | S )N
attributes)get_connection_countappend)rF   r0   countrS   rP   rM   s       r/   connection_count_callbackzBregister_pools_connection_count.<locals>.connection_count_callback   sU    L#3 S)8)M)M)O S%E: ''Ej(QRSS  rI   )r,   opentelemetry.metricsrP   r   registerr@   r.   )rM   rL   rW   rD   rP   s   `   @r/   register_pools_connection_countrZ      sW     )*I5	   AB%%)+D	
  s   ,> 	A
	A
c                 ~    t         t               a t         y	 t         j                  |        y# t        $ r Y yw xY w)z
    Record a connection timeout event.

    Args:
        pool_name: Connection pool identifier

    Example:
        >>> record_connection_timeout('ConnectionPool<localhost:6379>')
    Nr5   )r   r,   record_connection_timeoutr.   r\   s    r/   r]   r]     K     !57%44 	5 	
     0 	<<c                     t         t               a t         y	 t         j                  | |       y# t        $ r Y yw xY w)at  
    Record time taken to obtain a connection from the pool.

    Args:
        pool_name: Connection pool identifier
        duration_seconds: Wait time in seconds

    Example:
        >>> start = time.monotonic()
        >>> # ... wait for connection from pool ...
        >>> record_connection_wait_time('ConnectionPool<localhost:6379>', time.monotonic() - start)
    Nr5   r    )r   r,   record_connection_wait_timer.   ra   s     r/   rb   rb     sN    $ !57%66- 	7 	
  r4   close_reasonr)   c                     t         t               a t         y	 t         j                  | |       y# t        $ r Y yw xY w)a  
    Record a connection closed event.

    Args:
        close_reason: Reason for closing (e.g. 'error', 'application_close')
        error_type: Error type if closed due to error

    Example:
        >>> record_connection_closed('ConnectionPool<localhost:6379>', 'idle_timeout')
    Nrc   r)   )r   r,   record_connection_closedr.   re   s     r/   rf   rf   >  sN      !57%33%! 	4 	
  r4   connection_namemaint_notificationrelaxedc                     t         t               a t         y	 t         j                  | ||       y# t        $ r Y yw xY w)a_  
    Record a connection timeout relaxation event.

    Args:
        connection_name: Connection identifier
        maint_notification: Maintenance notification type
        relaxed: True to count up (relaxed), False to count down (unrelaxed)

    Example:
        >>> record_connection_relaxed_timeout('localhost:6379_a1b2c3d4', 'MOVING', True)
    Nrg   rh   ri   )r   r,   !record_connection_relaxed_timeoutr.   rk   s      r/   rl   rl   \  sQ    $ !57%<<+1 	= 	

  r;   c                 ~    t         t               a t         y	 t         j                  |        y# t        $ r Y yw xY w)z
    Record a connection handoff event (e.g., after MOVING notification).

    Args:
        pool_name: Connection pool identifier

    Example:
        >>> record_connection_handoff('ConnectionPool<localhost:6379>')
    Nr\   )r   r,   record_connection_handoffr.   r\   s    r/   rn   rn   }  r^   r_   r*   r+   is_internalc           	          t         t               a t         y	 t         j                  | ||||||       y# t        $ r Y yw xY w)a  
    Record error count.

    Args:
        server_address: Server address
        server_port: Server port
        network_peer_address: Network peer address
        network_peer_port: Network peer port
        error_type: Error type (Exception)
        retry_attempts: Retry attempts
        is_internal: Whether the error is internal (e.g., timeout, network error)

    Example:
        >>> record_error_count('localhost', 6379, 'localhost', 6379, ConnectionError(), 3)
    Nr!   r"   r*   r+   r)   r&   ro   )r   r,   record_error_countr.   rq   s          r/   rr   rr     s]    4 !57%--)#!5/!)# 	. 	
  s   6 	AA	directionchannelshardedc                     t         t               a t         y|}|t               }||j                  rd}	 t         j	                  | ||       y# t
        $ r Y yw xY w)a5  
    Record a PubSub message (published or received).

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

    Example:
        >>> record_pubsub_message(PubSubDirection.PUBLISH, 'channel', False)
    N)rs   rt   ru   )r   r,   _get_confighide_pubsub_channel_namesrecord_pubsub_messager.   )rs   rt   ru   effective_channelconfigs        r/   ry   ry     sz    $ !57%  &"B"B $00% 	1 	

     A 	AAconsumer_namez[The consumer_name argument is no longer used and will be removed in the next major version.lag_secondsstream_nameconsumer_groupc                     t         t               a t         y|}|t               }||j                  rd}	 t         j	                  | ||       y# t
        $ r Y yw xY w)z
    Record the lag of a streaming message.

    Args:
        lag_seconds: Lag in seconds
        stream_name: Stream name
        consumer_group: Consumer group name
        consumer_name: Consumer name
    Nr~   r   r   )r   r,   rw   hide_stream_namesrecord_streaming_lagr.   )r~   r   r   r}   effective_stream_namer{   s         r/   r   r     sz    , !57% (&":":$(!//#-) 	0 	

  r|   c           
         t         t               a t         y| sy	 t        j                         j	                         }t               }|duxr |j                  }t        | t              r| j                         D ]y  \  }}|rdn
t        |      }|D ]`  }	|	D ]Y  }
|
\  }}t        |      }|j                  d      \  }}t        d|t        |      dz  z
        }t         j                  |||       [ b { y| D ]w  }t        |d         }|rdn|}|d   D ]Y  }
|
\  }}t        |      }|j                  d      \  }}t        d|t        |      dz  z
        }t         j                  |||       [ y y# t        $ r Y yw xY w)aQ  
    Record streaming lag from XREAD/XREADGROUP response.

    Parses the response and calculates lag for each message based on message ID timestamp.

    Args:
        response: Response from XREAD/XREADGROUP command
        consumer_group: Consumer group name (for XREADGROUP)
        consumer_name: Consumer name (for XREADGROUP)
    N-g        i  r   r      )r   r,   r   now	timestamprw   r   
isinstancedictitemsr   splitmaxintr   r.   )responser   r}   r   r{   r   r   stream_messagesr   messagesmessage
message_id_r   r~   stream_entrys                   r/   "record_streaming_lag_from_responser     s   . !57%-lln&&( "$.K63K3K h%080@ ,_-D<3L & !0 H#+ (/
A%1*%=
'1'7'7'<	1&)#sS^d5J/J&K*??(3(=+9 @ 	& !) *<?;0A{%+A G$+MJ!-j!9J#-#3#3C#8LIq"%c3Y$1F+F"GK&;;$/$9'5 < 	   s   CE4 7A<E4 4	F ?F c                     t         t               a t         y	 t         j                  | ||||       y# t        $ r Y yw xY w)a  
    Record a maintenance notification count.

    Args:
        server_address: Server address
        server_port: Server port
        network_peer_address: Network peer address
        network_peer_port: Network peer port
        maint_notification: Maintenance notification type (e.g., 'MOVING', 'MIGRATING')

    Example:
        >>> record_maint_notification_count('localhost', 6379, 'localhost', 6379, 'MOVING')
    Nr!   r"   r*   r+   rh   )r   r,   record_maint_notification_countr.   r   s        r/   r   r   h  sW    , !57%	::)#!5/1 	; 	
  s   4 	A A resultc                 ~    t         t               a t         y	 t         j                  |        y# t        $ r Y yw xY w)zm
    Record a Client Side Caching (CSC) request.

    Args:
        result: CSC result ('hit' or 'miss')
    Nr   )r   r,   record_csc_requestr.   r   s    r/   r   r     sK     !57%-- 	. 	
  r_   c                      t         t               a t         yd } 	 t         j                  |        y# t        $ r Y yw xY w)z;
    Initialize observable gauge for CSC items metric.
    Nc                     t               }|j                  t              }g }|D ]  }|j                   |               |S r>   )r   r?   CSC_ITEMS_REGISTRY_KEYrA   rB   s        r/   rH   z+init_csc_items.<locals>.observable_callback  sH    @B(,,-CD	! 	,H
+	, rI   rJ   )r   r,   init_csc_itemsr.   )rH   s    r/   r   r     sP     !57%))( 	* 	
  s   3 	??rG   c                      t         t               a t         yddlm  fd}	 t	               }|j                  t        |       y# t        $ r Y yw xY w)z
    Adds given callback to CSC items observable registry.

    Args:
        callback: Callback function that returns the cache size
        pool_name: Connection pool name for observability
    Nr   rO   c                  L              t        j                              gS )Nr\   rR   )r   build_csc_attributes)rP   rG   r5   s   r/   csc_items_callbackz7register_csc_items_callback.<locals>.csc_items_callback  s(    
+@@9U
 	
rI   )r   r,   rX   rP   r   rY   r   r.   )rG   r5   r   rD   rP   s   ``  @r/   register_csc_items_callbackr     sY     !57% 2
@B%%&<>PQ s    A
 
	AArV   r   c                     t         t               a t         y	 t         j                  | |       y# t        $ r Y yw xY w)z
    Record a Client Side Caching (CSC) eviction.

    Args:
        count: Number of evictions
        reason: Reason for eviction
    NrV   r   )r   r,   record_csc_evictionr.   r   s     r/   r   r     sN     !57%.. 	/ 	
  r4   bytes_savedc                 ~    t         t               a t         y	 t         j                  |        y# t        $ r Y yw xY w)z
    Record the number of bytes saved by using Client Side Caching (CSC).

    Args:
        bytes_saved: Number of bytes saved
    Nr   )r   r,   record_csc_network_savedr.   r   s    r/   r   r     sK     !57%33# 	4 	
  r_   	fail_fromr   fail_toc                     t         t               a t         y	 t         j                  | ||       y# t        $ r Y yw xY w)z
    Record a geo failover.

    Args:
        fail_from: Database failed from
        fail_to: Database failed to
        reason: Reason for the failover
    Nr   r   r   )r   r,   record_geo_failoverr.   r   s      r/   r   r     sQ     !57%.. 	/ 	

  r;   c                  <   	 t               j                         } | | j                  j                  sy| j	                         j                  t        j                  t        j                        }t        || j                        S # t        $ r Y yt        $ r Y yw xY w)z
    Get or create the global metrics collector.

    Returns:
        RedisMetricsCollector instance if observability is enabled, None otherwise
    N)r   get_provider_managerr{   enabled_telemetryget_meter_provider	get_meterr   
METER_NAMEMETER_VERSIONImportErrorr.   )managermeters     r/   r,   r,   9  s    ,.CCE?'.."B"B **,66!,,.C.Q.Q
 %UGNN;;  s   0B AB 	BBBr   c                  p    	 t               j                         } | y| j                  S # t        $ r Y yw xY w)z
    Get the OTel configuration from the observability manager.

    Returns:
        OTelConfig instance if observability is enabled, None otherwise
    N)r   r   r{   r.   )r   s    r/   rw   rw   T  s<    ,.CCE?~~ s   ) ) 	55c                      da y)zM
    Reset the global collector (used for testing or re-initialization).
    N)r    rI   r/   reset_collectorr   d  s
    
 rI   c                  2    t         
t               a t         duS )zw
    Check if observability is enabled.

    Returns:
        True if metrics are being collected, False otherwise
    N)r   r,   r   rI   r/   
is_enabledr   l  s     !57T))rI   )NNNNNNN)r   )r'   N)NN)NNNNNNT)NNNr>   )A__doc__r   typingr   r   r   r   redis.observability.attributesr   r	   r
   r   r   r   redis.observability.metricsr   r   redis.observability.providersr   redis.observability.registryr   redis.utilsr   r   r   redis.connectionr   redis.multidb.databaser   redis.observability.configr   r   __annotations__r   r@   strfloatr   r.   boolr-   r3   r:   rK   rZ   r]   rb   rf   rl   rn   rr   ry   r   r   r   r   r   r   r   r   r   r,   rw   r   r   r   rI   r/   <module>r      s  *  : :  K D J J J835 7; H23 :$  2  e %)!%"&!%"& $$(::: SM: #	:
 3-: I: $: : SM: 
:
:z. 
H **%* * 
	*Z C

4 C
45	
:	6 
B +/&*;'# 
<  
	B	8 %)!%*.'+&*$(*SM*#* #3-*  }	*
 #* SM* * 
*^ ""%%c]% d^% 
	%P !"h "&$(#'	$$#$ SM$ C=	$
 
$
$N !"h %)#'GSMG C=G 
	G
GT$$$ $ 	$
 $ 
$P #'Y0>  $!!}! 
!L #'Y 
6	0  
	<(+@"A 6Xl+  *D *rI   