o
    io                     @   s  d dl mZ d dl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 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.m0Z0 d d$l.m1Z1 d d%l2m3Z4 d d&l2m5Z6 d d'l2m7Z8 d d(l2m9Z9 d d)l2m:Z: d d*l2m;Z; d d+l<m=Z= d d,l>m?Z? d d-l>m@Z@ d d.lAmBZB d d/lCmDZD G d0d1 d1e@ZEe=eFZGd2eHd3eHfd4d5ZId2eHd3eJfd6d7ZKG d8d9 d9e?ZLdS ):    )StringION)TracebackType)Any)Callable)Optional)Text)Union)cast)MAX_SPAN_META_VALUE_LEN)SpanLink)SpanLinkKind)_SpanPointer)_SpanPointerDirection)Context)_AttributeValueType)_SAMPLING_AGENT_DECISION)_SAMPLING_LIMIT_DECISION)_SAMPLING_RULE_DECISION)_SPAN_MEASURED_KEY)	ERROR_MSG)ERROR_STACK)
ERROR_TYPE)MANUAL_DROP_KEY)MANUAL_KEEP_KEY)SERVICE_KEY)SERVICE_VERSION_KEY)	USER_KEEP)USER_REJECT)VERSION_KEY)http)net)core)NumericType)ensure_text)
is_integer)MAX_INT_64BITS)MAX_UINT_64BITS)MIN_INT_64BITS)SAMPLING_DECISION_TRACE_TAG_KEY)SPAN_API_DATADOG)SamplingMechanism)
get_logger)SpanData)SpanEventData)config)Timec                       s`   e Zd Zg dZ		ddedeeeef  dee f fddZ	dd	 Z
d
d Zdd Z  ZS )	SpanEvent)name
attributestime_unix_nanoNr1   r2   r3   c                    sD   t  ||| || _|d u rt }|| _|r|| _d S i | _d S N)super__init__r1   r/   time_nsr3   r2   )selfr1   r2   r3   	__class__ G/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/_trace/span.pyr6   8   s   zSpanEvent.__init__c                 C   s"   | j | jd}| jr| j|d< |S )N)r1   r3   r2   r1   r3   r2   )r8   dr;   r;   r<   __dict__E   s   
zSpanEvent.__dict__c                 C   s   d| j  d| j d| j dS )z~
        Stringify and return value.
        Attribute value can be either str, bool, int, float, or a list of these.
        zSpanEvent(name='z', time=z, attributes=)r=   r8   r;   r;   r<   __repr__K   s   zSpanEvent.__repr__c                 c   s4    d| j fV  d| jfV  | jrd| jfV  d S d S )Nr1   r3   r2   r=   rA   r;   r;   r<   __iter__R   s   zSpanEvent.__iter__NN)__name__
__module____qualname__	__slots__strr   dictr   intr6   r?   rB   rC   __classcell__r;   r;   r9   r<   r0   5   s    r0   	large_intreturnc                 C   s   t | @ S )z2Get the 64 lowest order bits from a 128bit integer)_MAX_UINT_64BITSrM   r;   r;   r<    _get_64_lowest_order_bits_as_int\      rQ   c                 C   s   | ddd S )z3Get the 64 highest order bits from a 128bit integer032xN   r;   rP   r;   r;   r<   !_get_64_highest_order_bits_as_hexa   s   rU   c                   @   s  e Zd Zg dZdddddddddedfdedee dee dee dee dee d	ee d
ee dee dee	e
d gdf   dedee	e  ddfddZdddZdee ddfddZdededdfddZdeeef ddfddZdedee fddZdd ee ddfd!d"Zd#eddfd$d%Zd&ee fd'd(Zd)edee fd*d+Zdded,ee ddfd-d.Zded,eeef ddfd/d0Zdedeeeef  fd1d2Zded,eddfd3d4Z dedee fd5d6Z!deeef fd7d8Z"d9eeef ddfd:d;Z#ded,eddfd<d=Z$d>eeef ddfd?d@Z%dedee fdAdBZ&	ddedCeeee'f  dDee ddfdEdFZ(dGe
d gdf fdHdIZ)deeef fdJdKZ*ddLee fdMdNZ+	ddOee, dPe,dQee- dLee def
dRdSZ.	ddOee, dPe,dQee- dLee ddf
dTdUZ/	ddVe,dCeeee'f  ddfdWdXZ0ded,e1de2fdYdZZ3ded,e4e2eeef de2fd[d\Z5e6dd]d^Z7e7j8dd_d^Z7e7j9dd`d^Z7e6ddadbZ:e:j8ddddbZ:e:j9ddedbZ:ddedCeeeef  ddfdfdgZ;			ddededhee diee dCeeeef  ddfdjdkZ<	ddledme=dnedoeeeef  ddf
dpdqZ>dre4ee?f ddfdsdtZ@ddudvZAddwdxZBdOeee,  dPee, dQee- ddfdydzZCdefd{d|ZDdefd}d~ZEe6de2fddZFdS )Span)_meta_meta_structcontext_metrics_store_parent_context_local_root_value_service_entry_span_value_parent_ignored_exceptions_on_finish_callbacks_links_events__weakref__Nr1   serviceresource	span_typetrace_idspan_id	parent_idstartrY   	on_finishspan_apilinksrN   c                 C   s   i | _ i | _i | _|
du rg n|
| _|	| _| j}| j}|	r#|	||nt||dd| _	g | _
|r:|D ]}| | q2g | _d| _d| _d| _d| _d| _dS )a  
        Create a new span. Call `finish` once the traced operation is over.

        **Note:** A ``Span`` should only be accessed or modified in the process
        that it was created in. Using a ``Span`` from within a child process
        could result in a deadlock or unexpected behavior.

        :param str name: the name of the traced operation.

        :param str service: the service name
        :param str resource: the resource name
        :param str span_type: the span type

        :param int trace_id: the id of this trace's root span.
        :param int parent_id: the id of this span's direct parent span.
        :param int span_id: the id of this span.

        :param int start: the start time of request as a unix epoch in seconds
        :param object context: the Context of the span.
        :param on_finish: list of functions called when the span finishes.
        NF)rh   ri   	is_remote)rW   rZ   rX   ra   r\   rh   ri   copyr   rY   rb   _set_link_or_append_pointerrc   r_   r`   r]   r^   r[   )r8   r1   re   rf   rg   rh   ri   rj   rk   rY   rl   rm   rn   	_trace_id_span_idnew_linkr;   r;   r<   r6   z   s*   $
zSpan.__init__c                 C   st   | j - | j jD ]}| j|| j j|  q| j jD ]}| j|| j j|  qW d    d S 1 s3w   Y  d S r4   )rY   rW   
setdefaultrZ   )r8   tagmetricr;   r;   r<   _update_tags_from_context   s   "zSpan._update_tags_from_contextexcc                 C   s&   | j d u r|g| _ d S | j | d S r4   )r`   append)r8   ry   r;   r;   r<   _ignore_exception   s   
zSpan._ignore_exceptionkeyvalc                 C   s   | j si | _ || j |< d S r4   )r[   )r8   r|   r}   r;   r;   r<   _set_ctx_item   s   zSpan._set_ctx_itemitemsc                 C   s   | j si | _ | j | d S r4   )r[   update)r8   r   r;   r;   r<   _set_ctx_items   s   zSpan._set_ctx_itemsc                 C   s   | j sd S | j |S r4   )r[   getr8   r|   r;   r;   r<   _get_ctx_item   s   zSpan._get_ctx_itemfinish_timec                 C   s0   |du r|  t  dS |  t|d  dS )zMark the end time of the span and submit it to the tracer.
        If the span has already been finished don't do anything.

        :param finish_time: The end time of the span, in seconds. Defaults to ``now``.
        Ng    eA)
