
    g(                    >   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mZmZmZ d dlmZ e G d d             Ze G d d             Ze G d d             Z e G d d             Z!ddZ" G d de      Z#y)    )annotations)	dataclass)cached_property)Lock)CallableLiteral)context)ReadableSpanSpanSpanProcessor)SamplerTraceIdRatioBased)Self)ATTRIBUTES_LOG_LEVEL_NUM_KEYLEVEL_NUMBERSNUMBER_TO_LEVELONE_SECOND_IN_NANOSECONDS	LevelName)WrapperSpanProcessorc                  ^    e Zd ZU dZded<   	 edd       ZddZd ZddZ	ddZ
dd	Zdd
Zy)	SpanLevela  A convenience class for comparing span/log levels.

    Can be compared to log level names (strings) such as 'info' or 'error' using
    `<`, `>`, `<=`, or `>=`, so e.g. `level >= 'error'` is valid.

    Will raise an exception if compared to a non-string or an invalid level name.
    intnumberc                @    t        j                  | j                        S )zIThe human-readable name of the level, or `None` if the number is invalid.)r   getr   selfs    T/var/www/openai/venv/lib/python3.12/site-packages/logfire/sampling/_tail_sampling.pynamezSpanLevel.name&   s     ""4;;//    c                    t        |t              r| j                  |k(  S t        |t              r| j                  |k(  S t        |t
              r| j                  |j                  k(  S t        S N)
isinstancer   r   strr   r   NotImplementedr   others     r   __eq__zSpanLevel.__eq__+   sW    eS!;;%''eS!99%%eY';;%,,..r    c                ,    t        | j                        S r"   )hashr   r   s    r   __hash__zSpanLevel.__hash__4   s    DKK  r    c                .    | j                   t        |   k  S r"   r   r   r&   s     r   __lt__zSpanLevel.__lt__7       {{]5111r    c                .    | j                   t        |   kD  S r"   r-   r&   s     r   __gt__zSpanLevel.__gt__:   r/   r    c                .    | j                   t        |   k\  S r"   r-   r&   s     r   __ge__zSpanLevel.__ge__=       {{mE222r    c                .    | j                   t        |   k  S r"   r-   r&   s     r   __le__zSpanLevel.__le__@   r4   r    N)returnLevelName | None)r'   object)r'   r   )__name__
__module____qualname____doc____annotations__propertyr   r(   r+   r.   r1   r3   r6    r    r   r   r      sE     K 0 0!2233r    r   c                  J    e Zd ZU dZded<   ded<   ed	d       Zed
d       Zy)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]endedc                &    | j                   d   d   S )Nr   )rC   r   s    r   
first_spanzTraceBuffer.first_spanN   s    ||Aq!!r    c                N    | j                   j                  }|J |j                  S r"   )rF   r	   trace_id)r   span_contexts     r   rH   zTraceBuffer.trace_idR   s)    ..'''$$$r    N)r7   r   )r7   r   )r:   r;   r<   r=   r>   r   rF   rH   r@   r    r   rB   rB   D   s;    
 76" " % %r    rB   c                  d    e Zd ZU dZded<   	 ded<   	 ded<   	 ded	<   edd
       Zedd       Zy)TailSamplingSpanInfoz`Argument passed to the [`SamplingOptions.tail`][logfire.sampling.SamplingOptions.tail] callback.r
   spancontext.Context | Noner	   zLiteral['start', 'end']eventrB   bufferc                    | j                   j                  xs i }|j                  t              }t	        |t
              s	t        d   }t        |      S )zThe log level of the span.info)rL   
attributesr   r   r#   r   r   r   )r   rR   levels      r   rS   zTailSamplingSpanInfo.levelo   sF     YY))/R
;<%%!&)Er    c                    | j                   j                  xs | j                   j                  xs d| j                  j                  j                  xs t        d      z
  t        z  S )zRThe time in seconds between the start of the trace and the start/end of this span.r   inf)rL   end_time
start_timerO   rF   floatr   r   s    r   durationzTailSamplingSpanInfo.durationx   sS    
 YY<499#7#7<1AWAWAbAbArfklqfrs%& 	&r    N)r7   r   )r7   rX   )r:   r;   r<   r=   r>   r?   rS   rY   r@   r    r   rK   rK   Y   sX    j
 $# #"
     & &r    rK   c                  b    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       Zy)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      @        )r^   level_thresholdduration_thresholdbackground_ratec                   t        |t        t        f      r|nd}dcxk  r|cxk  rdk  st        d       t        d      df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.
        r\   ra   zEInvalid sampling rates, must be 0.0 <= background_rate <= head <= 1.0c                P    | j                   kD  ry| j                  k\  ryS )Nr\   )rY   rS   )	span_inford   rc   rb   s    r   get_tail_sample_ratez?SamplingOptions.level_or_duration.<locals>.get_tail_sample_rate   s4    !-)2D2DGY2Y*y//Q""r    )r^   r_   )rg   rK   r7   rX   )r#   rX   r   
ValueError)clsr^   rb   rc   rd   head_sample_raterh   s     ```  r   level_or_durationz!SamplingOptions.level_or_duration   s`    $ $.dUCL#A4sA*:AcAdee Bdee	# #788r    )
r^   r]   rb   r8   rc   zfloat | Nonerd   rX   r7   r   )	r:   r;   r<   r=   r^   r>   r_   classmethodrl   r@   r    r   r[   r[      s    
  D/ <@D
8?	  !$,4+.!$9 9 *	9
 )9 9 
9 9r    r[   c                T    | t         j                  z  t        j                  |      k  S r"   )r   TRACE_ID_LIMITget_bound_for_rate)rH   rates     r   check_trace_id_ratiorr      s&    (777;L;_;_`d;eeer    c                  Z     e Zd ZdZd fdZd	d
 fdZd fdZddZddZd fdZ	 xZ
