o
    i"                     @  s   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	m
Z
 d dlmZ d dlmZmZmZ d dlmZ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G dd dZeG dd dZeG dd dZdddZ G dd deZ!dS )    )annotations)	dataclass)cached_property)Lock)CallableLiteral)context)ReadableSpanSpanSpanProcessor)SamplerTraceIdRatioBased)Self)ONE_SECOND_IN_NANOSECONDS	LevelName)WrapperSpanProcessor)	SpanLevelc                   @  s>   e Zd ZU dZded< ded< eddd	ZedddZdS )TraceBufferzArguments of `SpanProcessor.on_start` and `SpanProcessor.on_end` for spans in a single trace.

    These are stored until either the trace is included by tail sampling or it's completed and discarded.
    z)list[tuple[Span, context.Context | None]]startedzlist[ReadableSpan]endedreturnr
   c                 C  s   | j d d S )Nr   )r   self r   e/var/www/html/karishye-ai-python/venv/lib/python3.10/site-packages/logfire/sampling/_tail_sampling.py
first_span   s   zTraceBuffer.first_spanintc                 C  s   | j j}|d us
J |jS N)r   r   trace_id)r   span_contextr   r   r   r   #   s   zTraceBuffer.trace_idN)r   r
   )r   r   )__name__
__module____qualname____doc____annotations__r   r   r   r   r   r   r   r      s   
 r   c                   @  sT   e Zd ZU dZded< 	 ded< 	 ded< 	 ded	< edddZedddZdS )TailSamplingSpanInfoz`Argument passed to the [`SamplingOptions.tail`][logfire.sampling.SamplingOptions.tail] callback.r	   spancontext.Context | Noner   zLiteral['start', 'end']eventr   bufferr   r   c                 C  s   t | jS )zThe log level of the span.)r   	from_spanr&   r   r   r   r   level@   s   zTailSamplingSpanInfo.levelfloatc                 C  s*   | j jp	| j jp	d| jjjptd t S )zRThe time in seconds between the start of the trace and the start/end of this span.r   inf)r&   end_time
start_timer)   r   r,   r   r   r   r   r   durationE   s   $zTailSamplingSpanInfo.durationN)r   r   )r   r,   )r    r!   r"   r#   r$   propertyr+   r0   r   r   r   r   r%   *   s   
 r%   c                   @  sH   e Zd ZU dZdZded< 	 dZded< 	 eddd	d
ddddZdS )SamplingOptionszOptions for [`logfire.configure(sampling=...)`][logfire.configure(sampling)].

    See the [sampling guide](https://logfire.pydantic.dev/docs/guides/advanced/sampling/).
          ?float | SamplerheadNz.Callable[[TailSamplingSpanInfo], float] | Nonetailnoticeg      @        )r5   level_thresholdduration_thresholdbackground_rater9   LevelName | Noner:   float | Noner;   r,   r   r   c                  sb   t |ttfr	|nd}d   kr|  krdks"td tdd fdd	}| ||d
S )a  Returns a `SamplingOptions` instance that tail samples traces based on their log level and duration.

        If a trace has at least one span/log that has a log level greater than or equal to `level_threshold`,
        or if the duration of the whole trace is greater than `duration_threshold` seconds,
        then the whole trace will be included.
        Otherwise, the probability is `background_rate`.

        The `head` parameter is the same as in the `SamplingOptions` constructor.
        r3   r8   zEInvalid sampling rates, must be 0.0 <= background_rate <= head <= 1.0	span_infor%   r   r,   c                   s0   d ur| j krdS d ur| jkrdS  S )Nr3   )r0   r+   )r>   r;   r:   r9   r   r   get_tail_sample_rate   s
   z?SamplingOptions.level_or_duration.<locals>.get_tail_sample_rate)r5   r6   N)r>   r%   r   r,   )
isinstancer,   r   
ValueError)clsr5   r9   r:   r;   head_sample_rater@   r   r?   r   level_or_durationl   s   	z!SamplingOptions.level_or_duration)
r5   r4   r9   r<   r:   r=   r;   r,   r   r   )	r    r!   r"   r#   r5   r$   r6   classmethodrE   r   r   r   r   r2   N   s   
 
r2   r   r   rater,   r   boolc                 C  s   | t j@ t |k S r   )r   TRACE_ID_LIMITget_bound_for_rate)r   rG   r   r   r   check_trace_id_ratio   s   rK   c                      sb   e Zd ZdZd fdd	Zd d! fddZd" fddZd#ddZd$ddZd$ fddZ	  Z
S )%TailSamplingProcessorzYPasses spans to the wrapped processor if any span in a trace meets the sampling criteria.	processorr   r@   'Callable[[TailSamplingSpanInfo], float]r   Nonec                   s$   t  | || _i | _t | _d S r   )super__init__r@   tracesr   lock)r   rM   r@   	__class__r   r   rQ      s   zTailSamplingProcessor.__init__Nr&   r
   parent_contextr'   c                   s   d}d }| j 8 |jr8|jj}|jd u rtg g | j|< | j|}|d ur8|j||f | 	t
||d|}W d    n1 sBw   Y  |d u rTt || d S |r]| | d S d S )NFstart)rS   r   r   parentr   rR   getr   append
check_spanr%   rP   on_startpush_buffer)r   r&   rV   droppedr)   r   rT   r   r   r\      s$   
zTailSamplingProcessor.on_startr	   c                   s   d}d }| j 5 |jr5|jj}| j|}|d ur5|j| | t|d d|}|j	d u r5| j
|d  W d    n1 s?w   Y  |d u rPt | d S |rY| | d S d S )NFend)rS   r   r   rR   rY   r   rZ   r[   r%   rX   poprP   on_endr]   )r   r&   r^   r)   r   rT   r   r   ra      s$   
zTailSamplingProcessor.on_endr>   r%   rH   c                 C  s,   |  |}t|jj| }r| |j |S )zbIf the span meets the sampling criteria, drop the buffer and return True. Otherwise, return False.)r@   rK   r)   r   drop_buffer)r   r>   sample_ratesampledr   r   r   r[      s   
z TailSamplingProcessor.check_spanr)   r   c                 C  s   | j |j= d S r   )rR   r   )r   r)   r   r   r   rb      s   z!TailSamplingProcessor.drop_bufferc                   s4   |j D ]}t j|  q|jD ]}t | qd S r   )r   rP   r\   r   ra   )r   r)   r   r&   rT   r   r   r]      s
   

z!TailSamplingProcessor.push_buffer)rM   r   r@   rN   r   rO   r   )r&   r
   rV   r'   r   rO   )r&   r	   r   rO   )r>   r%   r   rH   )r)   r   r   rO   )r    r!   r"   r#   rQ   r\   ra   r[   rb   r]   __classcell__r   r   rT   r   rL      s    

rL   N)r   r   rG   r,   r   rH   )"
__future__r   dataclassesr   	functoolsr   	threadingr   typingr   r   opentelemetryr   opentelemetry.sdk.tracer	   r
   r    opentelemetry.sdk.trace.samplingr   r   typing_extensionsr   logfire._internal.constantsr   r   #logfire._internal.exporters.wrapperr   logfire.typesr   r   r%   r2   rK   rL   r   r   r   r   <module>   s(    #
@