_finish_nsr/   r7   rK   )r8   r   r;   r;   r<   finish   s   zSpan.finishfinish_time_nsc                 C   s6   | j d urd S || jp| | _ | jD ]}||  qd S r4   )duration_nsstart_nsra   )r8   r   cbr;   r;   r<   r      s   


zSpan._finish_nsdecisionc                 C   sH   || j _| tj | jr tttfD ]}|| jj	v r| jj	|= qd S d S r4   )
rY   sampling_priority_set_sampling_decision_makerr*   MANUAL_local_rootr   r   r   rZ   )r8   r   r|   r;   r;   r<   _override_sampling_decision   s   
z Span._override_sampling_decisionsampling_mechanismc                 C   s   d| }|| j jt< |S )Nz-%d)rY   rW   r(   )r8   r   valuer;   r;   r<   r      s   z!Span._set_sampling_decision_makerr   c              	   C   s`  |t jkr	t|}t|}tjf}||v r+|s+zt|}d}W n ttfy*   Y nw |dur?|r?t	|dkr?| 
|| dS t|trL| 
|| dS |tkrW| t dS |tkrb| t dS |tkrj|| _n|tkru| t| n|tkr|du rd}| 
|| dS zt|| j|< || jv r| j|= W dS W dS  ty   tjd|dd Y dS w )a  Set a tag key/value pair on the span.

        Keys must be strings, values must be ``str``-able.

        :param key: Key to use for the tag
        :type key: str
        :param value: Value to assign for the tag
        :type value: ``str``-able value
        TNl             z!error setting tag %s, ignoring itexc_info)r   STATUS_CODErI   r$   r    TARGET_PORTrK   
ValueError	TypeErrorabs
set_metric
isinstancefloatr   r   r   r   r   r   re   r   set_tagr   r   rW   rZ   	Exceptionlogwarning)r8   r|   r   val_is_an_int	INT_TYPESr;   r;   r<   r      sP   




zSpan.set_tagc                 C   s   || j |< dS )z~
        Set a tag key/value pair on the span meta_struct
        Currently it will only be exported with V4 encoding
        N)rX   r8   r|   r   r;   r;   r<   _set_struct_tag>  s   zSpan._set_struct_tagc                 C      | j |dS )z4Return the given struct or None if it doesn't exist.N)rX   r   r   r;   r;   r<   _get_struct_tagE     zSpan._get_struct_tagc              
   C   sZ   zt |dd| j|< W dS  ty, } ztjr|tjd|dd W Y d}~dS d}~ww )zSet a value for a tag. Values are coerced to unicode in Python 2 and
        str in Python 3, with decoding errors in conversion being replaced with
        U+FFFD.
        replace)errorszFailed to set text tag '%s'Tr   N)r#   rW   r   r.   _raiser   r   )r8   r|   r   er;   r;   r<   _set_tag_strI  s   zSpan._set_tag_strc                 C   r   )z1Return the given tag or None if it doesn't exist.N)rW   r   r   r;   r;   r<   get_tagU  r   zSpan.get_tagc                 C   
   | j  S )zReturn all tags.)rW   rp   rA   r;   r;   r<   get_tagsY     
zSpan.get_tagstagsc                 C   s.   |rt | D ]\}}| || qdS dS )zlSet a dictionary of tags on the given span. Keys and values
        must be strings (or stringable)
        N)iterr   r   )r8   r   kvr;   r;   r<   set_tags]  s
   zSpan.set_tagsc              	   C   s   |t kr ztt|}W n ttfy   td|| Y dS w t|ttfsAzt|}W n ttfy@   t	d|| Y dS w t
|sKt
|rTt	d|| dS || jv r]| j|= || j|< dS )z7This method sets a numeric tag value for the given key.z.failed to convert %r tag to an integer from %rNz ignoring not number metric %s:%szignoring not real metric %s:%s)r   rK   boolr   r   r   r   r   r   debugmathisnanisinfrW   rZ   r   r;   r;   r<   r   e  s(   
zSpan.set_metricmetricsc                 C   s*   |r|  D ]\}}| || qdS dS )zSet a dictionary of metrics on the given span. Keys must be
        must be strings (or stringable). Values must be numeric.
        N)r   r   )r8   r   r   r   r;   r;   r<   set_metrics  s
   zSpan.set_metricsc                 C   s   | j |S )z4Return the given metric or None if it doesn't exist.)rZ   r   r   r;   r;   r<   
get_metric  s   zSpan.get_metricr2   	timestampc                 C   s   | j t||| d S r4   )rc   rz   r0   )r8   r1   r2   r   r;   r;   r<   
_add_event  s   zSpan._add_eventcallbackc                 C   s   | j d| dS )zEAdd an errortracking related callback to the on_finish_callback arrayr   N)ra   insert)r8   r   r;   r;   r<   !_add_on_finish_exception_callback  s   z&Span._add_on_finish_exception_callbackc                 C   r   )zReturn all metrics.)rZ   rp   rA   r;   r;   r<   get_metrics  r   zSpan.get_metricslimitc                 C   sx   t  \}}}|r|r|r|rt| }| j||||d dS |du r&tj}dtj|d ddd }|| j	t
< dS )zIf the current stack has an exception, tag the span with the
        relevant error info. If not, tag it with the current python stack.
        r   N r   )sysr   r   set_exc_infor.   _span_traceback_max_sizejoin	tracebackformat_stackrW   r   )r8   r   exc_typeexc_valexc_tbtbr;   r;   r<   set_traceback  s   
zSpan.set_tracebackr   r   r   c                 C   s   |du rt j}t| }t }tj|||||d | }t|tkrJt|dkrJ|d }t }tj|||||d | }t|tkrJt|dks)|S )a  
        Return a formatted traceback as a string.
        If the traceback is too long, it will be truncated to the limit parameter,
        but from the end of the traceback (keeping the most recent frames).

        If the traceback surpasses the MAX_SPAN_META_VALUE_LEN limit, it will
        try to reduce the traceback size by half until it fits
        within this limit (limit for tag values).

        :param exc_type: the exception type
        :param exc_val: the exception value
        :param exc_tb: the exception traceback
        :param limit: the maximum number of frames to keep
        :return: the formatted traceback as a string
        N)filer   r      )	r.   r   r   r   r   print_exceptiongetvaluelenr
   )r8   r   r   r   r   buffr   r;   r;   r<   _get_traceback  s   
zSpan._get_tracebackc                    s    r|r|sdS t  trtt|jdkrdS | jr(t fdd| jD r(dS d| _| j |||d}d j j	f }|| j
t< z	t|| j
t< W n tya   |r_t|dr_|jj	| j
t< Y nw || j
t< td	| f td
|  ||f dS )z:Tag the span with an error tuple as from `sys.exc_info()`.Nr   c                    s   g | ]}t  |qS r;   )
issubclass).0r   r   r;   r<   
<listcomp>  s    z%Span.set_exc_info.<locals>.<listcomp>r   r   %s.%sr:   zweb.request.final_tagszspan.exception)r   
SystemExitr	   coder`   anyerrorr   rF   rE   rW   r   rI   r   r   hasattrr:   r   r!   dispatch)r8   r   r   r   r   r   exc_type_strr;   r   r<   r     s(   

zSpan.set_exc_info	exceptionc                    sp     t|||j}d|jj|jjf t||d}|r, fdd| D }||  j	d|t
 d dS )a  
        Records an exception as a span event. Multiple exceptions can be recorded on a span.

        :param exception: The exception to record.
        :param attributes: Optional dictionary of additional attributes to add to the exception event.
            These attributes will override the default exception attributes if they contain the same keys.
            Valid attribute values include (homogeneous array of) strings, booleans, integers, floats.
        r   )zexception.typezexception.messagezexception.stacktracec                    s"   i | ]\}}  ||r||qS r;   )_validate_attributer   r   r   rA   r;   r<   
