
    \jW                        U d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dl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 d dlmZmZ d dlmZmZmZmZmZ d d	lmZ erad 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)m*Z* d dlm+Z+m,Z,m-Z-m.Z.m/Z/m0Z0  e'de1e.e2d      Z3	 d dl4m5Z5 d dl6m7Z8 e8Z7de9d<    e5dd      Z:da=de9d<   d d!d"d#d$d%d&e>fd'Z?d&e>fd(Z@dAd)ZAdBd*ZBdAd+ZCdAd,ZDdAd-ZEdAd.ZFdAd/ZGdCd0ZHd1d2d&e>fd3ZI G d4 d5      ZJ G d6 d7      ZK G d8 d9eK      ZL G d: d;eK      ZMd<ZN G d= d>      ZO G d? d@      ZPy# e;$ r ejx                  Z:dZ7Y w xY w)D    N)deque)datetimetimezone)VERSION)Envelope)LRUCache)DEFAULT_SAMPLING_FREQUENCYextract_stack)capture_internal_exception	is_geventloggernowset_in_app_in_frames)TYPE_CHECKING)Any)Callable)Deque)Dict)List)Optional)Set)Type)Union)	TypedDict)ContinuousProfilerModeSDKInfo)ExtractedSampleFrameIdStackIdThreadIdProcessedFrameProcessedStackProcessedSample	timestamp	thread_idstack_id)get_original)
ThreadPoolzOptional[Type[_ThreadPool]]r)   timesleepzOptional[ContinuousScheduler]
_scheduleroptionsDict[str, Any]sdk_infor   capture_funcCallable[[Envelope], None]returnc                    t         d u}|rt        j                  d       t                t	               rt
        j                  }nt        j                  }| j                  d      | d   }n'| j                  di       }|j                  d      xs |}t        }|t        j                  k(  rt        || ||      a n<|t
        j                  k(  rt        || ||      a nt        dj                  |            t        j                  dj                  t         j                               |st        j                  t               y)	Nz0[Profiling] Continuous Profiler is already setupprofiler_mode_experimentscontinuous_profiling_modez$Unknown continuous profiler mode: {}z9[Profiling] Setting up continuous profiler in {mode} mode)modeT)r,   r   debugteardown_continuous_profilerr   GeventContinuousSchedulerr7   ThreadContinuousSchedulergetr	   
ValueErrorformatatexitregister)r-   r/   r0   already_initializeddefault_profiler_moder4   experiments	frequencys           Q/root/env/lib/python3.12/site-packages/sentry_sdk/profiler/continuous_profiler.pysetup_continuous_profilerrF   J   s+    %D0GH$&{
 !: > > 9 > >{{?#/0 kk."5 OO78Q<Q 	 +I1666.w,

 
388	8.w,

 ?FF}UVV
LLCJJ 	K 	
 45    c                  0    t         yt         j                  S NF)r,   sampled rG   rE   is_profile_session_sampledrL      s    rG   c                  d    t         y t         j                         sy t         j                          y N)r,   is_auto_start_enabledmanual_startrK   rG   rE   !try_autostart_continuous_profilerrQ      s(     ++-rG   c                  8    t         y t         j                         S rN   )r,   
