
    9Yf                        d Z ddlmZ ddlZddlZddlZddlZddlZddlZddlmZm	Z	 ddl
Z
	 ddlZddl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 dd
lmZ ddlm Z   ejB                  d      Z"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+dZ,e(e'ddddddiZ-dZ.dj_                  g d      dz   Z0 e1       Z2 e3ed       xr ejh                  jk                  d!d       Z6ejh                  jk                  d"d       Z7 e
jp                         Z9d# Z:d$ Z;e6r ejx                  e:e;e;%        G d& d'e1      Z= e=       Z>y# e$ r ddlZY w xY w)(zH
DogStatsd is a Python client for DogStatsd, a Statsd fork for Datadog.
    )randomN)LockRLock)OptionalListTextUnion)TimedContextManagerDecorator"DistributedContextManagerDecoratorget_default_route)Cgroup)is_p3ktext)normalize_tags)__version__zdatadog.dogstatsd	localhosti  g333333?g-C6?zdd.internal.entity_idDD_ENTITY_IDDD_ORIGIN_DETECTION_ENABLEDi      i   DD_ENVenv
DD_SERVICEservice
DD_VERSIONversion
   
)z)datadog.dogstatsd.client.metrics:%s|c|#%sz(datadog.dogstatsd.client.events:%s|c|#%sz0datadog.dogstatsd.client.service_checks:%s|c|#%sz,datadog.dogstatsd.client.bytes_sent:%s|c|#%sz/datadog.dogstatsd.client.bytes_dropped:%s|c|#%sz5datadog.dogstatsd.client.bytes_dropped_queue:%s|c|#%sz6datadog.dogstatsd.client.bytes_dropped_writer:%s|c|#%sz.datadog.dogstatsd.client.packets_sent:%s|c|#%sz1datadog.dogstatsd.client.packets_dropped:%s|c|#%sz7datadog.dogstatsd.client.packets_dropped_queue:%s|c|#%sz8datadog.dogstatsd.client.packets_dropped_writer:%s|c|#%sregister_at_fork!DD_DOGSTATSD_DISABLE_FORK_SUPPORT&DD_DOGSTATSD_DISABLE_INSTANCE_TRACKINGc                  :    t         D ]  } | j                           y)zPrepare all client instances for a process fork.

    If SUPPORTS_FORKING is true, this will be called automatically before os.fork().
    N)
_instancespre_forkcs    V/var/www/highfloat_scraper/venv/lib/python3.12/site-packages/datadog/dogstatsd/base.pyr$   r$   i   s    
  	

    c                  :    t         D ]  } | j                           y)zRestore all client instances after a fork.

    If SUPPORTS_FORKING is true, this will be called automatically after os.fork().
    N)r#   	post_forkr%   s    r'   r*   r*   r   s    
  	r(   )beforeafter_in_childafter_in_parentc                      e Zd Zd\  ZZZZeede	dddddddde
ddddddddddddfdZed        Zej                  d	        ZdCd
Zd Zd Zd Zd Zd Zd Zd Zd Zed        Zej                  d        Zed        ZdDdZd Zeefd       Zed        Z ed        Z!dEdZ"d Z#d Z$d Z%	 	 dFdZ&	 	 	 dGd Z'	 	 	 dGd!Z(	 	 dFd"Z)	 	 dFd#Z*	 	 dFd$Z+dHd%Z,dHd&Z-dFd'Z.d( Z/dId)Z0d* Z1d+ Z2ed,        Z3ed-        Z4d. Z5d/ Z6d0 Z7d1 Z8d2 Z9d3 Z:d4 Z;ed5        Z<ed6        Z=	 	 	 	 	 	 	 dJd7Z>	 	 	 	 dHd8Z?d9 Z@d: ZAd; ZBd< ZCd= ZDd> ZEd? ZFd@ ZGdA ZHdB ZIy)K	DogStatsd)r            NTFr0   r   c                    t               | _        |t        j                  d       t        j
                  j                  d      }|r|t        k(  r|}t        j
                  j                  d      }|r|t        k(  r	 t        |      }t        j
                  j                  d|      }t        j
                  j                  d|      xs |}t        j
                  j                  d      d	vrd
