
    mh4                     2   d Z ddlZddlZddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 dd	lmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ d
dlmZ g dZ 	 ddl!m"Z" n# e#$ r e$Z"Y nw xY werddl%m&Z&  ee'          Z(eZ)dZ* G d de+          Z, G d dej-                  Z. G d de.          Z/ G d  d!e.          Z0 G d" d#e.          Z1 G d$ d%e1          Z2 G d& d'e/          Z3 G d( d)e3          Z4dS )*zSamplers manage the client-side trace sampling

Any `sampled = False` trace won't be written, and can be ignored by the instrumentation.
    N)TYPE_CHECKING)Dict)List)Optional)Tuple)config)SAMPLING_LIMIT_DECISION   )ENV_KEY)_PRIORITY_CATEGORY)DEFAULT_SAMPLING_RATE_LIMIT)MAX_UINT_64BITS)
get_logger)RateLimiter)%_get_highest_precedence_rule_matching)_set_sampling_tags)SamplingRule)_config)customerdynamicdefault)JSONDecodeError)Spanl   qWV[{c                       e Zd ZdS )SamplingErrorN__name__
__module____qualname__     :/usr/local/lib/python3.11/site-packages/ddtrace/sampler.pyr   r   4           Dr!   r   c                   2    e Zd ZdZej        d             ZdS )BaseSamplerr    c                     d S Nr    selfspans     r"   samplezBaseSampler.sample;   s	     	r!   N)r   r   r   	__slots__abcabstractmethodr+   r    r!   r"   r%   r%   8   s6        I    r!   r%   )	metaclassc                   2    e Zd ZdZej        d             ZdS )BasePrioritySamplerr    c                     d S r'   r    )r)   sample_ratess     r"   #update_rate_by_service_sample_ratesz7BasePrioritySampler.update_rate_by_service_sample_ratesD   s    r!   N)r   r   r   r,   r-   r.   r4   r    r!   r"   r1   r1   A   s6        I    r!   r1   c                       e Zd ZdZd ZdS )
AllSamplerzSampler sampling all the tracesc                     dS )NTr    r(   s     r"   r+   zAllSampler.sampleL   s    tr!   N)r   r   r   __doc__r+   r    r!   r"   r6   r6   I   s)        ))    r!   r6   c                   :    e Zd ZdZd	deddfdZdeddfdZd ZdS )
RateSamplerzSampler based on a rate

    Keep (100 * `sample_rate`)% of the traces.
    It samples randomly, its main purpose is to reduce the instrumentation footprint.
          ?sample_ratereturnNc                     t          dt          d|                    }|                     |           t                              dd|z             dS )z0sample_rate is clamped between 0 and 1 inclusiver
   r   z.initialized RateSampler, sample %s%% of tracesd   N)minmaxset_sample_ratelogdebugr)   r<   s     r"   __init__zRateSampler.__init__W   sO    !SK0011[)))		BC+DUVVVVVr!   c                 V    t          |          | _        | j        t          z  | _        d S r'   )floatr<   _MAX_UINT_64BITSsampling_id_thresholdrE   s     r"   rB   zRateSampler.set_sample_rate]   s)     --%)%58H%H"""r!   c                 F    |j         t          z  t          z  | j        k    }|S r'   )_trace_id_64bitsKNUTH_FACTORrI   rJ   )r)   r*   sampleds      r"   r+   zRateSampler.samplea   s#    )L8<LLQUQkkr!   r;   )r   r   r   r8   rH   rF   rB   r+   r    r!   r"   r:   r:   P   s         W WE WD W W W WI5 IT I I I I    r!   r:   c                       e Zd ZdS )_AgentRateSamplerNr   r    r!   r"   rQ   rQ   f   r#   r!   rQ   c                   b    e Zd ZdZdZdZe	 	 dd            ZddZ	 	 ddZ	d	 Z
d
 Zd Zd ZdS )RateByServiceSamplerzSampler based on a rate, by service

    Keep (100 * `sample_rate`)% of the traces.
    The sample rate is kept independently for each service/env tuple.
    )r<   _by_service_samplers_default_samplerzservice:,env:Nc                 (    | pd} |pd}d| z   dz   |z   S )zACompute a key with the same format used by the Datadog agent API. zservice:z,env:r    )serviceenvs     r"   _keyzRateByServiceSampler._keyu   s+     -RiRG#g-33r!   r;   c                 T    || _         t          | j                   | _        i | _        d S r'   )r<   r:   rU   rT   rE   s     r"   rF   zRateByServiceSampler.__init__   s+    & +D,< = =$&!!!r!   c                     |t           j        }|t           j        }t          |          | j        |                     ||          <   d S r'   )r   rX   rY   rQ   rT   rZ   )r)   r<   rX   rY   s       r"   rB   z$RateByServiceSampler.set_sample_rate   sE     ?nG;*C=N{=[=[!$))GS"9"9:::r!   c                     |                      |          \  }}t          |||j        |                     |                     |S r'   )_make_sampling_decisionr   r<   _choose_priority_category)r)   r*   rN   samplers       r"   r+   zRateByServiceSampler.sample   sP    77==**733		
 	
 	
 r!   c                     || j         u rt          j        S t          |t                    rt          j        S t          j        S r'   )rU   r   DEFAULT
isinstancerQ   AUTORULE_DEF)r)   r`   s     r"   r_   z.RateByServiceSampler._choose_priority_category   s>    d+++%--!233 	/%**%..r!   c                     |                     t                    }|                     |j        |          }| j                            |          p| j        }|                    |          }||fS r'   )get_tagr   rZ   rX   rT   getrU   r+   )r)   r*   rY   keyr`   rN   s         r"   r^   z,RateByServiceSampler._make_sampling_decision   sb    ll7##iic**+//44M8M..&&r!   c                 p    i }|                                 D ]\  }}t          |          ||<   || _        d S r'   )itemsrQ   rT   )r)   rate_by_servicesamplersri   r<   s        r"   r4   z8RateByServiceSampler.update_rate_by_service_sample_rates   sH     / 5 5 7 7 	; 	;C-k::HSMM$,!!!r!   )NNrO   )r   r   r   r8   r,   _default_keystaticmethodrZ   rF   rB   r+   r_   r^   r4   r    r!   r"   rS   rS   j   s          LI"L4 4 4 \4' ' ' ' 	\ \ \ \   / / /     - - - - -r!   rS   c                   n     e Zd ZdZdZdZeZ	 	 	 	 	 d fd	Zd Z	e	Z
ed	             Z fd
Z fdZ xZS )DatadogSamplera  
    By default, this sampler relies on dynamic sample rates provided by the trace agent
    to determine which traces are kept or dropped.

    You can also configure a static sample rate via ``default_sample_rate`` to use for sampling.
    When a ``default_sample_rate`` is configured, that is the only sample rate used, and the agent
    provided rates are ignored.

    You may also supply a list of ``SamplingRule`` instances to set sample rates for specific
    services.

    Example rules::

        DatadogSampler(rules=[
            SamplingRule(sample_rate=1.0, service="my-svc"),
            SamplingRule(sample_rate=0.0, service="less-important"),
        ])

    Rules are evaluated in the order they are provided, and the first rule that matches is used.
    If no rule matches, then the agent sample rates are used.

    This sampler can be configured with a rate limit. This will ensure the max number of
    sampled traces per second does not exceed the supplied limit. The default is 100 traces kept
    per second.
    )limiterrulesdefault_sample_rate_rate_limit_always_onN    eAFc                    t          t          |                                            || _        |}|1t	          j        d          dk    rt          t          j                  }|t          t          j	                  }|| _
        |.t          j        }|r|                     |          }ng }|| _        njg | _        |D ]`}t          |t                    r| j                            |           2t"          j        r"t'          d                    |                    a|(| j                            t          |                     t+          ||          | _        t.                              d|            dS )a  
        Constructor for DatadogSampler sampler

        :param rules: List of :class:`SamplingRule` rules to apply to the root span of every trace, default no rules
        :param default_sample_rate: The default sample rate to apply if no rules matched (default: ``None`` /
            Use :class:`RateByServiceSampler` only)
        :param rate_limit: Global rate limit (traces per second) to apply to all traces regardless of the rules
            applied to them, (default: ``100``)
        N_trace_sample_rater   zCRule {!r} must be a sub-class of type ddtrace.sampler.SamplingRulesr<   zinitialized %r)superrq   rF   rt   ddconfig_get_sourcerH   ry   int_trace_rate_limitru   _trace_sampling_rules_parse_rules_from_strrs   rc   r   appendr   _raise	TypeErrorformatr   rr   rC   rD   )
r)   rs   rt   
rate_limitrate_limit_windowrate_limit_always_oneffective_sample_rateenv_sampling_rulesrule	__class__s
            r"   rF   zDatadogSampler.__init__   s   & 	nd##,,...#6  3&#$899YFF(-h.I(J(J%X788J%9"=!)!?! 223EFFDJJDJ x xdL11 xJ%%d++++] x#$i$p$pqu$v$vwwwx !,Jl7LMMMNNN #:/@AA		"D)))))r!   c                     d | j                                         D             }d                    | j        j        || j        | j                  S )Nc                 $    i | ]\  }}||j         S r    rz   ).0ri   r`   s      r"   
<dictcomp>z*DatadogSampler.__str__.<locals>.<dictcomp>  s!    ```lc7g)```r!   z.{}(agent_rates={!r}, limiter={!r}, rules={!r}))rT   rk   r   r   r   rr   rs   )r)   ratess     r"   __str__zDatadogSampler.__str__  sN    ``d>W>]>]>_>_```?FFN#UDL$*
 
 	
r!   c           	         g }	 t          j        |           }n># t          $ r1 t          j        r"t          d                    |                     Y nw xY w|D ]x}d|vrAt          j        r4t          d                    t          j        |                              Ht          |d                   }|
                    dt          j                  }|
                    dt          j                  }|
                    dt          j                  }|
                    dt          j                  }|
                    dd	          }		 t          ||||||	
          }
nY# t
          $ rL}t          j        r5t          d                    t          j        |          |                    Y d }~[d }~ww xY w|                    |
           zt          |d           }|S )Nz*Unable to parse DD_TRACE_SAMPLING_RULES={}r<   z-No sample_rate provided for sampling rule: {}rX   nameresourcetags
provenancer   )r<   rX   r   r   r   r   z#Error creating sampling rule {}: {}c                 @    t                               | j                  S r'   )PROVENANCE_ORDERindexr   )r   s    r"   <lambda>z6DatadogSampler._parse_rules_from_str.<locals>.<lambda>?  s    AQAWAWX\XgAhAh r!   )ri   )jsonloadsr   r   r   
ValueErrorr   KeyErrordumpsrH   rh   r   NO_RULEr   sorted)rs   sampling_rules
json_rulesr   r<   rX   r   r   r   r   sampling_rulees               r"   r   z$DatadogSampler._parse_rules_from_str  s    	]E**JJ 	] 	] 	]} ] !M!T!TUZ![![\\\] ]	]  	1 	1DD((= m"#R#Y#YZ^ZdeiZjZj#k#klll] 344Khhy,*>??G88FL$899Dxx
L,@AAH88FL$899D,	::J , +#%)! ! !    = h$%J%Q%QRVR\]aRbRbde%f%fggg !!-0000  4h4hiiis(    8AAE##
F9-AF44F9c           	      ,   |j                             |           t          || j                  }| j        }| j        }|r|                    |          }|j        }nGt          t          |           	                    |          \  }}t          |t                    r|j        }|s| j        r@|r>| j                                        }|                    t           | j        j                   t%          ||||                     ||                     |S r'   )context_update_tagsr   rs   rU   r<   r+   r{   rq   r^   rc   r:   ru   rr   
is_allowed
set_metricr	   effective_rater   #_choose_priority_category_with_rule)r)   r*   matched_ruler`   r<   rN   r   s         r"   r+   zDatadogSampler.sampleB  s   !!$'''<T4:NN'& 	2"))$//G&2KK  %^T::RRSWXXGW';// 2%1 	V45 	V  V,1133 79TUUU44\7KK		
 	
 	
 r!   c                     |r7|j         }|dk    rt          j        S |dk    rt          j        S t          j        S | j        rt          j        S t          t          |           	                    |          S )Nr   r   )
r   r   RULE_CUSTOMERRULE_DYNAMICre   ru   USERr{   rq   r_   )r)   r   r`   r   r   s       r"   r   z2DatadogSampler._choose_priority_category_with_rulec  sw     
	+JZ'')77Y&&)66%..' 	+ &**^T**DDWMMMr!   )NNNrw   F)r   r   r   r8   r,   NO_RATE_LIMITr   DEFAULT_RATE_LIMITrF   r   __repr__ro   r   r+   r   __classcell__)r   s   @r"   rq   rq      s         4 UIM4  "6* 6* 6* 6* 6* 6*p
 
 
 H$ $ \$L    BN N N N N N N N Nr!   rq   )5r8   r-   r   typingr   r   r   r   r   ddtracer   ddtrace.constantsr	   	constantsr   internal.constantsr   r   r   rI   internal.loggerr   internal.rate_limiterr   internal.samplingr   r   r   r   settingsr   r|   r   json.decoderr   ImportErrorr   ddtrace._trace.spanr   r   rC   MAX_TRACE_IDrM   	Exceptionr   ABCMetar%   r1   r6   r:   rQ   rS   rq   r    r!   r"   <module>r      sZ   
 


                                            5 5 5 5 5 5       2 2 2 2 2 2 ; ; ; ; ; ; C C C C C C ' ' ' ' ' ' . . . . . . D D D D D D 1 1 1 1 1 1 ' ' ' ' ' ' ) ) ) ) ) ) 655 !,,,,,,, ! ! ! OOO!  )(((((( j  "	 	 	 	 	I 	 	 	    CK        +              +   ,	 	 	 	 	 	 	 	M- M- M- M- M-. M- M- M-`vN vN vN vN vN) vN vN vN vN vNs   6A= =BB