auto_startrK   rG   rE   !try_profile_lifecycle_trace_startrT      s      ""rG   c                  :    t         y t         j                          y rN   )r,   rP   rK   rG   rE   start_profilerrV      s    rG   c                  P    t        j                  dt        d       t                y )NzWThe `start_profile_session` function is deprecated. Please use `start_profile` instead.   
stacklevel)warningswarnDeprecationWarningrV   rK   rG   rE   start_profile_sessionr^      s    MMa
 rG   c                  :    t         y t         j                          y rN   )r,   manual_stoprK   rG   rE   stop_profilerra      s    rG   c                  P    t        j                  dt        d       t                y )NzUThe `stop_profile_session` function is deprecated. Please use `stop_profile` instead.rX   rY   )r[   r\   r]   ra   rK   rG   rE   stop_profile_sessionrc      s    MM_
 OrG   c                      t                d ay rN   )ra   r,   rK   rG   rE   r9   r9      s    O JrG   c                  0    t         y t         j                  S rN   )r,   profiler_idrK   rG   rE   get_profiler_idrg      s    !!!rG   sample_ratezUnion[float, None]c                 H    | syt        j                          t        |       k  S rI   )randomfloat)rh   s    rE   +determine_profile_session_sampling_decisionrl      s      ==?U;///rG   c                   $    e Zd ZU dZeed<   ddZy)ContinuousProfileTactiveNc                     d| _         y rI   )ro   selfs    rE   stopzContinuousProfile.stop   s	    rG   r2   N)__name__
__module____qualname__ro   bool__annotations__rs   rK   rG   rE   rn   rn      s    FDrG   rn   c            
           e Zd ZU dZded<   deddddd	d
