Ë
    çÞËjC  ã                   óD  — 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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rUd 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)m*Z*  e!de+e(e,dœ«      Z-	 d dl.m/Z/ d dl0m1Z2 e2Z1 e/dd«      Z3da6d„ Z7d„ Z8d„ Z9d„ Z:d„ Z;d„ Z< G d„ d «      Z= G d!„ d"e=«      Z> G d#„ d$e=«      Z?d%Z@ G d&„ d'«      ZA G d(„ d)«      ZBy# e4$ r ejj                  Z3dZ1Y Œ`w xY w)*é    N)Ú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)ÚDict)ÚList)ÚOptional)ÚType)ÚUnion)Ú	TypedDict)ÚContinuousProfilerModeÚSDKInfo)ÚExtractedSampleÚFrameIdÚStackIdÚThreadIdÚProcessedFrameÚProcessedStackÚProcessedSample©Ú	timestampÚ	thread_idÚstack_id)Úget_original)Ú
ThreadPoolÚtimeÚsleepc                 ó@  — t         �t        j                  d«       yt        «       rt        j
                  }nt        j
                  }| 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
                  ¬«      «       t        j                  t        «       y)	Nz0[Profiling] Continuous Profiler is already setupFÚ_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_modeÚexperimentsÚprofiler_modeÚ	frequencys          úd/var/www/photos/backend/venv/lib/python3.12/site-packages/sentry_sdk/profiler/continuous_profiler.pyÚsetup_continuous_profilerr?   E   s  € ô ÐÜ�‰ÐGÔHØä„{ô
 !:× >Ñ >Ñä 9× >Ñ >Ðà—+‘+˜n¨bÓ1€Kð 	�‰Ð3Ó4ÒMÐ8Mð ô +€IàÔ1×6Ñ6Ò6Ü.Ø�w ¨,ó
‰
ð 
Ô3×8Ñ8Ò	8Ü.Ø�w ¨,ó
‰
ô Ð?×FÑFÀ}ÓUÓVÐVä
‡L�LØC×JÑJÜ—‘ð 	Kó 	
ôô ‡O�OÔ0Ô1àó    c                  ód   — t         €y t         j                  «       sy t         j                  «        y ©N)r-   Úshould_autostartÚensure_running© r@   r>   Ú!try_autostart_continuous_profilerrF   t   s(   € äÐØô ×&Ñ&Ô(Øä×ÑÕr@   c                  ó:   — t         €y t         j                  «        y rB   )r-   rD   rE   r@   r>   Ústart_profilerrH   ˆ   s   € äÐØä×ÑÕr@   c                  ó:   — t         €y t         j                  «        y rB   )r-   ÚteardownrE   r@   r>   Ústop_profilerrK   �   s   € äÐØä×ÑÕr@   c                  ó   — t        «        d ay rB   )rK   r-   rE   r@   r>   r6   r6   ˜   s   € ä„Oð �Jr@   c                  ó0   — t         €y t         j                  S rB   )r-   Úprofiler_idrE   r@   r>   Úget_profiler_idrO       s   € äÐØÜ×!Ñ!Ð!r@   c                   óP   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	e
d„ «       Zd	„ Zd
„ Zy)ÚContinuousSchedulerÚunknownc                 óˆ   — d|z  | _         || _        || _        || _        | j	                  «       | _        d | _        d| _        y )Ng      ð?F)Úintervalr7   r8   r9   Úmake_samplerÚsamplerÚbufferÚrunning)Úselfr=   r7   r8   r9   s        r>   Ú__init__zContinuousScheduler.__init__ª   sA   € à˜i™ˆŒØˆŒØ ˆŒØ(ˆÔØ×(Ñ(Ó*ˆŒØˆŒàˆ�r@   c                 ó`   — | j                   j                  d«      }|sy|j                  d«      S )Nr*   FÚcontinuous_profiling_auto_start)r7   r1   )rY   r;   s     r>   rC   z$ContinuousScheduler.should_autostartµ   s,   € à—l‘l×&Ñ& ~Ó6ˆÙØØ�‰Ð@ÓAÐAr@   c                 ó   — t         ‚rB   ©ÚNotImplementedError©rY   s    r>   rD   z"ContinuousScheduler.ensure_running¼   ó   € ä!Ð!r@   c                 ó   — t         ‚rB   r^   r`   s    r>   rJ   zContinuousScheduler.teardownÀ   ra   r@   c                 ó   — t         ‚rB   r^   r`   s    r>   ÚpausezContinuousScheduler.pauseÄ   ra   r@   c                 ón   — t        | j                  | j                  t        | j                  «      | _        y rB   )ÚProfileBufferr7   r8   ÚPROFILE_BUFFER_SECONDSr9   rW   r`   s    r>   Úreset_bufferz ContinuousScheduler.reset_bufferÈ   s&   € ä#Ø�L‰L˜$Ÿ-™-Ô)?À×ARÑARó
ˆ�r@   c                 óH   — | j                   €y | j                   j                  S rB   )rW   rN   r`   s    r>   rN   zContinuousScheduler.profiler_idÎ   s!   € ð �;‰;ÐØØ�{‰{×&Ñ&Ð&r@   c                 óZ   ‡ ‡‡— t        j                  «       Št        d¬«      Šˆˆˆ fd„}|S )Né   )Úmax_sizec            
      óf  •— t        «       }	 t        j                  «       j                  «       D ��cg c]  \  }}t	        |«      t        |‰‰«      f‘Œ }}}‰j                  �‰j                  j                  ||«       yyc c}}w # t        $ r  t        t        j                  «       «       Y yw xY w)z£
            Take a sample of the stack on all the threads in the process.
            This should be called at a regular interval to collect samples.
            N)r   ÚsysÚ_current_framesÚitemsÚstrr	   ÚAttributeErrorr
   Úexc_inforW   Úwrite)	ÚargsÚkwargsÚtsÚtidÚframeÚsampleÚcacheÚcwdrY   s	         €€€r>   Ú_sample_stackz7ContinuousScheduler.make_sampler.<locals>._sample_stackÛ   s¦   ø€ ô “ˆBð	ô '*×&9Ñ&9Ó&;×&AÑ&AÓ&C÷á"˜˜Uô ˜“Xœ}¨U°E¸3Ó?Ò@ð�ñ ð �{‰{Ð&Ø—‘×!Ñ! " fÕ-ð 'ùóøô "ò ô +¬3¯<©<«>Ô:Ùð	ús"   �%B ²"BÁB ÂB Â&B0Â/B0)ÚosÚgetcwdr   )rY   r}   r{   r|   s   ` @@r>   rU   z ContinuousScheduler.make_samplerÕ   s%   ú€ ä�i‰i‹kˆä #Ô&ˆö	.ð. Ðr@   c                 óp  — t        j                  «       }| j                  ro| j                  «        t        j                  «       |z
  }|| j                  k  rt        | j                  |z
  «       t        j                  «       }| j                  rŒo| j                  �| j                  j                  «        y y rB   )r'   Úperf_counterrX   rV   rT   Úthread_sleeprW   Úflush)rY   ÚlastÚelapseds      r>   ÚrunzContinuousScheduler.runô   sŒ   € ä× Ñ Ó"ˆà�lŠlØ�L‰LŒNô
 ×'Ñ'Ó)¨DÑ0ˆGØ˜Ÿ™Ò&Ü˜TŸ]™]¨WÑ4Ô5ô ×$Ñ$Ó&ˆDð �l‹lð �;‰;Ð"Ø�K‰K×ÑÕð #r@   N)Ú__name__Ú