| _        nd| _        || _        || _        |
|
| _        d| _        d| _        n.d| _        | j#                  ||	      | _        t        |      | _        || _        d| _        d| _        || _        |s0|r.d| _        | j#                  ||	      | _        t        |      | _        d| _        d| _        d| _        t        j
                  j                  dd      j3                  d      D cg c]  }|s|	 }}d}t4        j7                         D ]V  \  }} t        j
                  j                  |d      }!|!s)|j9                  dj;                  | |!             |t<        k(  sUd
}X |g }||z   | _        |tA        |      }|| _!        || _"        || _#        d| _$        |s%| jK                  |||      }| jM                  ||       ddj;                  tN              g| _(        | jS                          || _*        | | _+        tY        jX                         | _-        d| _.        g | _/        ta               | _1        | je                          ta               | _3        | jh                  | _5        || _6        | jl                  r&| jn                  | _5        t        jq                  d       d| _9        || _:        tw        jx                         | _=        d| _>        | j                  | jt                         d| _@        d| _A        d| _B        |s| j                  ||       t        r|rt        j                  |        yyy# t        $ r t        j                  d||       Y w xY wc c}w )a   
        Initialize a DogStatsd object.

        >>> statsd = DogStatsd()

        :envvar DD_AGENT_HOST: the host of the DogStatsd server.
        If set, it overrides default value.
        :type DD_AGENT_HOST: string

        :envvar DD_DOGSTATSD_PORT: the port of the DogStatsd server.
        If set, it overrides default value.
        :type DD_DOGSTATSD_PORT: integer

        :envvar DATADOG_TAGS: Tags to attach to every metric reported by dogstatsd client.
        :type DATADOG_TAGS: comma-delimited string

        :envvar DD_ENTITY_ID: Tag to identify the client entity.
        :type DD_ENTITY_ID: string

        :envvar DD_ENV: the env of the service running the dogstatsd client.
        If set, it is appended to the constant (global) tags of the statsd client.
        :type DD_ENV: string

        :envvar DD_SERVICE: the name of the service running the dogstatsd client.
        If set, it is appended to the constant (global) tags of the statsd client.
        :type DD_SERVICE: string

        :envvar DD_VERSION: the version of the service running the dogstatsd client.
        If set, it is appended to the constant (global) tags of the statsd client.
        :type DD_VERSION: string

        :envvar DD_DOGSTATSD_DISABLE: Disable any statsd metric collection (default False)
        :type DD_DOGSTATSD_DISABLE: boolean

        :envvar DD_TELEMETRY_HOST: the host for the dogstatsd server we wish to submit
        telemetry stats to. If set, it overrides default value.
        :type DD_TELEMETRY_HOST: string

        :envvar DD_TELEMETRY_PORT: the port for the dogstatsd server we wish to submit
        telemetry stats to. If set, it overrides default value.
        :type DD_TELEMETRY_PORT: integer

        :envvar DD_ORIGIN_DETECTION_ENABLED: Enable/disable sending the container ID field
        for origin detection.
        :type DD_ORIGIN_DETECTION_ENABLED: boolean

        :envvar DD_DOGSTATSD_DISABLE_FORK_SUPPORT: Don't install global fork hooks with os.register_at_fork.
        Global fork hooks then need to be called manually before and after calling os.fork.
        :type DD_DOGSTATSD_DISABLE_FORK_SUPPORT: boolean

        :envvar DD_DOGSTATSD_DISABLE_INSTANCE_TRACKING: Don't register instances of this class with global fork hooks.
        :type DD_DOGSTATSD_DISABLE_INSTANCE_TRACKING: boolean

        :param host: the host of the DogStatsd server.
        :type host: string

        :param port: the port of the DogStatsd server.
        :type port: integer

        :max_buffer_size: Deprecated option, do not use it anymore.
        :type max_buffer_type: None

        :flush_interval: Amount of time in seconds that the flush thread will
        wait before trying to flush the buffered metrics to the server. If set,
        it overrides the default value.
        :type flush_interval: float

        :disable_buffering: If set, metrics are no longered buffered by the client and
        all data is sent synchronously to the server
        :type disable_buffering: bool

        :param namespace: Namespace to prefix all metric names
        :type namespace: string

        :param constant_tags: Tags to attach to all metrics
        :type constant_tags: list of strings

        :param use_ms: Report timed values in milliseconds instead of seconds (default False)
        :type use_ms: boolean

        :param use_default_route: Dynamically set the DogStatsd host to the default route
        (Useful when running the client in a container) (Linux only)
        :type use_default_route: boolean

        :param socket_path: Communicate with dogstatsd through a UNIX socket instead of
        UDP. If set, disables UDP transmission (Linux only)
        :type socket_path: string

        :param default_sample_rate: Sample rate to use by default for all metrics
        :type default_sample_rate: float

        :param max_buffer_len: Maximum number of bytes to buffer before sending to the server
        if sending metrics in batch. If not specified it will be adjusted to a optimal value
        depending on the connection type.
        :type max_buffer_len: integer

        :param disable_telemetry: Should client telemetry be disabled
        :type disable_telemetry: boolean

        :param telemetry_min_flush_interval: Minimum flush interval for telemetry in seconds
        :type telemetry_min_flush_interval: integer

        :param telemetry_host: the host for the dogstatsd server we wish to submit
        telemetry stats to. Optional. If telemetry is enabled and this is not specified
        the default host will be used.
        :type host: string

        :param telemetry_port: the port for the dogstatsd server we wish to submit
        telemetry stats to. Optional. If telemetry is enabled and this is not specified
        the default host will be used.
        :type port: integer

        :param telemetry_socket_path: Submit client telemetry to dogstatsd through a UNIX
        socket instead of UDP. If set, disables UDP transmission (Linux only)
        :type telemetry_socket_path: string

        :param container_id: Allows passing the container ID, this will be used by the Agent to enrich
        metrics with container tags.
        This feature requires Datadog Agent version >=6.35.0 && <7.0.0 or Agent versions >=7.35.0.
        When configured, the provided container ID is prioritized over the container ID discovered
        via Origin Detection. When DD_ENTITY_ID is set, this value is ignored.
        Default: None.
        :type container_id: string

        :param origin_detection_enabled: Enable/disable the client origin detection.
        This feature requires Datadog Agent version >=6.35.0 && <7.0.0 or Agent versions >=7.35.0.
        When enabled, the client tries to discover its container ID and sends it to the Agent
        to enrich the metrics with container tags.
        Origin detection can be disabled by configuring the environment variabe DD_ORIGIN_DETECTION_ENABLED=false
        The client tries to read the container ID by parsing the file /proc/self/cgroup.
        This is not supported on Windows.
        The client prioritizes the value passed via DD_ENTITY_ID (if set) over the container ID.
        Default: True.
        More on this: https://docs.datadoghq.com/developers/dogstatsd/?tab=kubernetes#origin-detection-over-udp
        :type origin_detection_enabled: boolean

        :param socket_timeout: Set timeout for socket operations, in seconds. Optional.
        If sets to zero, never wait if operation can not be completed immediately. If set to None, wait forever.
        This option does not affect hostname resolution when using UDP.
        :type socket_timeout: float

        :param telemetry_socket_timeout: Set timeout for the telemetry socket operations. Optional.
        Effective only if either telemetry_host or telemetry_socket_path are set.
        If sets to zero, never wait if operation can not be completed immediately. If set to None, wait forever.
        This option does not affect hostname resolution when using UDP.
        :type telemetry_socket_timeout: float

        :param disable_background_sender: Use a background thread to communicate with the dogstatsd server. Optional.
        When enabled, a background thread will be used to send metric payloads to the Agent.
        Applications should call stop() before exiting to make sure all pending payloads are sent.
        Default: True.
        :type disable_background_sender: boolean

        :param sender_queue_size: Set the maximum number of packets to queue for the sender. Optional
        How may packets to queue before blocking or dropping the packet if the packet queue is already full.
        Default: 0 (unlimited).
        :type sender_queue_size: integer

        :param sender_queue_timeout: Set timeout for packet queue operations, in seconds. Optional.
        How long the application thread is willing to wait for the queue clear up before dropping the metric packet.
        If set to None, wait forever.
        If set to zero drop the packet immediately if the queue is full.
        Default: 0 (no wait)
        :type sender_queue_timeout: float

        :param track_instance: Keep track of this instance and automatically handle cleanup when os.fork() is called,
        if supported.
        Default: True.
        :type track_instance: boolean
        NGThe parameter max_buffer_size is now deprecated and is not used anymoreDD_AGENT_HOSTDD_DOGSTATSD_PORTzpPort number provided in DD_DOGSTATSD_PORT env var is not an integer:                 %s, using %s as port numberDD_TELEMETRY_HOSTDD_TELEMETRY_PORTDD_DOGSTATSD_DISABLE>   1yesTruetrueTFzutf-8DATADOG_TAGS ,z{name}:{value})namevaluez	client:pyzclient_version:{}r   Statsd buffering is disabled)Gr   _socket_locklogwarningosenvirongetDEFAULT_HOSTDEFAULT_PORTint