ddf
dZdefdZddZ	ddZ
ddZddZddZddZddZedd       ZddZddZy)ContinuousSchedulerunknownr   r7   rD   r-   r.   r/   r   r0   r1   r2   Nc                 z   d|z  | _         || _        || _        || _        | j                  j	                  d      | _        | j                  j	                  d      }t        |      | _        | j                         | _	        d | _
        d | _        d| _        d| _        t        d      | _        t!               | _        y )Ng      ?profile_lifecycleprofile_session_sample_rateF   )maxlen)intervalr-   r/   r0   r<   	lifecyclerl   rJ   make_samplersamplerbufferpidrunningsoft_shutdownr   new_profilessetactive_profiles)rr   rD   r-   r/   r0   r   s         rE   __init__zContinuousScheduler.__init__   s     i ())*=>&*ll&6&67T&U#B'
 ((*15$("8=S8I9<rG   c                     | j                   t        j                         k(  ry| j                  j	                  d      }|sy|j	                  d      S )NFr5   continuous_profiling_auto_start)r   osgetpidr-   r<   )rr   rC   s     rE   rO   z)ContinuousScheduler.is_auto_start_enabled   sC     88ryy{"ll&&~6@AArG   c                     | j                   sy | j                  dk7  ry t        j                  d       t	               }| j
                  j                  |       | j                          |S )Ntracez"[Profiling] Auto starting profiler)rJ   r   r   r8   rn   r   appendensure_running)rr   profiles     rE   rS   zContinuousScheduler.auto_start  sU    ||>>W$9:#%  )rG   c                 ^    | j                   sy | j                  dk7  ry | j                          y Nmanual)rJ   r   r   rq   s    rE   rP   z ContinuousScheduler.manual_start  s'    ||>>X%rG   c                 D    | j                   dk7  ry | j                          y r   )r   teardownrq   s    rE   r`   zContinuousScheduler.manual_stop!  s    >>X%rG   c                     t         rN   NotImplementedErrorrq   s    rE   r   z"ContinuousScheduler.ensure_running'      !!rG   c                     t         rN   r   rq   s    rE   r   zContinuousScheduler.teardown*  r   rG   c                     t         rN   r   rq   s    rE   pausezContinuousScheduler.pause-  r   rG   c                 n    t        | j                  | j                  t        | j                        | _        y rN   )ProfileBufferr-   r/   PROFILE_BUFFER_SECONDSr0   r   rq   s    rE   reset_bufferz ContinuousScheduler.reset_buffer0  s&    #LL$--)?ARAR
rG   c                 `    | j                   r| j                  y | j                  j                  S rN   )r   r   rf   rq   s    rE   rf   zContinuousScheduler.profiler_id5  s%    ||t{{2{{&&&rG   c                      t        j                         t        d       j                  dk(  rdddddt        f fd}|S dddddt        f fd	}|S )
N   )max_sizer   argsr   kwargsr2   c            
         j                   sj                  syt        j                         }t               }	 t	        j
                         j                         D cg c]  \  }}t        |      t        |
      f }}}t        |      D ]5  }j                  j                  j                   j                                7 g }j                  D ]   }	|	j                  r|j!                  |	       " |D ]  }	j                  j#                  |	        j$                  j$                  j'                  ||       yc c}}w # t        $ r  t        t	        j                                Y yw xY w)
                Take a sample of the stack on all the threads in the process.
                This should be called at a regular interval to collect samples.
                TF)r   r   lenr   sys_current_framesitemsstrr
   AttributeErrorr   exc_inforangeaddpopleftro   r   remover   write)r   r   r   tstidframesample_inactive_profilesr   cachecwdrr   s             rE   _sample_stackz7ContinuousScheduler.make_sampler.<locals>._sample_stackB  s]    ((1E1E  #4#4#45U	! +.*=*=*?*E*E*G&C S=s#CDF ( |, JA((,,T->->-F-F-HIJ$&!#33 :G">>
 *009:  1 9G((//89 ;;*KK%%b&1M & ! /s||~> 	!s#   %E
  "EE
 E
 
&E32E3c            
      d   t               }	 t        j                         j                         D cg c]  \  }}t	        |      t        |      f }}}j                  j                  j                  ||       yc c}}w # t        $ r  t        t        j                                Y yw xY w)r   F)r   r   r   r   r   r
   r   r   r   r   r   )	r   r   r   r   r   r   r   r   rr   s	         rE   r   z7ContinuousScheduler.make_sampler.<locals>._sample_stack  s     U	! +.*=*=*?*E*E*G&C S=s#CDF  ;;*KK%%b&1 & ! /s||~> 	!s"   %B "B B  B &B/.B/)r   getcwdr   r   rx   )rr   r   r   r   s   ` @@rE   r   z ContinuousScheduler.make_sampler;  si    iik#&>>W$=U =e = =r 1U e  0 rG   c                    t        j                         }| j                  r| j                         | _        t        j                         |z
  }|| j
                  k  rt        | j
                  |z
         | j                  rd| _        n!t        j                         }| j                  r| j                  }||j                          y y rI   )	r*   perf_counterr   r   r   r   thread_sleepr   flush)rr   lastelapsedr   s       rE   runzContinuousScheduler.run  s      "ll!%D
 '')D0G&T]]W45 !!$  $$&D+ ll. LLN rG   r2   zUnion[ContinuousProfile, None]rt   r2   zUnion[str, None])r2   zCallable[..., bool])ru   rv   rw   r7   ry   intr   rx   rO   rS   rP   r`   r   r   r   r   propertyrf   r   r   rK   rG   rE   r{   r{      s    %.D
".?? "? 	?
 3? 
?8Bt B """

 ' '
`DrG   r{   c            
       \     e Zd ZU dZdZded<   dZdeddd	d
ddddf
 fdZddZ	ddZ
 xZS )r;   zr
    This scheduler is based on running a daemon thread that will call
    the sampler at a regular interval.
    threadr   r7   z)sentry.profiler.ThreadContinuousSchedulerrD   r-   r.   r/   r   r0   r1   r2   Nc                 j    t         |   ||||       d | _        t        j                         | _        y rN   )superr   r   	threadingLocklockrr   rD   r-   r/   r0   	__class__s        rE   r   z"ThreadContinuousScheduler.__init__  s-     	GX|D48NN$	rG   c                    d| _         t        j                         }| j                  r| j                  |k(  ry | j
                  5  | j                  r| j                  |k(  r
	 d d d        y || _        d| _        | j                          t        j                  | j                  | j                  d      | _        	 | j                  j                          d d d        y # t        $ r d| _        d | _        Y "w xY w# 1 sw Y   y xY w)NFT)nametargetdaemon)r   r   r   r   r   r   r   r   Threadr   r   r   startRuntimeErrorrr   r   s     rE   r   z(ThreadContinuousScheduler.ensure_running  s    "iik <<DHHOYY 	# ||C	# 	# DHDL 
 $**		$((SWXDK#!!#)	# 	#*   #  %"	#+	# 	#s1   C:*AC::CC74C:6C77C::Dc                     | j                   rd| _         | j                  "| j                  j                          d | _        y y rI   r   r   joinrq   s    rE   r   z"ThreadContinuousScheduler.teardown  6    << DL;;"KKDK #rG   rt   )ru   rv   rw   __doc__r7   ry   r   r   r   r   r   __classcell__r   s   @rE   r;   r;     sZ    
 &.D
"-6D
%
% "
% 	
%
 3
% 

%"#HrG   r;   c            
       X     e Zd ZU dZdZded<   dedddd	d
dddf
 fdZddZddZ	 xZ
S )r:   as  
    This scheduler is based on the thread scheduler but adapted to work with
    gevent. When using gevent, it may monkey patch the threading modules
    (`threading` and `_thread`). This results in the use of greenlets instead
    of native threads.

    This is an issue because the sampler CANNOT run in a greenlet because
    1. Other greenlets doing sync work will prevent the sampler from running
    2. The greenlet runs in the same thread as other greenlets so when taking
       a sample, other greenlets will have been evicted from the thread. This
       results in a sample containing only the sampler's code.
    geventr   r7   rD   r-   r.   r/   r   r0   r1   r2   Nc                     t         $t        dj                  | j                              t        |   ||||       d | _        t        j                         | _	        y )Nz"Profiler mode: {} is not available)
r)   r=   r>   r7   r   r   r   r   r   r   r   s        rE   r   z"GeventContinuousScheduler.__init__  sN     AHHSTTGX|D/3NN$	rG   c                    d| _         t        j                         }| j                  r| j                  |k(  ry | j
                  5  | j                  r| j                  |k(  r
	 d d d        y || _        d| _        | j                          t        d      | _        	 | j                  j                  | j                         d d d        y # t        $ r d| _        d | _        Y "w xY w# 1 sw Y   y xY w)NFT   )r   r   r   r   r   r   r   r)   r   spawnr   r   r   s     rE   r   z(GeventContinuousScheduler.ensure_running  s    "iik <<DHHOYY 	# ||C	# 	# DHDL $Q-DK#!!$((+!	# 	#"   #  %"	##	# 	#s0   C$*.C$%CC!C$ C!!C$$C-c                     | j                   rd| _         | j                  "| j                  j                          d | _        y y rI   r   rq   s    rE   r   z"GeventContinuousScheduler.teardown=  r   rG   rt   )ru   rv   rw   r   r7   ry   r   r   r   r   r   r   s   @rE   r:   r:     sU     &.D
"-%% "% 	%
 3% 
%#@rG   r:   <   c            
       T    e Zd Zdddddedddd	f
d
Zdedddd	fdZdedefdZddZ	y	)r   r-   r.   r/   r   buffer_sizer0   r1   r2   Nc                 D   || _         || _        || _        || _        t	        j
                         j                  | _        t               | _	        t               | _        t        j                  t        j                        j                         | j                  z
  | _        y rN   )r-   r/   r   r0   uuiduuid4hexrf   ProfileChunkchunkr   start_monotonic_timer   r   utcr%   start_timestamp)rr   r-   r/   r   r0   s        rE   r   zProfileBuffer.__init__J  sy      &(::<++!^
 %(E! LL&002T5N5NN 	rG   monotonic_timer   r   c                     | j                  |      r.| j                          t               | _        t	               | _        | j                  j                  | j                  |z   |       y rN   )should_flushr   r   r   r   r   r   r   )rr   r   r   s      rE   r   zProfileBuffer.writef  sK    ^,JJL%DJ(+D%

-->GrG   c                 :    || j                   z
  | j                  k\  S rN   )r   r   )rr   r   s     rE   r   zProfileBuffer.should_flushn  s       9 99T=M=MMMrG   c                     | j                   j                  | j                  | j                  | j                        }t               }|j                  |       | j                  |       y rN   )r   to_jsonrf   r-   r/   r   add_profile_chunkr0   )rr   r   envelopes      rE   r   zProfileBuffer.flushs  sK    

