
    Yf4              	       v   d 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Zddl	m
Z
mZ ddlmZ ddlZddlmZ ddlmZ ddlmZ ddlmZmZmZmZmZmZmZ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+ ddl,Zddlm-Z-m.Z.m/Z/ e0Z1 e+de0e1e2d      Z3e%e2   Z4 e+de0e&e0   e0e2e&e0   d      Z5 e+dde0i      Z6 e+de%e5   e%e4   e%e3   e$e1e6f   d      Z7 e+dde0i      Z8e)e0e2e0f   Z9e)e9df   Z:e)e2e2f   Z;e)e;e:e%e5   f   Z<e(e)e1e<f      Z=	 dd l>m?Z? dd!l@mAZA  e?d"d#      ZBdaEd$ZFd%ZGd& ZHd' ZId( ZJd)ZKeKfd*ZLd+ ZMd, ZNerd- ZOnd. ZO e2d/      ZP G d0 d1      ZQ G d2 d3e
      ZR G d4 d5eR      ZS G d6 d7eR      ZTy# eC$ r ej                  ZBdZAY nw xY w)8a  
This file is originally based on code from https://github.com/nylas/nylas-perftools,
which is published under the following license:

The MIT License (MIT)

Copyright (c) 2014 Nylas

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
    N)ABCabstractmethod)deque)PY311)LRUCache)TYPE_CHECKING)capture_internal_exceptionfilename_for_moduleget_current_thread_meta	is_geventis_valid_sample_rateloggernanosecond_timeset_in_app_in_frames)	FrameType)Any)Callable)Deque)Dict)List)Optional)Set)Sequence)Tuple)	TypedDict)EventSamplingContextProfilerModeProcessedSampleelapsed_since_start_ns	thread_idstack_idProcessedFrame)abs_pathfilenamefunctionlinenomoduleProcessedThreadMetadatanameProcessedProfileframesstackssamplesthread_metadataProfileContext
profile_id.)get_original)
ThreadPooltimesleepe      c                     | d   }|y| d   }||dkD  ry| d   j                  d      }|t        j                  d       |dkD  ryy)Nprofiles_samplerTprofiles_sample_rater   _experimentszy_experiments['profiles_sample_rate'] is deprecated. Please use the non-experimental profiles_sample_rate option directly.F)getr   warning)optionsr;   r<   s      S/var/www/highfloat_scraper/venv/lib/python3.12/site-packages/sentry_sdk/profiler.pyhas_profiling_enabledrB      sr    12#"#9:',@1,D">2667MN'	

  !#    c                    t         t        j                  d       yt        }t	               rt
        j                  }nt        j                  }| j                  d      | d   }n>| j                  di       j                  d      }|t        j                  d       |xs |}|t        j                  k(  s|dk(  rt        |      a n:|t
        j                  k(  rt        |      a nt        dj                  |            t        j                  d	j                  t         j                  
             t         j                          t        j                  t               y)Nz%[Profiling] Profiler is already setupFprofiler_moder=   zk_experiments['profiler_mode'] is deprecated. Please use the non-experimental profiler_mode option directly.r7   	frequencyzUnknown profiler mode: {}z.[Profiling] Setting up profiler in {mode} mode)modeT)
_schedulerr   debugDEFAULT_SAMPLING_FREQUENCYr   GeventSchedulerrH   ThreadSchedulerr>   r?   
ValueErrorformatsetupatexitregisterteardown_profiler)r@   rG   default_profiler_moderE   s       rA   setup_profilerrU      s'    <=*I{
 !0 4 4 / 4 4{{?#/0NB7;;OL$NNB &>)> 	---G#$y9
	/..	.$y9
4;;MJKK
LL8??Z__?U 
OO%&rC   c                  <    t         t         j                          d a y N)rI   teardown rC   rA   rS   rS      s    
 JrC      c                 r   t        |      }| "| j                  }|j                  |        |} | "t        d |D              }g }t	        |      D ]K  \  }}	|j                  |	      }