ValueError_enabled_max_buffer_lensocket_timeoutsocket_pathhostportresolve_hosttelemetry_socket_pathtelemetry_hosttelemetry_porttelemetry_socket_timeoutsockettelemetry_socketencodingsplitDD_ENV_TAGS_MAPPINGitemsappendformatENTITY_ID_ENV_VARconstant_tagsr   	namespaceuse_msdefault_sample_rate_container_id_is_origin_detection_enabled_set_container_idr   _client_tags_reset_telemetry_telemetry_flush_interval
_telemetrytime_last_flush_time_current_buffer_total_size_bufferr   _buffer_lock_reset_buffer_config_lock_send_to_buffer_send_disable_buffering_send_to_serverdebug_forking_flush_interval	threadingEvent_flush_thread_stop_flush_thread_start_flush_thread_queue_sender_thread_sender_enabledenable_background_senderTRACK_INSTANCESr#   add)"selfrR   rS   max_buffer_sizeflush_intervaldisable_bufferingrc   rb   rd   use_default_routerQ   re   disable_telemetrytelemetry_min_flush_intervalrV   rW   rU   max_buffer_lencontainer_idorigin_detection_enabledrP   rX   disable_background_sendersender_queue_sizesender_queue_timeouttrack_instance
agent_hostdogstatsd_porttagenv_tagshas_entity_idvartag_namerB   s"                                     r'   __init__zDogStatsd.__init__   s   N !F &KKab ZZ^^O4
$,.D(;<dl2>* (;^L(;^LTPT ::>>019UU DM!DM  .,"*DDIDI#D))$0ABDID	DI%:"""(@%$)-D&"&"3"3NDU"VD"%n"5D  $ $&::>>."#E#K#KC#PXCTWCXX0668 	)MCJJNN3+E 0 7 7XU 7 ST++$(M	)  M*X5 YI"#6  "'+'H'H6($ ""<1IJ &&{3
 	)E&// $		*+'!G "G ))
"3""--DJII45 
  ."+//"3!  !5!56"$())*;=QR~NN4   .?g  -"	Z Ys   >P, %Q-Q, QQc                     | j                   S N)_socket_pathr   s    r'   rQ   zDogStatsd.socket_path  s       r(   c                     | j                   5  || _        |!d| _        | j                  xs t        | _        n d| _        | j                  xs t        | _        d d d        y # 1 sw Y   y xY w)Nudpuds)rD   r   
_transportrO   UDP_OPTIMAL_PAYLOAD_LENGTH_max_payload_sizeUDS_OPTIMAL_PAYLOAD_LENGTH)r   paths     r'   rQ   zDogStatsd.socket_path  sg     	\ $D|"')-)=)=)[A[&"')-)=)=)[A[&	\ 	\ 	\   AA!!A*c                     | j                   5  d| _        || _        |d| _        d| _        n|dkD  | _        t        d|      | _        | j                          ddd       y# 1 sw Y   yxY w)a  
        Use a background thread to communicate with the dogstatsd server.
        When enabled, a background thread will be used to send metric payloads to the Agent.

        Applications should call stop() before exiting to make sure all pending payloads are sent.

        Compatible with os.fork() starting with Python 3.7. On earlier versions, compatible if applications
        arrange to call pre_fork() and post_fork() module functions around calls to os.fork().

        :param sender_queue_size: Set the maximum number of packets to queue for the sender.
            How many packets to queue before blocking or dropping the packet if the packet queue is already full.
            Default: 0 (unlimited).
        :type sender_queue_size: integer, optional
        :param sender_queue_timeout: Set timeout for packet queue operations, in seconds.
            How long the application thread is willing to wait for the queue clear up before dropping the metric packet.
            If set to None, wait forever. If set to zero drop the packet immediately if the queue is full.
            Default: 0 (no wait).
        :type sender_queue_timeout: float, optional
        TNr   )rs   r   _sender_queue_size_queue_blocking_queue_timeoutmax_start_sender_thread)r   r   r   s      r'   r   z"DogStatsd.enable_background_sender  sq    *  
	(#'D &7D##+'+$&*#';a'?$&)!-A&B#%%'
	( 
	( 
	(r   c                 t    | j                   5  d| _        | j                          ddd       y# 1 sw Y   yxY w)zuDisable background sender mode.

        This call will block until all previously queued payloads are sent.
        FN)rs   r   _stop_sender_threadr   s    r'   r   z#DogStatsd.disable_background_sender   s6    
  	'#(D $$&	' 	' 	's   .7c                     d| _         y )NFrl   r   s    r'   r   zDogStatsd.disable_telemetry	  s	    r(   c                     d| _         y )NTr   r   s    r'   enable_telemetryzDogStatsd.enable_telemetry  s	    r(   c                    | j                   s| j                  t        k  rt        j	                  d       y | j
                  ry | j                  y d }t        j                  dj                  | j                  j                        || |f      | _        d| j                  _        | j                  j                          t        j	                  d| j                         y )Nz(Statsd periodic buffer flush is disabledc                     | j                   j                         sAt        j                  |       | j	                          | j                   j                         s@y y r   )r}   is_setrm   sleepflush)r   r   s     r'   _flush_thread_loopz9DogStatsd._start_flush_thread.<locals>._flush_thread_loop  s=    --446