__module__Ú__qualname__r,   rZ   rC   rD   rJ   rd   rh   ÚpropertyrN   rU   r†   rE   r@   r>   rQ   rQ   §   sD   „ Ø€Dò	òBò"ò"ò"ò
ð ñ'ó ð'òó> r@   rQ   c                   ó@   ‡ — e Zd ZdZdZdZˆ fd„Zˆ fd„Zd„ Zd„ Z	ˆ xZ
S )r0   zr
    This scheduler is based on running a daemon thread that will call
    the sampler at a regular interval.
    Úthreadz)sentry.profiler.ThreadContinuousSchedulerc                 óx   •— t         ‰| �  ||||«       d | _        d | _        t	        j
                  «       | _        y rB   )ÚsuperrZ   rŒ   ÚpidÚ	threadingÚLockÚlock©rY   r=   r7   r8   r9   Ú	__class__s        €r>   rZ   z"ThreadContinuousScheduler.__init__  s2   ø€ ä‰Ñ˜ G¨X°|ÔDàˆŒØˆŒÜ—N‘NÓ$ˆ�	r@   c                 óf   •— t         ‰| �  «       xr! | j                  t        j                  «       k7  S rB   ©rŽ   rC   r�   r~   Úgetpid©rY   r”   s    €r>   rC   z*ThreadContinuousScheduler.should_autostart  ó%   ø€ ä‰wÑ'Ó)ÒE¨d¯h©h¼"¿)¹)»+Ñ.EÐEr@   c                 óþ  — 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)NT)ÚnameÚtargetÚdaemonF)r~   r—   rX   r�   r’   rh   r�   ÚThreadr›   r†   rŒ   ÚstartÚRuntimeError©rY   r�   s     r>   rD   z(ThreadContinuousScheduler.ensure_running  sÙ   € ä�i‰i‹kˆð �<Š<˜DŸH™H¨šOØà�Y‰Yñ 	#ð �|Š| §¡¨C¢Ø÷	#ð 	#ð ˆDŒHØˆDŒLð ×ÑÔô
 $×*Ñ*°·	±	À$Ç(Á(ÐSWÔXˆDŒKð#Ø—‘×!Ñ!Ô#÷)	#ð 	#øô*  ò #ð  %�”Ø"�–ð	#ú÷+	#ð 	#ús0   ½C3Á#AC3Â3CÃC0Ã-C3Ã/C0Ã0C3Ã3C<c                 ó’   — | j                   rd| _         | j                  �!| j                  j                  «        d | _        d | _        y ©NF©rX   rŒ   ÚjoinrW   r`   s    r>   rJ   z"ThreadContinuousScheduler.teardownB  ó8   € à�<Š<Ø ˆDŒLà�;‰;Ð"Ø�K‰K×ÑÔØˆDŒKàˆ�r@   )r‡   rˆ   r‰   Ú__doc__r,   r›   rZ   rC   rD   rJ   Ú__classcell__©r”   s   @r>   r0   r0   
  s*   ø„ ñð
 €DØ6€Dô%ôFò!#öF	r@   r0   c                   ó<   ‡ — e Zd ZdZdZˆ fd„Zˆ fd„Zd„ Z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.
    Úgeventc                 óÌ   •— t         €$t        dj                  | j                  «      «      ‚t        ‰| �  ||||«       d | _        d | _        t        j                  «       | _
        y )Nz"Profiler mode: {} is not available)r&   r2   r3   r,   rŽ   rZ   rŒ   r�   r�   r‘   r’   r“   s        €r>   rZ   z"GeventContinuousScheduler.__init__^  sU   ø€ ô ÐÜÐA×HÑHÈÏÉÓSÓTÐTä‰Ñ˜ G¨X°|ÔDàˆŒØˆŒÜ—N‘NÓ$ˆ�	r@   c                 óf   •— t         ‰| �  «       xr! | j                  t        j                  «       k7  S rB   r–   r˜   s    €r>   rC   z*GeventContinuousScheduler.should_autostartj  r™   r@   c                 óä  — 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 d d d «       y w xY w# 1 sw Y   y xY w)NTé   F)r~   r—   rX   r�   r’   rh   r&   rŒ   Úspawnr†   r    r¡   s     r>   rD   z(GeventContinuousScheduler.ensure_runningn  sÖ   € ä�i‰i‹kˆð �<Š<˜DŸH™H¨šOØà�Y‰Yñ 	ð �|Š| §¡¨C¢Ø÷	ð 	ð ˆDŒHØˆDŒLð ×ÑÔä$ Q›-ˆDŒKðØ—‘×!Ñ! $§(¡(Õ+÷!	ð 	øô"  ò ð  %�”Ø"�”Ø÷-	ð 	ð"ú÷#	ð 	ús/   ½C&Á#.C&Â%CÃC#ÃC&Ã"C#Ã#C&Ã&C/c                 ó’   — | j                   rd| _         | j                  �!| j                  j                  «        d | _        d | _        y r£   r¤   r`   s    r>   rJ   z"GeventContinuousScheduler.teardownŽ  r¦   r@   )
r‡   rˆ   r‰   r§   r,   rZ   rC   rD   rJ   r¨   r©   s   @r>   r/   r/   N  s%   ø„ ñð €Dô
%ôFòö@	r@   r/   é
   c                   ó$   — e Zd Zd„ Zd„ Zd„ Zd„ Zy)rf   c                 óD  — || _         || _        || _        || _        t	        j
                  «       j                  | _        t        «       | _	        t        «       | _        t        j                  t        j                  «      j                  «       | j                  z
  | _        y rB   )r7   r8   Úbuffer_sizer9   ÚuuidÚuuid4ÚhexrN   ÚProfileChunkÚchunkr   Ústart_monotonic_timer   r   Úutcr"   Ústart_timestamp)rY   r7   r8   rµ   r9   s        r>   rZ   zProfileBuffer.__init__ž  sw   € àˆŒØ ˆŒØ&ˆÔØ(ˆÔäŸ:™:›<×+Ñ+ˆÔÜ!“^ˆŒ
