o
    BDi,Y                     @   sr  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 e8Z7e5ddZ9W n e:y   ej;Z9dZ7Y nw da<dd Z=dd Z>d d! Z?d"d# Z@d$d% ZAd&d' ZBd(d) ZCd*d+ ZDd,d- ZEd.d/ ZFG d0d1 d1ZGG d2d3 d3ZHG d4d5 d5eHZIG d6d7 d7eHZJd8ZKG d9d: d:ZLG d;d< d<ZMdS )=    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)
ThreadPooltimesleepc                 C   s   t d urtd dS t rtj}ntj}| dd ur!| d }n| di }|dp-|}t}|tjkr=t|| ||a n|tjkrJt|| ||a nt	d
|tdj
t jd tt d	S )
Nz0[Profiling] Continuous Profiler is already setupFprofiler_mode_experimentscontinuous_profiling_modez$Unknown continuous profiler mode: {}z9[Profiling] Setting up continuous profiler in {mode} mode)modeT)
_schedulerr   debugr   GeventContinuousSchedulerr.   ThreadContinuousSchedulergetr   
ValueErrorformatatexitregisterteardown_continuous_profiler)optionssdk_infocapture_funcdefault_profiler_moder+   experiments	frequency r?   `/var/www/Datamplify/venv/lib/python3.10/site-packages/sentry_sdk/profiler/continuous_profiler.pysetup_continuous_profilerJ   s8   




rA   c                   C   s$   t d u rd S t  sd S t   d S N)r/   is_auto_start_enabledmanual_startr?   r?   r?   r@   !try_autostart_continuous_profiler}   s
   rE   c                   C   s   t d u rd S t  S rB   )r/   
auto_startr?   r?   r?   r@   !try_profile_lifecycle_trace_start   s   rG   c                   C      t d u rd S t   d S rB   )r/   rD   r?   r?   r?   r@   start_profiler      rI   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DeprecationWarningrI   r?   r?   r?   r@   start_profile_session      
rR   c                   C   rH   rB   )r/   manual_stopr?   r?   r?   r@   stop_profiler   rJ   rU   c                   C   rK   )NzUThe `stop_profile_session` function is deprecated. Please use `stop_profile` instead.rL   rM   )rO   rP   rQ   rU   r?   r?   r?   r@   stop_profile_session   rS   rV   c                   C   s   t   d ad S rB   )rU   r/   r?   r?   r?   r@   r8      s   r8   c                   C   s   t d u rd S t jS rB   )r/   profiler_idr?   r?   r?   r@   get_profiler_id   s   rX   c                 C   s   | sdS t   t| k S NF)randomfloat)sample_rater?   r?   r@   +determine_profile_session_sampling_decision   s   r]   c                   @   s"   e Zd ZU dZeed< dd ZdS )ContinuousProfileTactivec                 C   s
   d| _ d S rY   )r_   selfr?   r?   r@   stop   s   
zContinuousProfile.stopN)__name__
__module____qualname__r_   bool__annotations__rb   r?   r?   r?   r@   r^      s   
 r^   c                   @   st   e Zd ZdZdd Zd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dS )ContinuousSchedulerunknownc                 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)intervalr9   r:   r;   r3   	lifecycler]   sampledmake_samplersamplerbufferpidrunningsoft_shutdownr   new_profilessetactive_profiles)ra   r>   r9   r:   r;   rk   r?   r?   r@   __init__   s    

zContinuousScheduler.__init__c                 C   s0   | j t kr	dS | jd}|sdS |dS )NFr,   continuous_profiling_auto_start)rt   osgetpidr9   r3   )ra   r=   r?   r?   r@   rC      s   
z)ContinuousScheduler.is_auto_start_enabledc                 C   s@   | j sd S | jdkrd S td t }| j| |   |S )Ntracez"[Profiling] Auto starting profiler)rp   ro   r   r0   r^   rw   appendensure_running)ra   profiler?   r?   r@   rF     s   

zContinuousScheduler.auto_startc                 C   s$   | j sd S | jdkrd S |   d S Nmanual)rp   ro   r   r`   r?   r?   r@   rD     s
   
z ContinuousScheduler.manual_startc                 C   s   | j dkrd S |   d S r   )ro   teardownr`   r?   r?   r@   rT      s   
zContinuousScheduler.manual_stopc                 C      t rB   NotImplementedErrorr`   r?   r?   r@   r   '     z"ContinuousScheduler.ensure_runningc                 C   r   rB   r   r`   r?   r?   r@   r   +  r   zContinuousScheduler.teardownc                 C   r   rB   r   r`   r?   r?   r@   pause/  r   zContinuousScheduler.pausec                 C   s   t | j| jt| j| _d S rB   )ProfileBufferr9   r:   PROFILE_BUFFER_SECONDSr;   rs   r`   r?   r?   r@   reset_buffer3  s   
z ContinuousScheduler.reset_bufferc                 C   s   | j d u rd S | j jS rB   )rs   rW   r`   r?   r?   r@   rW   9  s   
zContinuousScheduler.profiler_idc                    sD   t  tdd jdkr fdd}|S  fdd}|S )N   )max_sizer~   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 r?   strr	   .0tidframecachecwdr?   r@   
<listcomp>`      KContinuousScheduler.make_sampler.<locals>._sample_stack.<locals>.<listcomp>FN)rw   ry   lenr   sys_current_framesitemsAttributeErrorr
   exc_inforangeaddpopleftr_   r   removers   write)argskwargsrw   tssample_inactive_profilesr   r   r   ra   r?   r@   _sample_stackH  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   r?   r   r   r   r?   r@   r     r   r   FN)	r   r   r   r   r   r
   r   rs   r   )r   r   r   r   r   r?   r@   r     s   


)r|   getcwdr   ro   )ra   r   r?   r   r@   rq   @  s   