<dictcomp>  s   " z)Span.record_exception.<locals>.<dictcomp>r   )r1   r2   r   N)r   type__traceback__r:   rF   rE   rI   r   r   r   r/   r7   )r8   r   r2   r   attrsr;   rA   r<   record_exception  s   
zSpan.record_exceptionc                 C   s   t |ttttfr| ||S t |tstd|| dS t	|dkr%dS t |d ttttfs9td|| dS t
|d }|D ]}t ||rN| ||sXtd||  dS qAdS )NzHrecord_exception: Attribute %s must be a string, number, or boolean: %s.Fr   TzHrecord_exception: List values %s must be string, number, or boolean: %s.z=record_exception: Attribute %s array must be homogeneous: %s.)r   rI   r   rK   r   _validate_scalarlistr   r   r   r   )r8   r|   r   
first_typer}   r;   r;   r<   r     s"   
zSpan._validate_attributec                 C   sp   t |ttfr	dS t |tr!|tk s|tkrtd|| dS dS t |tr6t	
|s4td|| dS dS dS )NTzWrecord_exception: Attribute %s must be within the range of a signed 64-bit integer: %s.Fz;record_exception: Attribute %s must be a finite number: %s.)r   r   rI   rK   _MIN_INT_64BITS_MAX_INT_64BITSr   r   r   r   isfiniter   r;   r;   r<   r   4  s"   