ô %(£EˆÔ!ô �L‰LœŸ™Ó&×0Ñ0Ó2°T×5NÑ5NÑNð 	Õr@   c                 óÔ   — | j                  |«      r.| j                  «        t        «       | _        t	        «       | _        | j                  j                  | j                  |z   |«       y rB   )Úshould_flushrƒ   r¹   rº   r   r»   rt   r½   )rY   Úmonotonic_timerz   s      r>   rt   zProfileBuffer.writeµ  sK   € à×Ñ˜^Ô,Ø�J‰JŒLÜ%›ˆDŒJÜ(+«ˆDÔ%à�
‰
×Ñ˜×-Ñ-°Ñ>ÀÕGr@   c                 ó:   — || j                   z
  | j                  k\  S rB   )r»   rµ   )rY   rÀ   s     r>   r¿   zProfileBuffer.should_flush¾  s    € ð
  × 9Ñ 9Ñ9¸T×=MÑ=MÑMÐMr@   c                 óÒ   — | j                   j                  | j                  | j                  | j                  «      }t        «       }|j                  |«       | j                  |«       y rB   )rº   Úto_jsonrN   r7   r8   r   Úadd_profile_chunkr9   )rY   rº   Úenvelopes      r>   rƒ   zProfileBuffer.flushÅ  sK   € à—