[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 rY   )	r)   perf_counterru   rr   rv   rn   thread_sleeprs   flush)ra   lastelapsedr?   r?   r@   run  s   




zContinuousScheduler.runN)rc   rd   re   r.   rz   rC   rF   rD   rT   r   r   r   r   propertyrW   rq   r   r?   r?   r?   r@   rh      s    

erh   c                       s8   e Zd ZdZdZdZ fddZdd Zdd	 Z  Z	S )
r2   zr
    This scheduler is based on running a daemon thread that will call
    the sampler at a regular interval.
    threadz)sentry.profiler.ThreadContinuousSchedulerc                    s&   t  |||| d | _t | _d S rB   )superrz   r   	threadingLocklockra   r>   r9   r:   r;   	__class__r?   r@   rz     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)rv   r|   r}   ru   rt   r   r   r   Threadr   r   r   startRuntimeErrorra   rt   r?   r?   r@   r     s,   
"z(ThreadContinuousScheduler.ensure_runningc                 C   0   | j rd| _ | jd ur| j  d | _d | _d S rY   ru   r   joinrs   r`   r?   r?   r@   r        


z"ThreadContinuousScheduler.teardown)
rc   rd   re   __doc__r.   r   rz   r   r   __classcell__r?   r?   r   r@   r2     s    &r2   c                       s4   e Zd ZdZdZ fddZdd Zdd Z  ZS )	r1   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.
    geventc                    s>   t d u rtd| jt |||| d | _t | _	d S )Nz"Profiler mode: {} is not available)
r(   r4   r5   r.   r   rz   r   r   r   r   r   r   r?   r@   rz     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   )rv   r|   r}   ru   rt   r   r   r(   r   spawnr   r   r   r?   r?   r@   r   "  s,   

"z(GeventContinuousScheduler.ensure_runningc                 C   r   rY   r   r`   r?   r?   r@   r   D  r   z"GeventContinuousScheduler.teardown)	rc   rd   re   r   r.   rz   r   r   r   r?   r?   r   r@   r1     s    "r1   <   c                   @   s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
r   c                 C   sP   || _ || _|| _|| _t j| _t | _	t
 | _t
tj | j | _d S rB   )r9   r:   buffer_sizer;   uuiduuid4hexrW   ProfileChunkchunkr   start_monotonic_timer   r   utcr$   start_timestamp)ra   r9   r:   r   r;   r?   r?   r@   rz   T  s   zProfileBuffer.__init__c                 C   s:   |  |r|   t | _t | _| j| j| | d S rB   )should_flushr   r   r   r   r   r   r   )ra   monotonic_timer   r?   r?   r@   r   k  s
   
zProfileBuffer.writec                 C   s   || j  | jkS rB   )r   r   )ra   r   r?   r?   r@   r   t  s   zProfileBuffer.should_flushc                 C   s4   | j | j| j| j}t }|| | | d S rB   )r   to_jsonrW   r9   r:   r   add_profile_chunkr;   )ra   r   enveloper?   r?   r@   r   {  s   
zProfileBuffer.flushN)rc   rd   re   rz   r   r   r   r?   r?   r?   r@   r   S  s
    	r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )r   c                 C   s.   t  j| _i | _i | _g | _g | _g | _d S rB   )	r   r   r   chunk_idindexed_framesindexed_stacksframesstackssamplesr`   r?   r?   r@   rz     s   
zProfileChunk.__init__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 r?   )r   )r   frame_idr`   r?   r@   r     s    z&ProfileChunk.write.<locals>.<listcomp>r#   )r   	enumerater   r   r   r   r   r   r   r
   r   r   )	ra   r   r   r   r&   	frame_idsr   ir   r?   r`   r@   r     s,   

zProfileChunk.writec                 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   r?   r?   r@   
<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   rW   r   )releaseenvironmentdist)
r   r   r   r   r   r   r   r   r   strip)ra   rW   r9   r:   r   payloadkeyr?   r?   r@   r     s6   zProfileChunk.to_jsonN)rc   rd   re   rz   r   r   r?   r?   r?   r@   r     s    
r   )Nr6   r|   rZ   r   r   r)   r   rO   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!   r[   intr"   gevent.monkeyr'   gevent.threadpoolr(   _ThreadPoolr   ImportErrorr*   r/   rA   rE   rG   rI   rR   rU   rV   r8   rX   r]   r^   rh   r2   r1   r   r   r   r?   r?   r?   r@   <module>   s     	
3
 lBI0