""4#3#3T\\4==Q:""5)(#rG   rt   )
ru   rv   rw   r   r   rk   r   rx   r   r   rK   rG   rE   r   r   I  sq    
!
 
 	

 3
 

8HE H3D H HN5 NT N
$rG   r   c                   @    e Zd ZddZdeddddfdZded	d
dddd
fdZy)r   r2   Nc                     t        j                         j                  | _        i | _        i | _        g | _        g | _        g | _        y rN   )	r   r   r   chunk_idindexed_framesindexed_stacksframesstackssamplesrq   s    rE   r   zProfileChunk.__init__{  s:    

((4646.0.002rG   r   r   r   c                 p   |D ]  \  }\  }}}	 || j                   vrt        |      D ]T  \  }}|| j                  vst        | j                        | j                  |<   | j                  j                  ||          V t        | j                         | j                   |<   | j                  j                  |D cg c]  }| j                  |    c}       | j                  j                  ||| j                   |   d        y c c}w # t        $ r! t        t        j                                Y 1w xY w)Nr$   )r  	enumerater  r   r	  r   r
  r  r   r   r   r   )	rr   r   r   r   r'   	frame_idsr	  iframe_ids	            rE   r   zProfileChunk.write  s%   28 	;.C.(Iv; 4#6#66'0'; :8#4+>+>><?@S@S<TD//9 KK..vay9:
 588K8K4LD''1KK&&GPQ8,,X6Q ##%'%($($7$7$A	; R " ; +3<<>:;s)   -DA=D9D
