o
    S۷iX                     @   s  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rd 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Z3zd dl4m5Z5 d dl6m7Z8 e8Z7de9d< e5ddZ:W n e;y   ej<Z:dZ7Y nw da=de9d< d d!d"d#d$d%d&e>fd'd(Z?d&e>fd)d*Z@dNd+d,ZAdOd.d/ZBdNd0d1ZCdNd2d3ZDdNd4d5ZEdNd6d7ZFdNd8d9ZGdPd;d<ZHd=d>d&e>fd?d@ZIG dAdB dBZJG dCdD dDZKG dEdF dFeKZLG dGdH dHeKZMdIZNG dJdK dKZOG dLdM dMZPdS )Q    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                 C   s   t d u}|rtd t  t rtj}ntj}| dd ur$| d }n| di }|dp0|}t	}|tjkr@t|| ||a n|tjkrMt|| ||a nt
d|tdjt jd |sett dS )	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   GeventContinuousSchedulerr5   ThreadContinuousSchedulergetr   
ValueErrorformatatexitregister)r,   r.   r/   already_initializeddefault_profiler_moder2   experiments	frequency rC   ]/home/ubuntu/vllm_env/lib/python3.10/site-packages/sentry_sdk/profiler/continuous_profiler.pysetup_continuous_profilerJ   s<   




rE   c                   C   s   t d u rdS t jS NF)r+   sampledrC   rC   rC   rD   is_profile_session_sampled      rH   c                   C   s$   t d u rd S t  sd S t   d S N)r+   is_auto_start_enabledmanual_startrC   rC   rC   rD   !try_autostart_continuous_profiler   s
   rM   Union[ContinuousProfile, None]c                   C   s   t d u rd S t  S rJ   )r+   
auto_startrC   rC   rC   rD   !try_profile_lifecycle_trace_start   s   rP   c                   C      t d u rd S t   d S rJ   )r+   rL   rC   rC   rC   rD   start_profiler      rR   c                   C      t jdtdd t  d S )NzWThe `start_profile_session` function is deprecated. Please use `start_profile` instead.   
stacklevel)warningswarnDeprecationWarningrR   rC   rC   rC   rD   start_profile_session      
r[   c                   C   rQ   rJ   )r+   manual_stoprC   rC   rC   rD   stop_profiler   rS   r^   c                   C   rT   )NzUThe `stop_profile_session` function is deprecated. Please use `stop_profile` instead.rU   rV   )rX   rY   rZ   r^   rC   rC   rC   rD   stop_profile_session   r\   r_   c                   C   s   t   d ad S rJ   )r^   r+   rC   rC   rC   rD   r7      s   r7   Union[str, None]c                   C   s   t d u rd S t jS rJ   )r+   profiler_idrC   rC   rC   rD   get_profiler_id   rI   rb   sample_ratezUnion[float, None]c                 C   s   | sdS t   t| k S rF   )randomfloat)rc   rC   rC   rD   +determine_profile_session_sampling_decision   s   rf   c                   @   s$   e Zd ZU dZeed< dddZdS )ContinuousProfileTactiver1   Nc                 C   s
   d| _ d S rF   )rh   selfrC   rC   rD   stop   s   
zContinuousProfile.stopr1   N)__name__
__module____qualname__rh   bool__annotations__rk   rC   rC   rC   rD   rg      s   
 rg   c                
   @   s   e Zd ZU dZded< deddddd	d
ddf
ddZdefddZd(ddZ	d)ddZ
d)ddZd)ddZd)ddZd)ddZd)ddZed*d!d"Zd+d$d%Zd)d&d'ZdS ),ContinuousSchedulerunknownr   r5   rB   r,   r-   r.   r   r/   r0   r1   Nc                 C   sz   d| | _ || _|| _|| _| jd| _| jd}t|| _|  | _	d | _
d | _d| _d| _tdd| _t | _d S )Ng      ?profile_lifecycleprofile_session_sample_rateF   )maxlen)intervalr,   r.   r/   r:   	lifecyclerf   rG   make_samplersamplerbufferpidrunningsoft_shutdownr   new_profilessetactive_profiles)rj   rB   r,   r.   r/   ru   rC   rC   rD   __init__   s    

zContinuousScheduler.__init__c                 C   s0   | j t kr	dS | jd}|sdS |dS )NFr3   continuous_profiling_auto_start)r}   osgetpidr,   r:   )rj   rA   rC   rC   rD   rK      s   
z)ContinuousScheduler.is_auto_start_enabledrN   c                 C   s@   | j sd S | jdkrd S td t }| j| |   |S )Ntracez"[Profiling] Auto starting profiler)rG   ry   r   r6   rg   r   appendensure_running)rj   profilerC   rC   rD   rO     s   