>*

 --446r(   z{}_flush_threadrA   targetargsTz0Statsd flush thread registered with period of %s)rv   rz   MIN_FLUSH_INTERVALrE   rx   ry   r~   r{   Threadr`   	__class____name__daemonstart)r   r   r   s      r'   r   zDogStatsd._start_flush_thread  s    ""d&:&:>P&PII@A==)	
 '--"))$..*A*AB%(

 %)!  "		>  	
r(   c                     | j                   sy 	 | j                          	 | j                  j                          | j                   j	                          d | _         | j                  j                          y # w xY wr   )r~   r   r}   setjoinclearr   s    r'   _stop_flush_threadzDogStatsd._stop_flush_thread.  sd    !!	JJL##%!!%%' s   A6 6A8c                 H    t        | j                  xs | j                        S r   )boolrU   rV   r   s    r'    _dedicated_telemetry_destinationz*DogStatsd._dedicated_telemetry_destination>  s    D..E$2E2EFFr(   c                 &    | j                          | S r   )open_bufferr   s    r'   	__enter__zDogStatsd.__enter__B  s    r(   c                 $    | j                          y r   )close_buffer)r   exc_typerB   	tracebacks       r'   __exit__zDogStatsd.__exit__G  s    r(   c                 ^    | j                   5  | j                  cd d d        S # 1 sw Y   y xY wr   )rs   rv   r   s    r'   r   zDogStatsd.disable_bufferingJ  s)     	+**	+ 	+ 	+s   #,c                 P   | j                   5  | j                  |k(  r
	 d d d        y || _        |r7| j                  | _        | j	                          t
        j                  d       n,| j                  | _        | j                  | j                         d d d        y # 1 sw Y   y xY w)NrC   )
rs   rv   rw   ru   r   rE   rx   rt   r   rz   )r   is_disableds     r'   r   zDogStatsd.disable_bufferingO  s     	?&&+5	? 	?
 '2D# !11
'')		89!11
(()=)=>	? 	? 	?s   BA,BB%c                     |s| S t               S )z
        Resolve the DogStatsd host.

        :param host: host
        :type host: string
        :param use_default_route: Use the system default route as host (overrides `host` parameter)
        :type use_default_route: bool
        r   )rR   r   s     r'   rT   zDogStatsd.resolve_hostb  s     !K ""r(   c                    | j                   5  |r| j                         r| j                  sn| j                  ,| j	                  | j                  | j
                        | _        n6| j                  | j                  | j                  | j
                        | _        | j                  cddd       S | j                  sn| j                  ,| j	                  | j                  | j                        | _	        n6| j                  | j                  | j                  | j                        | _	        | j                  cddd       S # 1 sw Y   yxY w)z
        Return a connected socket.

        Note: connect the socket before assigning it to the class instance to
        avoid bad thread race conditions.
        N)rD   r   rZ   rU   _get_uds_socketrX   _get_udp_socketrV   rW   rY   rQ   rP   rR   rS   )r   	telemetrys     r'   
get_socketzDogStatsd.get_socketq  s     	TBBD,,11=040D0D 66 991-
 150D0D // // 991- ,,	 	" ;;##/"&"6"6t7G7GI\I\"]DK"&"6"6				++#DK ;;7	 	 	s   BD>/BD>>Ec                     | j                   5  || _        | j                  r| j                  j                  |       ddd       y# 1 sw Y   yxY w)z
        Set timeout for socket operations, in seconds.

        If set to zero, never wait if operation can not be completed immediately. If set to None, wait forever.
        This option does not affect hostname resolution when using UDP.
        N)rD   rP   rY   
settimeout)r   timeouts     r'   set_socket_timeoutzDogStatsd.set_socket_timeout  sC      	0")D{{&&w/	0 	0 	0s   /AAc                 .   t         j                  dk(  r}	 |j                  t        j                  t        j
                        }||k  rH|j                  t        j                  t        j
                  |       t        j                  d|dz         y y # w xY w)Nposixz$Socket send buffer increased to %dkbi   )	rG   rA   
getsockoptrY   
SOL_SOCKET	SO_SNDBUF
setsockoptrE   rx   )clssockmin_sizerecv_buff_sizes       r'   _ensure_min_send_buffer_sizez&DogStatsd._ensure_min_send_buffer_size  sx     77g!%1B1BFDTDT!U!X-OOF$5$5v7G7GRIIDhQUoV  s   A;B Bc                     t        j                   t         j                  t         j                        }|j                  |       | j	                  |       |j                  |       |S r   )rY   AF_UNIX
SOCK_DGRAMr   r   connect)r   rQ   r   r   s       r'   r   zDogStatsd._get_uds_socket  sG    }}V^^V->->? ((.[!r(   c                 `   t         j                  d||       t        j                  ||dt        j                        }|j                  d d       t        |      dz
  }t        |      D ]q  \  }\  }}}	}
}d }	 t        j                  |||	      }|j                  |       | j                  |       |j                  |       t         j                  d|       |c S  t        d	      # t        $ r:}||j                          t         j                  d||       ||k  rY d }~|d }~ww xY w)
NzConnecting to %s:%sr   c                 .    | d   t         j                  k(  S Nr   )rY   AF_INET)vs    r'   <lambda>z+DogStatsd._get_udp_socket.<locals>.<lambda>  s    AaDFNN$: r(   T)keyreverser0   zConnected to: %szFailed to connect to %s: %sz/getaddrinfo returned no addresses to connect to)rE   rx   rY   getaddrinfor   sortlen	enumerater   r   r   	ExceptioncloserM   )r   rR   rS   r   addrinfolastaddriaftyproto_addrr   es                 r'   r   zDogStatsd._get_udp_socket  s   		't4%%dD!V5F5FG 	:DIx=1$+4X+> 	P'A'Bq$D}}RU3(006T"		,d3	P" NOO  #JJL		7qAx<s   :A!C**	D-3.D(&D((D-c                     | j                   j                          | j                  | _        |t        j                  d       yy)a~  
        Open a buffer to send a batch of metrics.

        To take advantage of automatic flushing, you should use the context manager instead

        >>> with DogStatsd() as batch:
        >>>     batch.gauge("users.online", 123)
        >>>     batch.gauge("active.connections", 1001)

        Note: This method must be called before close_buffer() matching invocation.
        Nr4   )rs   acquirert   ru   rE   rF   )r   r   s     r'   r   zDogStatsd.open_buffer  s;     	!!#))
