
    \j5                     ~   d dl m Z mZ d dlmZ d dlmZmZ d dl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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%m&Z& d dl'm(Z(m)Z) erd dlm+Z+m,Z,m-Z- d dl.m/Z0 d dl"m1Z1 d dl2m3Z3m4Z4 dZ5dZ6dZ7	 	 	 	 	 	 ddZ8 G d de      Z9y# e*$ r	  ed      w xY w)    )datetimetimezone)time)TYPE_CHECKINGcast)
get_clientstart_transaction)INSTRUMENTER
SPANSTATUS)DidNotEnable)SENTRY_BAGGAGE_KEYSENTRY_TRACE_KEYadd_global_event_processor)TransactionSpan)	parse_url)	get_value)SpanProcessorReadableSpan)SpanAttributes)format_span_idformat_trace_idget_current_spanSpanKind)INVALID_SPAN_IDINVALID_TRACE_IDzopentelemetry not installed)AnyOptionalUnion)context)SpanContext)EventHintotel
   z	auto.otelc                    t               }|j                  d   t        j                  k7  r| S t	        | d      r
| d   dk(  r| S t               }|s| S |j                         }|j                  t        k(  s|j                  t        k(  r| S |j                  t        |j                        d       }|s| S | j                  di       }|j                  di       j                  |j                                | S )Ninstrumentertypetransactioncontextstrace)r   optionsr
   OTELhasattrr   get_span_contexttrace_idr   span_idr   getr   
setdefaultupdateget_trace_context)eventotel_span_mapclient	otel_spanctxsentry_spanr+   s          ^/root/env/lib/python3.12/site-packages/sentry_sdk/integrations/opentelemetry/span_processor.py!link_trace_context_to_error_eventr>   -   s     \F~~n%):)::uf%-="@ "I

$
$
&C
||''3;;/+I##N3;;$?FK
B/H$++K,I,I,KLL    c                        e Zd ZU dZi Zded<   i Zded<   d fdZddZdd	Z		 d	 	 	 	 	 ddZ
ddZd
ddefdZddZ	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 ddZ	 	 	 	 	 	 ddZ	 	 	 	 	 	 ddZ xZS )SentrySpanProcessorzZ
    Converts OTel spans into Sentry spans so they can be sent to the Sentry backend.
    )dict[str, Union[Transaction, SentrySpan]]r8   zdict[int, set[str]]
open_spansreturnc                 \    t        | d      st        | 	  |       | _        | j                  S )Ninstance)r/   super__new__rF   )cls	__class__s    r=   rH   zSentrySpanProcessor.__new__V   s)    sJ' 7?3/CL ||r?   c                 $     t         d fd       }y )Nc                 0    t        | j                        S N)r>   r8   )r7   hintselfs     r=   global_event_processorz<SentrySpanProcessor.__init__.<locals>.global_event_processor^   s    4UD<N<NOOr?   )r7   r#   rN   r$   rD   r#   r   )rO   rP   s   ` r=   __init__zSentrySpanProcessor.__init__]   s    	#	P 
$	Pr?   c                 ~   t        t               dz        }t        | j                  j	                               D ]  }| j                  |   t               k(  r| j                  j                  |       9||z
  t        kD  sF| j                  j                  |      D ]  }| j                  j                  |d          y)z?
        Prune spans that have been open for too long.
        <   N)	intr   listrC   keyssetpopSPAN_MAX_TIME_OPEN_MINUTESr8   )rO   current_time_minutesspan_start_minutesr2   s       r=   _prune_old_spansz$SentrySpanProcessor._prune_old_spansb   s      #46B;/"&OO  "#
 
	: 12ce;##$67 &(::=WW#223EF :G&&**7D9:
	:r?   r:   OTelSpanc           
         t               }|j                  sy |j                  d   t        j                  k7  ry |j                         }||j                  sy | j                  |      ry | j                  ||j                  |      }|d   }|r| j                  j                  |      nd }d }|j                  1t        j                  |j                  dz  t        j                         }d }	|r6|j#                  |d   |j$                  |t        j                  t&              }	n8t)        |j$                  |d   ||d   |d   |t        j                  t&              }	|	| j                  |d   <   |j                  Qt+        |j                  dz  d	z        }
