o
    i#                     @   s   d 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 g dZeeZG dd dZG dd dZ dS )zSamplers manage the client-side trace sampling

Any `sampled = False` trace won't be written, and can be ignored by the instrumentation.
    N)JSONDecodeError)Optional)Span)_SAMPLING_LIMIT_DECISION)config   )ENV_KEY)MAX_UINT_64BITS)SAMPLING_HASH_MODULO)SAMPLING_KNUTH_FACTOR)SamplingMechanism)
get_logger)RateLimiter)%_get_highest_precedence_rule_matching)_set_sampling_tags   )SamplingRule)customerdynamicdefaultc                   @   sP   e Zd ZdZddeddfddZdeddfdd	Zd
edefddZ	d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                 C   s   t dtd|}| | dS )z0sample_rate is clamped between 0 and 1 inclusiver   r   N)minmaxset_sample_rateselfr    r   J/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/_trace/sampler.py__init__'   s   zRateSampler.__init__c                 C   s   t || _| jt | _d S N)floatr   r	   sampling_id_thresholdr   r   r   r    r   ,   s   
zRateSampler.set_sample_ratespanc                 C   s   |j t t | jk}|S r"   )_trace_id_64bitsr   r
   r$   )r   r%   sampledr   r   r    sample0   s   zRateSampler.samplec                 C   s   d| j  dS )NzRateSampler(sample_rate=)r   )r   r   r   r    __repr__4   s   zRateSampler.__repr__)r   )__name__
__module____qualname____doc__r#   r!   r   r   boolr(   r+   r   r   r   r    r       s    r   c                	   @   s   e Zd ZdZdZdZdZ				d!deee	  d	ee
 d
edefddZedee dee fddZdeeef ddfddZdd ZeZdeddfddZdedefddZdee	 dede
fdd ZdS )"DatadogSamplerat  
    The DatadogSampler samples traces based on the following (in order of precedence):
       - A list of sampling rules, applied in the order they are provided. The first matching rule is used.
       - A global rate limit, applied only if a rule is matched or if `rate_limit_always_on` is set to `True`.
       - Sample rates provided by the agent (priority sampling, maps sample rates to service and env tags).
       - By default, spans are sampled at a rate of 1.0 and assigned an `AUTO_KEEP` priority, allowing
         the agent to determine the final sample rate and sampling decision.

    Example sampling rules::

        DatadogSampler(rules=[
            SamplingRule(sample_rate=1.0, service="my-svc"),
            SamplingRule(sample_rate=0.0, service="less-important"),
            SamplingRule(sample_rate=0.5), # sample all remaining services at 50%
        ])
    )limiterrules_rate_limit_always_on_agent_based_samplerszservice:,env:zSampling decision applied to %s: sampled=%s sample_rate=%s sampling_mechanism=%s matched_trace_sampling_rule=%s agent_sampled=%s rules=%s sampler_id=%sN    eAFr3   
rate_limitrate_limit_windowrate_limit_always_onc                 C   sb   t j}|du r|r| | n|pg | _i | _|| _|du r#tt j}t||| _	t
d|  dS )aD  
        Constructor for DatadogSampler sampler

        :param rules: list of :class:`SamplingRule` rules to apply to the root span of every trace, default no rules
        :param rate_limit: Global rate limit (traces per second) to apply to all traces regardless of the rules
            applied to them, (default: ``100``)
        :param rate_limit_window: The time window in nanoseconds for the rate limit, default is 1 second
        :param rate_limit_always_on: If set to `True`, the rate limit is always applied, even if no sampling rules
            are provided.
        Nzinitialized %r)r   _trace_sampling_rulesset_sampling_rulesr3   r5   r4   int_trace_rate_limitr   r2   logdebug)r   r3   r7   r8   r9   global_sampling_rulesr   r   r    r!   W   s   

zDatadogSampler.__init__serviceenvc                 C   s   d| pd d|p	d S )zACompute a key with the same format used by the Datadog agent API.zservice: z,env:r   )rA   rB   r   r   r    _keyx   s   zDatadogSampler._keyrate_by_servicer   c                 C   s<   i }|  D ]
\}}t|||< qtdt| || _d S )NzSUpdated DatadogSampler with %d service based sampling rates (provided by the agent))itemsr   r>   r?   lenr5   )r   rE   samplerskeyr   r   r   r    #update_rate_by_service_sample_rates}   s
   
z2DatadogSampler.update_rate_by_service_sample_ratesc              	   C   s>   dd | j  D }| jj d|d| jd| jd| j	S )Nc                 S   s   i | ]\}}||j qS r   r*   ).0rI   samplerr   r   r    
<dictcomp>   s    z*DatadogSampler.__str__.<locals>.<dictcomp>z(agent_rates=z
, limiter=z, rules=z), rate_limit_always_on=)r5   rF   	__class__r,   r2   r3   r4   )r   ratesr   r   r    __str__   s   zDatadogSampler.__str__c              	   C   s   g }z!t |}|D ]}d|vrtd| q
|td
i | q
W n ttfy7   tjd||dd Y nw t|dd d| _	d	S )z0Sets the trace sampling rules from a JSON stringr   z8No sample_rate provided for sampling rule: %s. Skipping.z8Failed to apply all sampling rules. Rules=%s, Applied=%sT)exc_infoc                 S   s   t | jS r"   )PROVENANCE_ORDERindex
provenance)ruler   r   r    <lambda>   s    z3DatadogSampler.set_sampling_rules.<locals>.<lambda>)rI   Nr   )
jsonloadsr>   errorappendr   r   
ValueErrorsortedr3   )r   r3   sampling_rules
json_rulesrU   r   r   r    r;      s   
z!DatadogSampler.set_sampling_rulesr%   c                 C   s  |   t|| j}d}d}d }|r||}|j}n| js:| |j|t	}|| j
v r:| j
| }||}|j}|s?| jrN|rN| j }|t| jj | ||d u}t|||| t| j||||||d urnt|nd| jd uryt| jndt| 	 |S )NTr   None)_update_tags_from_contextr   r3   r(   r   r4   rD   rA   get_tagr   r5   r2   
is_allowed
set_metricr   effective_rate_get_sampling_mechanismr   r>   r?   SAMPLE_DEBUG_MESSAGEstrid)r   r%   matched_ruler'   r   agent_samplerrI   sampling_mechanismr   r   r    r(      sJ   





zDatadogSampler.sampleri   agent_service_basedc                 C   sN   |r
|j dkr
tjS |r|j dkrtjS |rtjS | jrtjS |r$tjS tjS )Nr   r   )	rT   r   REMOTE_USER_TRACE_SAMPLING_RULE"REMOTE_DYNAMIC_TRACE_SAMPLING_RULELOCAL_USER_TRACE_SAMPLING_RULEr4   APPSECAGENT_RATE_BY_SERVICEDEFAULT)r   ri   rl   r   r   r    re      s   z&DatadogSampler._get_sampling_mechanism)NNr6   F)r,   r-   r.   r/   	__slots___default_keyrf   r   listr   r<   r#   r0   r!   staticmethodrg   rD   dictrJ   rP   r+   r;   r   r(   re   r   r   r   r    r1   8   s6    

!/r1   )!r/   rW   json.decoderr   typingr   ddtrace._trace.spanr   ddtrace.constantsr   !ddtrace.internal.settings._configr   	constantsr   internal.constantsr	   r
   r   r   internal.loggerr   internal.rate_limiterr   internal.samplingr   r   sampling_ruler   rR   r,   r>   r   r1   r   r   r   r    <module>   s*    