&KKab 'r(   c                    	 | j                          | j                  r| j                  | _        | j                  j                          y# | j                  r| j                  | _        | j                  j                          w xY w)z
        Flush the buffer and switch back to single metric packets.

        Note: This method must be called after a matching open_buffer()
        invocation.
        N)r   rv   rw   ru   rs   releaser   s    r'   r   zDogStatsd.close_buffer  sd    	(JJL&&!11
%%' &&!11
%%'s   A
 
9Bc                 b    | j                   5  d| _        g | _        d d d        y # 1 sw Y   y xY wr   )rq   ro   rp   r   s    r'   rr   zDogStatsd._reset_buffer  s/     	./D+DL	 	 	s   %.c                     | j                   5  | j                  r:| j                  dj                  | j                               | j	                          ddd       y# 1 sw Y   yxY w)zM
        Flush the metrics buffer by sending the data to the server.
        r   N)rq   rp   rw   r   rr   r   s    r'   r   zDogStatsd.flush  sP      	%||$$TYYt||%<=""$		% 	% 	%s   AAA&c                 ,    | j                  |d|||      S )z
        Record the value of a gauge, optionally setting a list of tags and a
        sample rate.

        >>> statsd.gauge("users.online", 123)
        >>> statsd.gauge("active.connections", 1001, tags=["protocol:http"])
        g_reportr   metricrB   tagssample_rates        r'   gaugezDogStatsd.gauge  s     ||FCkBBr(   c                 .    | j                  |d|||       y)z
        Increment a counter, optionally setting a value, tags and a sample
        rate.

        >>> statsd.increment("page.views")
        >>> statsd.increment("files.transferred", 124)
        r&   Nr  r  s        r'   	incrementzDogStatsd.increment  s     	VS%{;r(   c                 <    |r| n|}| j                  |d|||       y)z
        Decrement a counter, optionally setting a value, tags and a sample
        rate.

        >>> statsd.decrement("files.remaining")
        >>> statsd.decrement("active.connections", 2)
        r&   Nr  )r   r  rB   r  r  metric_values         r'   	decrementzDogStatsd.decrement$  s#     "'vEVS,kBr(   c                 .    | j                  |d|||       y)z
        Sample a histogram value, optionally setting tags and a sample rate.

        >>> statsd.histogram("uploaded.file.size", 1445)
        >>> statsd.histogram("album.photo.count", 26, tags=["gender:female"])
        hNr  r  s        r'   	histogramzDogStatsd.histogram5       	VS%{;r(   c                 .    | j                  |d|||       y)z
        Send a global distribution value, optionally setting tags and a sample rate.

        >>> statsd.distribution("uploaded.file.size", 1445)
        >>> statsd.distribution("album.photo.count", 26, tags=["gender:female"])
        dNr  r  s        r'   distributionzDogStatsd.distributionD  r  r(   c                 .    | j                  |d|||       y)z
        Record a timing, optionally setting tags and a sample rate.

        >>> statsd.timing("query.response.time", 1234)
        msNr  r  s        r'   timingzDogStatsd.timingS  s     	VT5$<r(   c                      t        | ||||      S )ay  
        A decorator or context manager that will measure the distribution of a
        function's/context's run time. Optionally specify a list of tags or a
        sample rate. If the metric is not defined as a decorator, the module
        name and function name will be used. The metric is required as a context
        manager.
        ::

            @statsd.timed("user.query.time", sample_rate=0.5)
            def get_user(user_id):
                # Do what you need to ...
                pass

            # Is equivalent to ...
            with statsd.timed("user.query.time", sample_rate=0.5):
                # Do what you need to ...
                pass

            # Is equivalent to ...
            start = time.time()
            try:
                get_user(user_id)
            finally:
                statsd.timing("user.query.time", time.time() - start)
        )r
   r   r  r  r  rd   s        r'   timedzDogStatsd.timeda  s    4 ,D&$VTTr(   c                      t        | ||||      S )a  
        A decorator or context manager that will measure the distribution of a
        function's/context's run time using custom metric distribution.
        Optionally specify a list of tags or a sample rate. If the metric is not
        defined as a decorator, the module name and function name will be used.
        The metric is required as a context manager.
        ::

            @statsd.distributed("user.query.time", sample_rate=0.5)
            def get_user(user_id):
                # Do what you need to ...
                pass

            # Is equivalent to ...
            with statsd.distributed("user.query.time", sample_rate=0.5):
                # Do what you need to ...
                pass

            # Is equivalent to ...
            start = time.time()
            try:
                get_user(user_id)
            finally:
                statsd.distribution("user.query.time", time.time() - start)
        )r   r&  s        r'   distributedzDogStatsd.distributed}  s    4 2$kSYZZr(   c                 .    | j                  |d|||       y)zV
        Sample a set value.

        >>> statsd.set("visitors.uniques", 999)
        sNr  r  s        r'   r   zDogStatsd.set  s     	VS%{;r(   c                    | j                   5  | j                  r"	 | j                  j                          d| _        | j                  r"	 | j                  j                          d| _        ddd       y# t        $ r)}t        j                  dt        |             Y d}~kd}~ww xY w# t        $ r)}t        j                  dt        |             Y d}~rd}~ww xY w# 1 sw Y   yxY w)z7
        Closes connected socket if connected.
        Unexpected error: %sN)rD   rY   r   OSErrorrE   errorstrrZ   )r   r  s     r'   close_socketzDogStatsd.close_socket  s      	-{{>KK%%' #$$>))//1 )-%	- 	-  >II4c!f==>  >II4c!f==>	- 	-s]   CA3C	B(#C3	B%<B C B%%C(	C1CCCCC&c                     | j                   r| j                   dz   nd|d|d||dk7  rdt        |      z   nd|rddj                  t        |            z   nd| j                  rd	| j                  z   	S d	S )