|
"t        |	||   |      }
|j                  |	|
       |j                  |
       M t        |      t        |      f}|||fS )aA  
    Extracts the stack starting the specified frame. The extracted stack
    assumes the specified frame is the top of the stack, and works back
    to the bottom of the stack.

    In the event that the stack is more than `MAX_STACK_DEPTH` frames deep,
    only the first `MAX_STACK_DEPTH` frames will be returned.
    maxlenc              3   2   K   | ]  }t        |        y wrW   )frame_id).0	raw_frames     rA   	<genexpr>z extract_stack.<locals>.<genexpr>
  s     Fihy)Fs   )
r   f_backappendtuple	enumerater>   extract_framesetlenhash)ra   cachecwdmax_stack_depth
raw_framesrc   	frame_idsr.   ifidframer#   s               rA   extract_stackrs      s      o.J

!!)$	 

 F:FFIFI& 3		#=!#z!}c:EIIc5!e$ :Y/HY&&rC   c                 Z    | j                   j                  | j                  t        |       fS rW   )f_codeco_filenamef_linenoget_frame_name)ra   s    rA   r_   r_   #  s&    (()*<*<nY>WXXrC   c                     |j                   j                  }	 |j                  d   }t        j
                  j                  ||      |t        ||      xs d | d   |j                  dS # t        $ r d }Y Nw xY w)N__name__r9   )r%   r)   r&   r'   r(   )	ru   rv   	f_globals	Exceptionospathjoinr
   rw   )rq   ra   rl   r%   r)   s        rA   rg   rg   (  s~    ++H$$Z0  GGLLh/'9ATF$$   s   A( (A65A6c                 .    | j                   j                  S rW   )ru   co_qualname)rr   s    rA   rx   rx   G  s    ||'''rC   c                 D   | j                   }|j                  }|j                  }	 |rj|d   dk(  rbd| j                  v rT| j                  d   j                  j
                  D ].  }||j                  v sdj                  |j                  |      c S  	 |r`|d   dk(  rXd| j                  v rJ| j                  d   j
                  D ].  }||j                  v sdj                  |j                  |      c S  |S # t        t        f$ r Y vw xY w# t        t        f$ r Y |S w xY w)Nr   selfz{}.{}cls)ru   co_varnamesco_namef_locals	__class____mro____dict__rO   rz   AttributeErrorrN   )rr   ru   r   r+   r   s        rA   rx   rx   M  s.    (( ~~	 Nf,enn, >>&1;;CC BCs||+&~~cllDAAB	 Ne+U^^+ >>%088 BCs||+&~~cllDAAB - 
+ 		  
+ 	
 	s=   AC7 3C7 C7 AD D 4D 7D	D	DDg   Bc                   T    e Zd Z	 	 ddZd Zd Zd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zy)ProfileNc                    |t         n|| _        || _        t        j                         j
                  | _        |j                  | _        t               d   xs d| _	        d | _
        	 |j                  | _        d| _        d| _        i | _        i | _        g | _        g | _        g | _        d| _        | |_        y # t        $ r
 d| _        Y Rw xY w)Nr   F)rI   	schedulerhubuuiduuid4hexevent_idsampledr   _default_active_thread_idactive_thread_id_start_timestamp_monotonic_nsstart_nsr   stop_nsactiveindexed_framesindexed_stacksr.   r/   r0   unique_samples_profile)r   transactionr   r   s       rA   __init__zProfile.__init__  s     (1'8i

(( #** *A)B1)E)J& $	'EEDM   #  	DM	s   )B: :CCc                     t               d   | _        t        j                  dj	                  | j                               y )Nr   z.[Profiling] updating active thread id to {tid})tid)r   r   r   rJ   rO   r   s    rA   update_active_thread_idzProfile.update_active_thread_id  s;     7 9! <<CC)) D 	
rC   c                 2   | j                   st        j                  d       d| _         y| j                  t        j                  d       d| _         yt        j
                  j                         }|j                         sd| _         y|j                  }t        |j                  d            r |d   |      }n|d   |d   }n|d   j                  d      }|t        j                  d       d| _         yt        |d	
      st        j                  d       d| _         yt        j                         t        |      k  | _         | j                   rt        j                  d       yt        j                  dj                  t        |                   y)a  
        Sets the profile's sampling decision according to the following
        precedence rules:

        1. If the transaction to be profiled is not sampled, that decision
        will be used, regardless of anything else.

        2. Use `profiles_sample_rate` to decide.
        z@[Profiling] Discarding profile because transaction is discarded.FNz@[Profiling] Discarding profile because profiler was not started.r;   r<   r=   zA[Profiling] Discarding profile because profiling was not enabled.	Profiling)sourcez>[Profiling] Discarding profile because of invalid sample rate.z [Profiling] Initializing profilezk[Profiling] Discarding profile because it's not included in the random sample (sample rate = {sample_rate}))sample_rate)r   r   rJ   r   
sentry_sdkScope
get_client	is_activer@   callabler>   r   r?   randomfloatrO   )r   sampling_contextclientr@   r   s        rA   _set_initial_sampling_decisionz&Profile._set_initial_sampling_decision  su    ||LLR !DL >>!LLR !DL!!,,.! DL..GKK 2345'"456FGK+,8!"89K!.1556LMK LLS !DL#KDNNP !DL
 }}{);;<<LL;<LL}  E  E %k 2 E rC   c                     | j                   r| j                  ry | j                  sJ d       t        j                  d       d| _        | j
                  st               | _        | j                  j                  |        y )NNo scheduler specifiedz[Profiling] Starting profileT)r   r   r   r   rJ   r   r   start_profilingr   s    rA   startzProfile.start  s[    ||t{{~~777~34}}+-DM&&t,rC   c                     | j                   r| j                  sy | j                  sJ d       t        j                  d       d| _        t               | _        y )Nr   z[Profiling] Stopping profileF)r   r   r   r   rJ   r   r   r   s    rA   stopzProfile.stop  sB    ||4;;~~777~34&(rC   c                     t         j                  j                  j                         }|j                  }| |_        ||f| _        | j                          | S rW   )r   scoper   get_isolation_scopeprofile_context_manager_stater   )r   r   old_profiles      rA   	__enter__zProfile.__enter__  sG      &&::<mm',k&:#

rC   c                 T    | j                          | j                  \  }}| `||_        y rW   )r   r   r   )r   tyvaluetbr   r   s         rA   __exit__zProfile.__exit__  s(    		!88{'#rC   c                 <   | j                   sy || j                  k  ry || j                  z
  }|t        kD  r| j                          y | xj                  dz  c_        t        |      }|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)N   r    )r   r   MAX_PROFILE_DURATION_NSr   r   strr   rf   r   ri   r.   rd   r/   r0   r   r	   sysexc_info)r   tssampleoffsetr!   r   r#   ro   r.   rp   r_   s              rA   writezProfile.write'  s|   {{dmm#++IIKq !$V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 ##2H%($($7$7$A	; R " ; +3<<>:;s+   4-E1"A=E1E,