zSpan._validate_scalarc                 C   
   | j p| S r4   r]   rA   r;   r;   r<   r   J  r   zSpan._local_rootc                 C   s   || ur	|| _ d S d | _ d S r4   r   )r8   r   r;   r;   r<   r   N     c                 C      | ` d S r4   r   rA   r;   r;   r<   r   R  rR   c                 C   r   r4   r^   rA   r;   r;   r<   _service_entry_spanV  r   zSpan._service_entry_spanspanc                 C   s   || u r	d | _ d S || _ d S r4   r   r8   r   r;   r;   r<   r   Z  r   c                 C   r   r4   r   rA   r;   r;   r<   r   ^  rR   c                 C   sp   |j r|jsd|j  d|j }tjrt|t| |j r4|jr6| j|j |j|jt	|j
|d dS dS dS )z/Defines a causal relationship between two spansz#Invalid span or trace id. trace_id:z	 span_id:rh   ri   
tracestateflagsr2   N)rh   ri   r.   r   r   r   r   set_link_tracestaterK   _traceflags)r8   rY   r2   msgr;   r;   r<   	link_spanb  s   

zSpan.link_spanr   r   c              	   C   s*   |d u rt  }| t|||||d d S )Nr   )rJ   rq   r   )r8   rh   ri   r   r   r2   r;   r;   r<   r  t  s   zSpan.set_linkpointer_kindpointer_directionpointer_hashextra_attributesc                 C   s   |  t||||d d S )N)r  r  r  r	  )rq   r   )r8   r  r  r  r	  r;   r;   r<   _add_span_pointer  s   	zSpan._add_span_pointerlinkc                 C   s   |j tjjkr| j| d S z#dd | jD |j}t	d| j|jt
| j|  || j|< W d S  tyB   | j| Y d S w )Nc                 S   s   g | ]}|j qS r;   )ri   )r   r  r;   r;   r<   r     s    z4Span._set_link_or_append_pointer.<locals>.<listcomp>z@Span %d already linked to span %d. Overwriting existing link: %s)kindr   SPAN_POINTERr   rb   rz   indexri   r   r   rI   r   )r8   r  #existing_link_idx_with_same_span_idr;   r;   r<   rq     s   z Span._set_link_or_append_pointerc                 C   s*   | }|dur|   |j}|dusdS dS )zFinish this span along with all (accessible) ancestors of this span.

        This method is useful if a sudden program shutdown is required and finishing
        the trace is desired.
        N)r   r_   r   r;   r;   r<   _finish_with_ancestors  s
   zSpan._finish_with_ancestorsc                 C   s   | S r4   r;   rA   r;   r;   r<   	__enter__  s   zSpan.__enter__c                 C   s@   z|r
|  ||| |   W d S  ty   td Y d S w )Nzerror closing trace)r   r   r   r   r   )r8   r   r   r   r;   r;   r<   __exit__  s   zSpan.__exit__c                 C   s  dd | j  D }dg d| j d| j d| j d| j d| j d	| j d
| j	 d| j
 d| joJ| j
oJ| j
| j  d| j d| j d| j d| j d| j d| j d| j d| jj d| S )z2Return a detailed string representation of a span.c                 S   s6   i | ]\}}|t |tr| nd t|j dqS )zwrong type [])r   rJ   keysr   rE   r   r;   r;   r<   r     s    $z!Span.__repr__.<locals>.<dictcomp>r   zSpan(name='z', span_id=z, parent_id=z, trace_id=z, service='z', resource='z	', type='z	', start=z, end=z, duration=z, error=z, tags=z
, metrics=z, links=z	, events=z
, context=z, service_entry_span_name=z), metastruct=)rX   r   r   r1   ri   rj   rh   re   rf   rg   r   r   r   rW   rZ   rb   rc   rY   r   )r8   metar;   r;   r<   rB     sN   	
zSpan.__repr__c                 C   s   d| j | j| j| jf S )z1Return a concise string representation of a span.z.<Span(id=%s,trace_id=%s,parent_id=%s,name=%s)>)ri   rh   rj   r1   rA   r;   r;   r<   __str__  s   zSpan.__str__c                 C   s,   | j | u p| jduo| jj| jko| jduS )zReturn whether the span is a "top level" span.

        Top level meaning the root of the trace or a child span
        whose service is different from its parent.
        N)r   r_   re   rA   r;   r;   r<   _is_top_level  s   
 zSpan._is_top_level)rN   Nr4   rD   )rN   rV   )r   rV   rN   N)r   rV   rN   N)NNN)GrE   rF   rG   rH   r)   rI   r   rK   r   r   r   r   r6   rx   r   r   r{   r   r~   rJ   r   r   r   r   r   r"   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   BaseExceptionr   r   r   r   objectr   r   r   r   propertyr   setterdeleterr   r  r  r   r
  r   rq   r  r  r  rB   r  r  r;   r;   r;   r<   rV   f   sN   	



A

B

1
-
"$





	rV   )Mior   r   r   r   typesr   typingr   r   r   r   r   r	   ddtrace._trace._limitsr
   ddtrace._trace._span_linkr   r   ddtrace._trace._span_pointerr   r   ddtrace._trace.contextr   ddtrace._trace.typesr   ddtrace.constantsr   r   r   r   r   r   r   r   r   r   r   r   r   r   ddtrace.extr   r    ddtrace.internalr!   ddtrace.internal.compatr"   r#   r$   ddtrace.internal.constantsr%   r   r&   rO   r'   r   r(   r)   r*   ddtrace.internal.loggerr+   ddtrace.internal.native._nativer,   r-   !ddtrace.internal.settings._configr.   ddtrace.internal.utils.timer/   r0   rE   r   rK   rQ   rI   rU   rV   r;   r;   r;   r<   <module>   sl    $