N.r?   :|r0   z|@|#r@   |c:)rc   r   r   r   rf   )r   r  metric_typerB   r  r  s         r'   _serialize_metriczDogStatsd._serialize_metric  s     '+nnT^^c!"<*5*:TD%%B7;TCHH^D122C+/+=+=UT'''E
 	
 DFE
 	
r(   c                    |y| j                   dury| j                  r| xj                  dz  c_        || j                  }|dk7  rt	               |kD  ry| j                  |      }| j                  |||||      }| j                  |       y)z
        Create a metric packet and send it.

        More information about the packets' format: http://docs.datadoghq.com/guides/dogstatsd/
        NTr0   )rN   rl   metrics_countre   r   _add_constant_tagsr9  ru   )r   r  r8  rB   r  r  payloads          r'   r  zDogStatsd._report  s     ===$??!#22K!; 6 &&t,((eT;W 	

7r(   c                     d| _         d| _        d| _        d| _        d| _        d| _        d| _        d| _        d| _        t        j                         | _
        y r   )r;  events_countservice_checks_count
bytes_sentbytes_dropped_queuebytes_dropped_writerpackets_sentpackets_dropped_queuepackets_dropped_writerrm   rn   r   s    r'   rj   zDogStatsd._reset_telemetry  sW    $%!#$ $%!%&"&'# $		r(   c                 4    | j                   | j                  z   S r   )rE  rF  r   s    r'   packets_droppedzDogStatsd.packets_dropped  s    ))D,G,GGGr(   c                 4    | j                   | j                  z   S r   )rB  rC  r   s    r'   bytes_droppedzDogStatsd.bytes_dropped  s    ''$*C*CCCr(   c                    | j                   d d  }|j                  dj                  | j                               |j	                  | j
                         dj                  |      }t        | j                  || j                  || j                  || j                  || j                  | j                  z   || j                  || j                  || j                  || j                  | j                   z   || j                  || j                   |fz  S )Nzclient_transport:{}r@   )ri   r_   r`   r   extendrb   r   TELEMETRY_FORMATTING_STRr;  r?  r@  rA  rB  rC  rD  rE  rF  )r   r  telemetry_tagss      r'   _flush_telemetryzDogStatsd._flush_telemetry  s      #)00ABD&&'$'%%OO$$t'@'@@$$%%&&)D)DD&&''-+
 
 	
r(   c                 z    | j                   xr. | j                  | j                  z   t        j                         k  S r   )rl   rn   rk   rm   r   s    r'   _is_telemetry_flush_timez"DogStatsd._is_telemetry_flush_time  s4     Q!!D$B$BBTYY[P	Qr(   c                    | j                   a| j                  5  | j                   ?	 | j                   j                  |dz   | j                  | j                         	 d d d        y 	 d d d        | j                  |dz          y # t
        j                  $ r- | xj                  dz  c_        | xj                  dz  c_        Y gw xY w# 1 sw Y   axY w)Nr   r0   )
r   rq   putr   r   queueFullrE  rB  _xmit_packet_with_telemetryr   packets     r'   rw   zDogStatsd._send_to_server  s    ;;""" ;;*6t7K7KTM`M`a  * 	(($7 !:: 622a7200A506	 s.   C4BC=C CCCCc                    | j                  |d       | j                         r| j                         }| j                  |d      rD| j                          | xj                  dz  c_        | xj
                  t        |      z  c_        y t        j                         | _        | xj                  t        |      z  c_	        | xj                  dz  c_
        y y )NFTr0   )_xmit_packetrQ  rO  rj   rD  rA  r   rm   rn   rC  rF  )r   rX  r   s      r'   rV  z%DogStatsd._xmit_packet_with_telemetry#  s    &%(((*--/I  D1%%'!!Q&!3y>1 )-		%))S^;)++q0+ +r(   c           	      R   	 |r1| j                         r!| j                  xs | j                  d      }n| j                  xs | j                         }|j	                  |j                  | j                               |s?| j                  r3| xj                  dz  c_        | xj                  t        |      z  c_	        y# t        j                  $ r Y nt        j                  t        j                  f$ r1}t        j                  d|       | j!                          Y d }~nDd }~wt        j"                  $ r}|j$                  t$        j&                  k(  rt        j)                  d|       n|j$                  t$        j*                  k(  rt        j)                  d|       n}|j$                  t$        j,                  k(  r:t        j)                  dt        |j                  | j                              |       n&t        j                  d|       | j!                          Y d }~nDd }~wt.        $ r5}t1        d|       t        j#                  dt3        |             Y d }~nd }~ww xY w|s?| j                  r3| xj4                  t        |      z  c_        | xj6                  dz  c_        y	)
NT)r   r0   zGError submitting packet: %s, dropping the packet and closing the socketz0Socket send would block: %s, dropping the packetz+Socket buffer full: %s, dropping the packetz7Packet size too big (size: %d): %s, dropping the packetr-  F)r   rZ   r   rY   sendencoder[   rl   rD  rA  r   r   herrorgaierrorrE   rF   r1  r/  errnoEAGAINrx   ENOBUFSEMSGSIZEr   printr0  rC  rF  )r   rX  is_telemetrymysocket
socket_errexcs         r'   rZ  zDogStatsd._xmit_packet2  s   )	8 E E G00SDOOdO4S  ;;;$//*;MM&--67DOO!!Q&!3v;.~~ 	v/ 	 KKY || 	$5<</		LjY!!U]]2		GT!!U^^3		Mdmm45 
 ] !!# 	8(#.II,c#h77	8 %%V4%''1,'s7   B<B? ?I$"I$7&D##I$9C%H##I$/+II$c                    | j                   5  | j                  t        |            r| j                          | j                  j                  |       | xj                  t        |      dz   z  c_        d d d        y # 1 sw Y   y xY w)Nr0   )rq   _should_flushr   r   rp   r_   ro   rW  s     r'   rt   zDogStatsd._send_to_bufferd  sh     	?!!#f+.

LL' ++s6{Q>+	? 	? 	?s   A'A==Bc                 D    | j                   |z   dz   | j                  kD  ryy)Nr0   TF)ro   r   )r   length_to_be_addeds     r'   rj  zDogStatsd._should_flushn  s'    **-??!CdF\F\\r(   c                 &    | j                  dd      S )Nr   \nreplacestrings    r'   _escape_event_contentzDogStatsd._escape_event_contents  s    ~~dE**r(   c                 F    | j                  dd      j                  dd      S )Nr   rn  zm:zm\:ro  rq  s    r'   _escape_service_check_messagez'DogStatsd._escape_service_check_messagew  s     ~~dE*224@@r(   c
           	      `   t         j                  |      }t         j                  |      }t               s^t        |t              st	        t         j                  |      d      }t        |t              st	        t         j                  |      d      }| j                  |      }dj                  t        |j                  dd            t        |j                  dd            ||      }