3DD&D54D5rf   r-   r.   r/   r   c                    | j                   | j                  | j                  t        j                         D ci c]-  }t        |j                        dt        |j                        i/ c}d}t        |d   |d   |d   |d          | j                  |d   t        dd||d	d
}dD ]'  }||   	t        ||         j                         ||<   ) |S c c}w )Nr   )r	  r
  r  thread_metadatar	  in_app_excludein_app_includeproject_root)r   versionpython2)r  
client_sdkplatformr   rf   r  )releaseenvironmentdist)r	  r
  r  r   r  r   identr   r   r  r   strip)rr   rf   r-   r/   r   r   payloadkeys           rE   r  zProfileChunk.to_json  s     kkkk||
 (113	   FLL!C,$  	

 	H$%$%N#		
  (" !&

 4 	9Cs|'"73<0668	9 ? s   2C
rt   )ru   rv   rw   r   rk   r   r   r  rK   rG   rE   r   r   z  sG    3; ;'8 ;T ;8&&)9&EN&	&rG   r   rt   r   r   )Qr?   r   rj   r   r   r*   r   r[   collectionsr   r   r   sentry_sdk.constsr   sentry_sdk.enveloper   sentry_sdk._lru_cacher   sentry_sdk.profiler.utilsr	   r
   sentry_sdk.utilsr   r   r   r   r   typingr   r   r   r   r   r   r   r   r   r   typing_extensionsr   sentry_sdk._typesr   r   r   r   r   r    r!   r"   rk   r   r#   gevent.monkeyr(   gevent.threadpoolr)   _ThreadPoolry   r   ImportErrorr+   r,   rx   rF   rL   rQ   rT   rV   r^   ra   rc   r9   rg   rl   rn   r{   r;   r:   r   r   r   rK   rG   rE   <module>r/     s    	  
      ' % ( *  !+A   !	
O*;0;J-;0L /3
+ 2666 /6 
	6rD 	#"0%0	0 _ _D? 3 ?DE 3 EP  .$ .$bL Lq  ::LJs   E   E65E6