zContinuousScheduler.auto_startc                 C   s$   | j sd S | jdkrd S |   d S Nmanual)rG   ry   r   ri   rC   rC   rD   rL     s
   
z ContinuousScheduler.manual_startc                 C   s   | j dkrd S |   d S r   )ry   teardownri   rC   rC   rD   r]   !  s   
zContinuousScheduler.manual_stopc                 C      t rJ   NotImplementedErrorri   rC   rC   rD   r   '     z"ContinuousScheduler.ensure_runningc                 C   r   rJ   r   ri   rC   rC   rD   r   *  r   zContinuousScheduler.teardownc                 C   r   rJ   r   ri   rC   rC   rD   pause-  r   zContinuousScheduler.pausec                 C   s   t | j| jt| j| _d S rJ   )ProfileBufferr,   r.   PROFILE_BUFFER_SECONDSr/   r|   ri   rC   rC   rD   reset_buffer0  s   
z ContinuousScheduler.reset_bufferr`   c                 C   s   | j d u rd S | j jS rJ   )r|   ra   ri   rC   rC   rD   ra   5  s   
zContinuousScheduler.profiler_idCallable[..., bool]c                    s`   t  tdd jdkrdddddtf fdd	}|S dddddtf fd
d	}|S )N   )max_sizer   argsr   kwargsr1   c                     s   j sjsdS tj }t }z fddt  D }W n ty0   tt	  Y dS w t
|D ]}jj   q5g }jD ]
}|jsP|| qF|D ]}j| qSjdurhj|| dS )
                Take a sample of the stack on all the threads in the process.
                This should be called at a regular interval to collect samples.
                Tc                    $   g | ]\}}t |t| fqS rC   strr	   .0tidframecachecwdrC   rD   
<listcomp>Y      KContinuousScheduler.make_sampler.<locals>._sample_stack.<locals>.<listcomp>FN)r   r   lenr   sys_current_framesitemsAttributeErrorr
   exc_inforangeaddpopleftrh   r   remover|   write)r   r   r   tssample_inactive_profilesr   r   r   rj   rC   rD   _sample_stackB  s0   






z7ContinuousScheduler.make_sampler.<locals>._sample_stackc                     sd   t  }z fddt  D }W n ty#   tt  Y dS w jdur0j|| dS )r   c                    r   rC   r   r   r   rC   rD   r     r   r   FN)	r   r   r   r   r   r
   r   r|   r   )r   r   r   r   r   rC   rD   r     s   


)r   getcwdr   ry   rp   )rj   r   rC   r   rD   rz   ;  s   

Yz ContinuousScheduler.make_samplerc                 C   sz   t  }| jr,|  | _t  | }|| jk rt| j|  | jr%d| _nt  }| js| jd ur;| j  d | _d S d S rF   )	r)   perf_counterr~   r{   r   rx   thread_sleepr|   flush)rj   lastelapsedrC   rC   rD   run  s   