53E1,E11&FFc                     t        j                         D ci c]-  }t        |j                        dt        |j                        i/ }}| j
                  | j                  | j                  |dS c c}w )Nr+   r-   )	threadingrf   r   identr+   r.   r/   r0   )r   threadr1   s      rA   processzProfile.processS  sv     $--/	
  FKK(  
 
 kkkk||.	
 	

s   2A0c                 R   | j                         }t        |d   |d   |d   |d          |j                  d      | j                  d||j                  dd      |d	   d
dt	        j
                         it	        j                         t	        j                         dt	        j                         t	        j                         d|d   |d   dt        | j                  | j                  z
        |d   d   d   t        | j                  | j                  n| j                        dgdS )Nr.   in_app_excludein_app_includeproject_rootenvironmentpythonrelease start_timestamp1architecture)r+   versionr   r   0contextstracetrace_id)idr+   relative_start_nsrelative_end_nsr   r   )r   r   platformr   r   	timestampr   devicer}   runtimetransactions)r   r   r>   r   r   machinesystemr   python_implementationpython_versionr   r   r   r   r   )r   	event_optr@   r   s       rA   to_jsonzProfile.to_jsong  s7   ,,.H$%$%N#		
 %==7  }}Y3"#45 0 0 2 !)#++-
 !668#224 $J/%m4 *- (+4<<$--+G'H )* 5g >z J(+008 66!22)'&
 &	