S )TailSamplingProcessorzYPasses spans to the wrapped processor if any span in a trace meets the sampling criteria.c                ^    t         |   |       || _        i | _        t	               | _        y r"   )super__init__rh   tracesr   lock)r   	processorrh   	__class__s      r   rw   zTailSamplingProcessor.__init__   s,    #$8! /1 F	r    c           	        d}d }| j                   5  |j                  r|j                  j                  }|j                  t	        g g       | j
                  |<   | j
                  j                  |      }|:|j                  j                  ||f       | j                  t        ||d|            }d d d        |t        | 1  ||       y |r| j                  |       y y # 1 sw Y   1xY w)NFstart)ry   r	   rH   parentrB   rx   r   rC   append
check_spanrK   rv   on_startpush_buffer)r   rL   parent_contextdroppedrO   rH   r{   s         r   r   zTailSamplingProcessor.on_start   s    YY||<<00;;&,7B,?DKK)2%NN))4*@A"oo.B4Y`bh.ijG $ >GT>2V$ ) Ys   BC!!C*c           	        d}d }| j                   5  |j                  r|j                  j                  }| j                  j	                  |      }|`|j
                  j                  |       | j                  t        |d d|            }|j                  | j                  j                  |d        d d d        |t        | 1  |       y |r| j                  |       y y # 1 sw Y   0xY w)NFend)ry   r	   rH   rx   r   rD   r   r   rK   r~   poprv   on_endr   )r   rL   r   rO   rH   r{   s        r   r   zTailSamplingProcessor.on_end   s     YY||<<002%LL''-"oo.B4uV\.]^G{{* $7  >GN4 V$  Ys   B C!!C*c                    | j                  |      }t        |j                  j                  |      x}r| j	                  |j                         |S )zbIf the span meets the sampling criteria, drop the buffer and return True. Otherwise, return False.)rh   rr   rO   rH   drop_buffer)r   rg   sample_ratesampleds       r   r   z TailSamplingProcessor.check_span	  sI    //	:*9+;+;+D+DkRR7RY--.r    c                2    | j                   |j                  = y r"   )rx   rH   )r   rO   s     r   r   z!TailSamplingProcessor.drop_buffer  s    KK(r    c                    |j                   D ]  }t        |   |   |j                  D ]  }t        |   |        y r"   )rC   rv   r   rD   r   )r   rO   rC   rL   r{   s       r   r   z!TailSamplingProcessor.push_buffer  s8    ~~GGg& &LLDGN4  !r    )rz   r   rh   z'Callable[[TailSamplingSpanInfo], float]r7   Noner"   )rL   r   r   rM   r7   r   )rL   r
   r7   r   )rg   rK   r7   bool)rO   rB   r7   r   )r:   r;   r<   r=   rw   r   r   r   r   r   __classcell__)r{   s   @r   rt   rt      s)    c%6%.)! !r    rt   N)rH   r   rq   rX   r7   r   )$
__future__r   dataclassesr   	functoolsr   	threadingr   typingr   r   opentelemetryr	   opentelemetry.sdk.tracer
   r   r    opentelemetry.sdk.trace.samplingr   r   typing_extensionsr   logfire._internal.constantsr   r   r   r   r   #logfire._internal.exporters.wrapperr   r   rB   rK   r[   rr   rt   r@   r    r   <module>r      s    " ! %  $ ! E E G "  E )3 )3 )3X % % %( $& $& $&N =9 =9 =9@f
Q!0 Q!r    