|rd|
|fz  }
|	r|
d|	}
|r|
d|}
|r|
d|}
|r|
d|}
|r|
d	|}
|r|
d
dj                  |      }
| j                  r|
d| j                  }
t        |
      dkD  rt        dj                  |            | j                  r| xj                  dz  c_        | j                  |
       y)a"  
        Send an event. Attributes are the same as the Event API.
            http://docs.datadoghq.com/api/

        >>> statsd.event("Man down!", "This server needs assistance.")
        >>> statsd.event("Web server restart", "The web server is up", alert_type="success")  # NOQA
        utf8z_e{{{},{}}}:{}|{}rp  z%s|d:%dz|h:z|k:z|p:z|s:z|t:r6  r@   r7  r   z7Event "{0}" payload is too big (>=8KB). Event discardedr0   N)r/   rs  r   
isinstanceunicoder<  r`   r   r]  r   rf   rM   rl   r?  ru   )r   titlemessage
alert_typeaggregation_keysource_type_namedate_happenedpriorityr  hostnamerr  s              r'   eventzDogStatsd.event{  s   & //611': xeW-	 ? ? FOgw/!)"A"A'"JFS &&t,%,,VY/0vy12	
 &-!88F"((3F"(/:F"((3F"(*:;F"(*5F!'$8F"($*<*<=Fv;!JQQ  ??"

6r(   c                    |t         j                  |      nd}dj                  ||      }| j                  |      }|rdj                  ||      }|rdj                  ||      }|r!dj                  |dj	                  |            }|rdj                  ||      }| j
                  rd	j                  || j
                        }| j                  r| xj                  d
z  c_        | j                  |       y)zy
        Send a service check run.

        >>> statsd.service_check("my_service.check_name", DogStatsd.WARNING)
        Nr?   z_sc|{0}|{1}z	{0}|d:{1}z	{0}|h:{1}z{0}|#{1}r@   z	{0}|m:{1}z	{0}|c:{1}r0   )	r/   ru  r`   r<  r   rf   rl   r@  ru   )r   