rC   c                    t         j                  j                         }|j                         syt	        |j
                        sy| j                  | j                  s*|j                  r|j                  j                  dd       y| j                  t        k  r?|j                  r|j                  j                  dd       t        j                  d       yy)NFr   r   )data_categoryinsufficient_dataz<[Profiling] Discarding profile because insufficient samples.T)r   r   r   r   rB   r@   r   	transportrecord_lost_eventr   PROFILE_MINIMUM_SAMPLESr   rJ   )r   r   s     rA   validzProfile.valid  s    !!,,.!$V^^4<<t||  22! 3  !88  22'y 3  LLWXrC   )NN)rz   
__module____qualname__r   r   r   r   r   r   r   r   r   r   r   rY   rC   rA   r   r     sF     	'$R
GR
-)
$*;X
(1
frC   r   c                   T    e Zd ZdZd Zd Zd Zed        Zed        Z	d Z
d Zd	 Zy
)	Schedulerunknownc                     d|z  | _         | j                         | _        t        d      | _        t               | _        y )Ng      ?rZ   r\   )intervalmake_samplersamplerr   new_profilesrh   active_profiles)r   rG   s     rA   r   zScheduler.__init__  s6    i((* "-"urC   c                 &    | j                          | S rW   )rP   r   s    rA   r   zScheduler.__enter__  s    

rC   c                 $    | j                          y rW   )rX   )r   r   r   r   s       rA   r   zScheduler.__exit__  s    rC   c                      y rW   rY   r   s    rA   rP   zScheduler.setup       	rC   c                      y rW   rY   r   s    rA   rX   zScheduler.teardown  r  rC   c                      y)z
        Ensure the scheduler is running. By default, this method is a no-op.
        The method should be overridden by any implementation for which it is
        relevant.
        NrY   r   s    rA   ensure_runningzScheduler.ensure_running  s     rC   c                 Z    | j                          | j                  j                  |       y rW   )r  r  rd   )r   r   s     rA   r   zScheduler.start_profiling  s"      )rC   c                 Z     t        j                         t        d       fd}|S )N   )max_sizec            
         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 ]2  }	|	j                  r|	j!                  ||       "|j#                  |	       4 |D ]  }	j                  j%                  |	        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  r  ri   r   r   _current_framesitemsr   rs   r   r	   r   rangeaddpopleftr   r   rd   remove)argskwargsr  nowr   rr   r   _inactive_profilesr   rk   rl   r   s             rA   _sample_stackz-Scheduler.make_sampler.<locals>._sample_stack  sM    $$T-A-A  t001L!#C	 '*&9&9&;&A&A&C"U X}UE3?@ ( <( F$$(():):)B)B)DEF !#// 6>>MM#v. &,,W56 - 5$$++G45G "  +3<<>:	s#   %D4  "D.D4 .D4 4&EE)r}   getcwdr   )r   r  rk   rl   s   ` @@rA   r  zScheduler.make_sampler  s&    iik#&=	5~ rC   N)rz   r   r   rH   r   r   r   r   rP   rX   r  r   r  rY   rC   rA   r   r     sN    D%
    *