zContinuousScheduler.runr1   rN   rl   r1   r`   )r1   r   )rm   rn   ro   r5   rq   intr   rp   rK   rO   rL   r]   r   r   r   r   propertyra   rz   r   rC   rC   rC   rD   rr      s2   
 



	




brr   c                
       s\   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dZdddZ	dddZ
  ZS )r9   zr
    This scheduler is based on running a daemon thread that will call
    the sampler at a regular interval.
    threadr   r5   z)sentry.profiler.ThreadContinuousSchedulerrB   r,   r-   r.   r   r/   r0   r1   Nc                    s&   t  |||| d | _t | _d S rJ   )superr   r   	threadingLocklockrj   rB   r,   r.   r/   	__class__rC   rD   r     s   z"ThreadContinuousScheduler.__init__c              	   C   s   d| _ t }| jr| j|krd S | jN | jr&| j|kr&	 W d    d S || _d| _|   tj| j	| j
dd| _z| j  W n tyQ   d| _d | _Y n	w W d    d S W d    d S 1 sew   Y  d S )NFT)nametargetdaemon)r   r   r   r~   r}   r   r   r   Threadr   r   r   startRuntimeErrorrj   r}   rC   rC   rD   r     s,   
"z(ThreadContinuousScheduler.ensure_runningc                 C   0   | j rd| _ | jd ur| j  d | _d | _d S rF   r~   r   joinr|   ri   rC   rC   rD   r        


z"ThreadContinuousScheduler.teardownrl   )rm   rn   ro   __doc__r5   rq   r   r   r   r   r   __classcell__rC   rC   r   rD   r9     s"   
 
$r9   c                
       sX   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dZdddZdddZ	  Z
S )r8   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   r5   rB   r,   r-   r.   r   r/   r0   r1   Nc                    s>   t d u rtd| jt |||| d | _t | _	d S )Nz"Profiler mode: {} is not available)
r(   r;   r<   r5   r   r   r   r   r   r   r   r   rC   rD   r     s
   z"GeventContinuousScheduler.__init__c              	   C   s   d| _ t }| jr| j|krd S | jJ | jr&| j|kr&	 W d    d S || _d| _|   td| _z	| j	| j
 W n tyM   d| _d | _Y n	w W d    d S W d    d S 1 saw   Y  d S )NFT   )r   r   r   r~   r}   r   r   r(   r   spawnr   r   r   rC   rC   rD   r     s,   

"z(GeventContinuousScheduler.ensure_runningc                 C   r   rF   r   ri   rC   rC   rD   r   ?  r   z"GeventContinuousScheduler.teardownrl   )rm   rn   ro   r   r5   rq   r   r   r   r   r   rC   rC   r   rD   r8      s    
 
 r8   <   c                
   @   s\   e Zd Zdddddedddd	f
d
dZdedddd	fddZdedefddZdddZ	d	S )r   r,   r-   r.   r   buffer_sizer/   r0   r1   Nc                 C   sP   || _ || _|| _|| _t j| _t | _	t
 | _t
tj | j | _d S rJ   )r,   r.   r   r/   uuiduuid4hexra   ProfileChunkchunkr   start_monotonic_timer   r   utcr$   start_timestamp)rj   r,   r.   r   r/   rC   rC   rD   r   N  s   zProfileBuffer.__init__monotonic_timer   r   c                 C   s:   |  |r|   t | _t | _| j| j| | d S rJ   )should_flushr   r   r   r   r   r   r   )rj   r   r   rC   rC   rD   r   j  s
   
zProfileBuffer.writec                 C   s   || j  | jkS rJ   )r   r   )rj   r   rC   rC   rD   r   r  s   zProfileBuffer.should_flushc                 C   s4   | j | j| j| j}t }|| | | d S rJ   )r   to_jsonra   r,   r.   r   add_profile_chunkr/   )rj   r   enveloperC   rC   rD   r   w  s   
zProfileBuffer.flushrl   )
rm   rn   ro   r   r   re   r   rp   r   r   rC   rC   rC   rD   r   M  s    
r   c                   @   sF   e Zd ZdddZdeddddfdd	Zd
eddddddfddZdS )r   r1   Nc                 C   s.   t  j| _i | _i | _g | _g | _g | _d S rJ   )	r   r   r   chunk_idindexed_framesindexed_stacksframesstackssamplesri   rC   rC   rD   r     s   
zProfileChunk.__init__r   r   r   c           	   	      s   |D ]]\}\}}}zG| j vrBt|D ]\}}| jvr,t j j|<  j||  qt j  j |<  j fdd|D   j|| j | d W q ty_   t	t
  Y qw d S )Nc                    s   g | ]} j | qS rC   )r   )r   frame_idri   rC   rD   r     s    z&ProfileChunk.write.<locals>.<listcomp>r#   )r   	enumerater   r   r   r   r   r   r   r
   r   r   )	rj   r   r   r   r&   	frame_idsr   ir   rC   ri   rD   r     s,   

zProfileChunk.writera   r,   r-   r.   r   c                 C   s   | j | j| jdd t D d}t|d |d |d |d  | j|d td	d
||dd}dD ]}|| d urCt|| 	 ||< q1|S )Nc                 S   s"   i | ]}t |jd t |jiqS )r   )r   identr   )r   r   rC   rC   rD   
<dictcomp>  s    
z(ProfileChunk.to_json.<locals>.<dictcomp>)r   r   r   thread_metadatar   in_app_excludein_app_includeproject_rootr   )r   versionpython2)r   
client_sdkplatformr   ra   r   )releaseenvironmentdist)
r   r   r   r   r   r   r   r   r   strip)rj   ra   r,   r.   r   payloadkeyrC   rC   rD   r     s6   zProfileChunk.to_jsonrl   )rm   rn   ro   r   re   r   r   r   rC   rC   rC   rD   r   ~  s    
	r   rl   r   r   )Qr=   r   rd   r   r   r)   r   rX   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!   re   r   r"   gevent.monkeyr'   gevent.threadpoolr(   _ThreadPoolrq   r   ImportErrorr*   r+   rp   rE   rH   rM   rP   rR   r[   r^   r_   r7   rb   rf   rg   rr   r9   r8   r   r   r   rC   rC   rC   rD   <module>   s   
  	

9




	

	


 cDJ1