check_namestatusr  	timestampr  r{  rr  s           r'   service_checkzDogStatsd.service_check  s     GNFY)99'B_a&&z6: &&t,!((;F!((:F ''?F!((9F!((1C1CDF??%%*%

6r(   c                 X    | j                   r|r|| j                   z   S | j                   S |S r   )rb   )r   r  s     r'   r<  zDogStatsd._add_constant_tags  s0    d0000%%%r(   c                 |    |r|s|yt         j                  j                  t        d      }|j	                         dvS )a  
        Returns whether the client should fill the container field.
        If DD_ENTITY_ID is set, we don't send the container ID
        If a user-defined container ID is provided, we don't ignore origin detection
        as dd.internal.entity_id is prioritized over the container field for backward compatibility.
        If DD_ENTITY_ID is not set, we try to fill the container field automatically unless
        DD_ORIGIN_DETECTION_ENABLED is explicitly set to false.
        Fr?   >   0nnoofffalse)rG   rH   rI   ORIGIN_DETECTION_ENABLEDlower)r   r   r   r   rB   s        r'   rg   z&DogStatsd._is_origin_detection_enabled  s:     (=L<T 

7<{{}$DDDr(   c                     |r|| _         y|r	 t               }|j                  | _         yy# t        $ r0}t        j                  dt        |             d| _         Y d}~yd}~ww xY w)zs
        Initializes the container ID.
        It can either be provided by the user or read from cgroups.
        NzCouldn't get container ID: %s)rf   r   r   r   rE   rx   r0  )r   r   r   readerr  s        r'   rh   zDogStatsd._set_container_id  sd    
 !-D#*%+%8%8" $  *		93q6B%)""*s   + 	A$&AA$c                    | j                   r| j                  ry | j                  y t        j                  | j
                        | _        t        j                  d       t        j                  dj                  | j                  j                        | j                  | j                  f      | _        d| j                  _        | j                  j!                          y )Nz!Starting background sender threadz{}_sender_threadr   T)r   ry   r   rT  Queuer   rE   rx   r{   r   r`   r   r   _sender_main_loopr   r   r   r   s    r'   r   zDogStatsd._start_sender_thread  s    ##t}};;"kk$"9"9:		56'..#**4>>+B+BC))++

 &*"!!#r(   c                     | j                   5  | j                  s
	 d d d        y | j                  j                  t               d | _        d d d        | j                  j                          d | _        y # 1 sw Y   +xY wr   )rq   r   rS  Stopr   r   r   s    r'   r   zDogStatsd._stop_sender_thread  si     	;;	 	 KKOOD!DK		 	  ""	 	s   A4&A44A=c                     	  |j                          }|t        u r |j                          y | j                  |        |j                          Nr   )rI   r  	task_donerV  )r   rT  items      r'   r  zDogStatsd._sender_main_loop*  sG    599;Dt|!,,T2EOO r(   c                 d    | j                          | j                  }| |j                          yy)z`
        Flush the buffer and wait for all queued payloads to be written to the server.
        N)r   r   r   )r   rT  s     r'   wait_for_pendingzDogStatsd.wait_for_pending3  s.    
 	


 EJJL r(   c                    t         j                  dt        j                         |        d| _        | j
                  5  | j                          | j                          ddd       | j                          y# 1 sw Y   xY w)a  Prepare client for a process fork.

        Flush any pending payloads, stop all background threads and
        close the connection. Once the function returns.

        The client should not be used from this point until
        post_fork() is called.
        z[%d] pre_fork for %sTN)	rE   rx   rG   getpidry   rs   r   r   r1  r   s    r'   r$   zDogStatsd.pre_forkB  sf     			("))+t< 	'##%$$&	' 		' 	's   !A77B c                    t         j                  dt        j                         |        | j	                          d| _        | j                  5  | j                  | j                         | j                          ddd       y# 1 sw Y   yxY w)z&Restore the client state after a fork.z[%d] post_fork for %sFN)
rE   rx   rG   r  r1  ry   rs   r   rz   r   r   s    r'   r*   zDogStatsd.post_forkT  sl     			)299;= 	($$T%9%9:%%'	( 	( 	(s   ,BBc                 r    | j                          d| _        | j                          | j                          y)zStop the client.

        Disable buffering, background sender and flush any pending payloads to the server.

        Client remains usable after this method, but sending metrics may block if socket_timeout is enabled.
        TN)r   r   r   r1  r   s    r'   stopzDogStatsd.stopa  s-     	&&(!%

r(   )r   r   )Fr   )NN)r0   NN)NNNN)r0   )NNNNNNN)Jr   
__module____qualname__OKWARNINGCRITICALUNKNOWNrJ   rK   DEFAULT_FLUSH_INTERVAL$DEFAULT_TELEMETRY_MIN_FLUSH_INTERVALr   propertyrQ   setterr   r   r   r   r   r   r   r   r   r   staticmethodrT   r   r   classmethodMIN_SEND_BUFFER_SIZEr   r   r   r   r   rr   r   r  r  r  r  r!  r$  r'  r)  r   r1  r9  r  rj   rH  rJ  rO  rQ  rw   rV  rZ  rt   rj  rs  ru  r  r  r<  rg   rh   r   r   r  r  r$   r*   r   r(   r'   r/   r/      s   %1"B7 -&J"!%!""&5J!X
 ! ! \ \(B' 
<( G
 + + ? ?$ # #"H
0 9M 
 
   P P6c((
% C& <& C* <& <& =U8[8<-&

8
, H H D D
>Q810d?
 + + A A BP #JE"* $$	#$(r(   r/   )?__doc__r   loggingrG   rY   r`  r{   rm   r   r   weakrefrT  ImportErrorr  typingr   r   r   r	   datadog.dogstatsd.contextr
   r   datadog.dogstatsd.router   datadog.dogstatsd.containerr   datadog.util.compatr   r   datadog.util.formatr   datadog.versionr   	getLoggerrE   rJ   rK   r  r   ENTITY_ID_TAG_NAMEra   r  r   r   r  r]   r  r   rM  objectr  hasattrrH   rI   SUPPORTS_FORKINGr   WeakSetr#   r$   r*   r   r/   statsdr  r(   r'   <module>r     s     	     ! 
 / . 6 . , . ' g+,     -  #  9  " !  !  )e))	  (* $
  99 		   x212t2::>>Jmos;t7t jjnn%MtTTW__
 Bx	S\]
k k\' 
q*  s   D; ;	EE