ErC   r   c                   B     e Zd ZdZdZdZ fdZd Zd Zd Z	d Z
 xZS )	rM   zr
    This scheduler is based on running a daemon thread that will call
    the sampler at a regular interval.
    r   zsentry.profiler.ThreadSchedulerc                     t         |   |       d| _        d | _        d | _        t        j                         | _        y )NrF   F)superr   runningr   pidr   Locklockr   rG   r   s     rA   r   zThreadScheduler.__init__4  s8    9- NN$	rC   c                      y rW   rY   r   s    rA   rP   zThreadScheduler.setup>      rC   c                 z    | j                   r/d| _         | j                  | j                  j                          y y y NFr!  r   r   r   s    rA   rX   zThreadScheduler.teardownB  4    << DL{{&  " ' rC   c                    t        j                         }| j                  r| j                  |k(  ry| j                  5  | j                  r| j                  |k(  r
	 ddd       y|| _        d| _        t        j                  | j                  | j                  d      | _	        	 | 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)aE  
        Check that the profiler has an active thread to run in, and start one if
        that's not the case.

        Note that this might fail (e.g. in Python 3.12 it's not possible to
        spawn new threads at interpreter shutdown). In that case self.running
        will be False after running this function.
        NT)r+   targetdaemonF)r}   getpidr!  r"  r$  r   Threadr+   runr   r   RuntimeErrorr   r"  s     rA   r  zThreadScheduler.ensure_runningI  s     iik <<DHHOYY 	 ||C	 	 DHDL
 $**		$((SWXDK!!#	 	      %"+	 	 !	 	s/   C,#?C,#CC)C,(C))C,,C5c                 $   t        j                         }| j                  rp| j                          t        j                         |z
  }|| j                  k  rt        | j                  |z
         t        j                         }| j                  roy y rW   r6   perf_counterr!  r  r   thread_sleepr   lastelapseds      rA   r1  zThreadScheduler.runp  k      "llLLN
 '')D0G&T]]W45 $$&D llrC   rz   r   r   __doc__rH   r+   r   rP   rX   r  r1  __classcell__r   s   @rA   rM   rM   +  s.    
 D,D%#%N'rC   rM   c                   B     e Zd ZdZdZdZ fdZd Zd Zd Z	d Z
 xZS )	rL   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.
    geventzsentry.profiler.GeventSchedulerc                     t         $t        dj                  | j                              t        |   |       d| _        d | _        d | _        t        j                         | _        y )Nz"Profiler mode: {} is not availablerF   F)r5   rN   rO   rH   r   r   r!  r   r"  r   r#  r$  r%  s     rA   r   zGeventScheduler.__init__  s]     AHHSTT9- 
 NN$	rC   c                      y rW   rY   r   s    rA   rP   zGeventScheduler.setup  r'  rC   c                 z    | j                   r/d| _         | j                  | j                  j                          y y y r)  r*  r   s    rA   rX   zGeventScheduler.teardown  r+  rC   c                    t        j                         }| j                  r| j                  |k(  ry | j                  5  | j                  r| j                  |k(  r
	 d d d        y || _        d| _        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)NTr   F)
r}   r/  r!  r"  r$  r5   r   spawnr1  r2  r3  s     rA   r  zGeventScheduler.ensure_running  s    iik <<DHHOYY 	 ||C	 	 DHDL$Q-DK!!$((+	 	     %"%	 		 	s/   C#C%B11CCCCCc                 $   t        j                         }| j                  rp| j                          t        j                         |z
  }|| j                  k  rt        | j                  |z
         t        j                         }| j                  roy y rW   r5  r8  s      rA   r1  zGeventScheduler.run  r;  rC   r<  r?  s   @rA   rL   rL     s-     D,D%$#8'rC   rL   )Ur=  rQ   r}   r   r   r   r   r6   r   abcr   r   collectionsr   r   sentry_sdk._compatr   sentry_sdk._lru_cacher   sentry_sdk._typesr   sentry_sdk.utilsr	   r
   r   r   r   r   r   r   typesr   typingr   r   r   r   r   r   r   r   r   typing_extensionsr   sentry_sdk.tracingr   r   r   r   ThreadIdintr   ProcessedStackr$   r*   r,   r2   FrameIdFrameIdsStackIdExtractedStackExtractedSamplegevent.monkeyr4   gevent.threadpoolr5   r7  ImportErrorr7   rI   rK   r   rB   rU   rS   MAX_STACK_DEPTHrs   r_   rg   rx   r   r   r   rM   rL   rY   rC   rA   <module>r^     sd  6  	   
    #   $ * +	 	 	 +FFH&)!	
O #YN sm	
	N (!	
 !>*>*O,#H.E$EF		
 	sN
 	G
 Wc\"H CHoG7Hd>.BBCNuX~%=>?O*,0L 
 ! 
  .0f  $	-'`Y
: 	(-` d) r rj	s slU'i U'pZ'i Z'w  ::LJs   4F" "F87F8