| j,                  j/                  |
t1                     j3                  |d          | j5                          y )
Nr(   parent_span_id    eAr2   )r2   namestart_timestampr(   originr1   baggage)ra   r2   r_   r1   rd   rb   r(   rc   rS   )r   
parsed_dsnr-   r
   r.   r0   is_valid_is_sentry_span_get_trace_dataparentr8   r3   
start_timer   fromtimestampr   utcstart_childra   SPAN_ORIGINr	   rT   rC   r4   rW   addr\   )rO   r:   parent_contextr9   span_context
trace_datar_   sentry_parent_spanrb   r<   span_start_in_minutess              r=   on_startzSentrySpanProcessor.on_starts   s   
   >>.)\->->> 113|'<'<	*)))**N

 $$456DD"">2$ 	 +&44$$s*HLLO ,88"9-^^ /).." 9 K ,^^"9--#J/"9- /).."	K 5@:i01+$'$$s*R/%! OO&&'<ceDHH9% 	r?   c                    t               }|j                  d   t        j                  k7  ry |j	                         }||j
                  sy t        |j                        }| j                  j                  |d       }|sy |j                  |_        | j                  ||       t        |t              rI|j                  |_
        |j                  t         | j#                  |             | j%                  ||       n| j'                  ||       d }|j(                  1t+        j,                  |j(                  dz  t.        j0                        }|j3                  |       |j4                  Nt7        |j4                  dz  dz        }| j8                  j;                  |t=                     j?                  |       | jA                          y )Nr(   r`   )end_timestamprS   )!r   r-   r
   r.   r0   rf   r   r2   r8   rX   ra   op_update_span_with_otel_status
isinstancer   set_contextOPEN_TELEMETRY_CONTEXT_get_otel_context"_update_transaction_with_otel_data_update_span_with_otel_dataend_timer   rk   r   rl   finishrj   rT   rC   r4   rW   discardr\   )rO   r:   r9   rq   r2   r<   rw   rt   s           r=   on_endzSentrySpanProcessor.on_end   s   >>.)\->->> 113|'<'< !5!56((,,Wd;"**;	Bk;/(~~K##&(>(>y(I 33KK ,,[)D)$22""S((,,M 	7+$'$$s*R/%! OO&&'<ceDLLWUr?   c                     d}|j                   )|j                   j                  t        j                        }t	        d|      }t               j                  }|r|j                  nd}|r|r||v ryy)zs
        Break infinite loop:
        HTTP requests to Sentry are caught by OTel and send again to Sentry.
        NOptional[str]TF)
attributesr3   r   HTTP_URLr   r   re   netloc)rO   r:   otel_span_urlre   dsn_urls        r=   rg   z#SentrySpanProcessor._is_sentry_span   sk    
 +%0044^5L5LMM_m<\,,
'1*##tWM)Ar?   c                     i }|j                   rt        |j                         |d<   |j                  j                   r"t        |j                  j                         |d<   |S )z
        Returns the OTel context for Sentry.
        See: https://develop.sentry.dev/sdk/performance/opentelemetry/#step-5-add-opentelemetry-context
        r   resource)r   dictr   )rO   r:   r;   s      r=   r}   z%SentrySpanProcessor._get_otel_context   sU    
  $Y%9%9 :C(("9#5#5#@#@AC
O
r?   c                 (   i }t        |j                        }||d<   t        |j                        }||d<   |rt        |j                        nd}||d<   t	        t
        |      }t        d|      }|r|d   nd|d<   t	        t        |      }	|	|d<   |S )zh
        Extracts tracing information from one OTel span's context and its parent OTel context.
        r2   r1   Nr_   z!dict[str, Union[str, bool, None]]parent_sampledrd   )r   r2   r   r1   r   r   r   r   )
rO   rq   parent_span_contextrp   rr   r2   r1   r_   sentry_trace_datard   s
             r=   rh   z#SentrySpanProcessor._get_trace_data  s     (*
 !5!56 '
9"<#8#89!)
: <ON.667TX 	 (6
#$%&6G !DFWX3D./$ 	#$ .? '
9r?   c                     |j                   j                  ry|j                   j                  r |j                  t        j
                         y|j                  t        j                         y)z?
        Set the Sentry span status from the OTel span
        N)statusis_unsetis_ok