‘
×"Ñ" 4×#3Ñ#3°T·\±\À4Ç=Á=ÓQˆÜ“:ˆØ×"Ñ" 5Ô)Ø×Ñ˜(Õ#r@   N)r‡   rˆ   r‰   rZ   rt   r¿   rƒ   rE   r@   r>   rf   rf   �  s   „ ò
ò.HòNó$r@   rf   c                   ó   — e Zd Zd„ Zd„ Zd„ Zy)r¹   c                 ó�   — t        j                  «       j                  | _        i | _        i | _        g | _        g | _        g | _        y rB   )	r¶   r·   r¸   Úchunk_idÚindexed_framesÚindexed_stacksÚframesÚstacksÚsamplesr`   s    r>   rZ   zProfileChunk.__init__Î  s:   € äŸ
™
›×(Ñ(ˆŒà ˆÔØ ˆÔØˆŒØˆŒØˆ�r@   c                 óp  — |D ]ÿ  \  }\  }}}	 || j                   vrºt        |«      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É   ÚlenrË   ÚappendrÌ   rÍ   rr   r
   rn   rs   )	rY   rw   rz   rx   r$   Ú	frame_idsrË   ÚiÚframe_ids	            r>   rt   zProfileChunk.writeØ  s%  € à28ò 	;Ñ.ˆCÑ.�(˜I vð;ð  4×#6Ñ#6Ñ6Ü'0°Ó';ò :™˜˜8Ø#¨4×+>Ñ+>Ò>Ü<?À×@SÑ@SÓ<T˜D×/Ñ/°Ñ9Ø ŸK™K×.Ñ.¨v°a©yÕ9ð:ô
 58¸×8KÑ8KÓ4L�D×'Ñ'¨Ñ1Ø—K‘K×&Ñ&ØGPÖQ¸8˜×,Ñ,¨XÓ6ÒQôð —‘×#Ñ#à%'Ø%(Ø$(×$7Ñ$7¸Ñ$Añöñ	;ùò Røô "ò ;ô +¬3¯<©<«>×:ð;ús)   Ž-D¼A=DÂ9D
Ã3DÄDÄ&D5Ä4D5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ÚplatformÚprofilerN   rÚ   )ÚreleaseÚenvironmentÚdist)rË   rÌ   rÍ   r�   rÏ   rq   Úidentr›   r   rÈ   r   Ústrip)rY   rN   r7   r8   rŒ   rß   ÚpayloadÚkeys           r>   rÃ   zProfileChunk.to_jsonõ  s   € ð —k‘kØ—k‘kØ—|‘|ô
 (×1Ñ1Ó3ö	 ð ô �F—L‘LÓ!ØœC §¡Ó,ð$ñ ò ñ	

ˆô 	Ø�HÑØÐ$Ñ%ØÐ$Ñ%Ø�NÑ#ô		
ð Ÿ™à  Ñ(Ü"ñð !ØØ&Øñ

ˆð 4ò 	9ˆCØ�s‰|Ñ'Ü" 7¨3¡<Ó0×6Ñ6Ó8�˜’ð	9ð ˆùò? s   ¸2C
N)r‡   rˆ   r‰   rZ   rt   rÃ   rE   r@   r>   r¹   r¹   Í  s   „ òò;ó:%r@   r¹   )Cr4   r~   rn   r�   r'   r¶   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   Útyping_extensionsr   Úsentry_sdk._typesr   r   r   r   r   r   r   r   ÚfloatÚintr    Úgevent.monkeyr%   Úgevent.threadpoolr&   Ú_ThreadPoolr‚   ÚImportErrorr(   r-   r?   rF   rH   rK   r6   rO   rQ   r0   r/   rg   rf   r¹   rE   r@   r>   ú<module>rõ      s*  ðÛ Û 	Û 
Û Û Û ß 'å %Ý (Ý *÷÷õ õ !áÝÝÝÝÝÝÝÝ+ßA÷÷ ñ  ØàØ!Øñ	
ó€OðÝ*Ý;à€JÙ ¨Ó0€Lð €
ò,ò^ ò( òòò"÷` ñ ` ôFAÐ 3ô AôHIÐ 3ô IðX Ð ÷-$ñ -$÷`Mò Møða ò Ø—:‘:€LØ‚Jðús   Â'D	 Ä	DÄD