set_statusr   OKINTERNAL_ERROR)rO   r<   r:   s      r=   ry   z1SentrySpanProcessor._update_span_with_otel_status&  sN     $$!!"":==1z889r?   c                    |j                  d|j                         |j                  }|j                  }|j                  r|j                  j	                         D ]  \  }}|j                  ||        |j                  j                  t        j                        }t        d|      }|j                  j                  t        j                        }|rd}|j                  t        j                  k(  r|dz  }n"|j                  t        j                  k(  r|dz  }|}|j                  j                  t        j                  d      }	|	r|dj                  |	      z  }|j                  j                  t        j                  d      }
|
r|dj                  |
      z  }|	s|
s|j                  j                  t        j                   d      }t        d|      }|rPt#        |      }dj                  |j$                  |j&                  |j(                        }|dj                  |      z  }|j                  j                  t        j*                  d      }t        d	|      }|rP|j-                  |       n>|r<d
}|j                  j                  t        j.                  d      }t        d|      }|r|}||_        ||_        y)z
        Convert OTel span data and update the Sentry span with it.
        This should eventually happen on the server when ingesting the spans.
        z	otel.kindNr   http.server.clientz {}z	{}://{}{}Optional[int]db)set_datakindra   r   itemsr3   r   HTTP_METHODr   	DB_SYSTEMr   SERVERCLIENTNET_PEER_NAMEformatHTTP_TARGETr   urlparseschemer   pathHTTP_STATUS_CODEset_http_statusDB_STATEMENTrx   description)rO   r<   r:   rx   r   keyvalhttp_methoddb_query	peer_nametargeturl
parsed_urlstatus_code	statements                  r=   r   z/SentrySpanProcessor._update_span_with_otel_data5  sW    	[)..9^^nn+%00668 /S$$S#./ $..22>3M3MNK<K ++//0H0HIH>>X__4)OB^^x6)OB)%0044^5Q5QSWX	5<<	#::K"--11.2L2LdS5<<#77K #..22>3J3JDQC4C%-c]
)00&--z/@/@*// $u||C'88'2266"33T #?K@//<%0044^5P5PRVW	 )<	"+K"-r?   c                    |j                   y |j                   j                  t        j                        }|r|j                   j                  t        j                        }t        d|      }|r|j                  |       d}|j                  t        j                  k(  r|dz  }n"|j                  t        j                  k(  r|dz  }||_        y y )Nr   r   r   r   )r   r3   r   r   r   r   r   r   r   r   r   rx   )rO   r<   r:   r   r   rx   s         r=   r~   z6SentrySpanProcessor._update_transaction_with_otel_dataw  s     '**..~/I/IJ#..22>3R3RSK<K++K8B~~0i8??2iKN r?   )rD   rA   )rD   N)rO   rA   rD   NrM   )r:   r]   rp   Optional[context_api.Context]rD   N)r:   r]   rD   N)r:   r]   rD   dict[str, Any])rq   r"   r   zOptional[SpanContext]rp   r   rD   r   )r<   
SentrySpanr:   r]   rD   N)__name__
__module____qualname____doc__r8   __annotations__rC   rH   rQ   r\   ru   r   boolrg   r}   rh   ry   r   r~   __classcell__)rJ   s   @r=   rA   rA   K   s   
 BDM>C )+J%*P
:( ;?B B  8B  
	B H+ Z  $# 5 8	
 
B:':4>:	:@.'@.4>@.	@.D ' 4> 	 r?   rA   N)r7   r#   r8   rB   rD   r#   ):r   r   r   typingr   r   
sentry_sdkr   r	   sentry_sdk.constsr
   r   sentry_sdk.integrationsr   ,sentry_sdk.integrations.opentelemetry.constsr   r   sentry_sdk.scoper   sentry_sdk.tracingr   r   r   urllib3.utilr   r   opentelemetry.contextr   opentelemetry.sdk.tracer   r   r]   opentelemetry.semconv.tracer   opentelemetry.tracer   r   r   r   opentelemetry.trace.spanr   r   ImportErrorr   r   r    opentelemetryr!   context_apir"   sentry_sdk._typesr#   r$   r|   rY   rn   r>   rA    r?   r=   <module>r      s    '  & 4 6 0 8 > .6/O:  ++4/-  #N<A - A Y  6
4
556s   
(B. .B<