U 췀g#@s*ddlZddlZddlZddlmZmZddlmZddlZddl m Z ddl m Z ddl mZddlmZerddlmZdd lmZdd lmZdd lmZdd lmZdd lmZddlmZd"ddZed#ddZddZddZed$ddZed%ddZdZdZddZ Gd d!d!Z!dS)&N)ThreadLock)contextmanager)Envelope)Session)format_timestamp) TYPE_CHECKING)Any)Callable)Dict) Generator)List)Optional)UnioncCsRtjdtdd|dkr tjj}|jj}|dkrN|jr>|jj ni}| dd}|S)zHDEPRECATED: Utility function to find out if session tracking is enabled.nThis function is deprecated and will be removed in the next major release. There is no public API replacement. stacklevelNauto_session_trackingF) warningswarnDeprecationWarning sentry_sdkHubcurrentscope_force_auto_session_trackingclientoptionsget)hub should_trackclient_optionsr#A/opt/hc_python/lib/python3.8/site-packages/sentry_sdk/sessions.py is_auto_session_tracking_enableds r% applicationc csvtjdtdd|dkr tjj}ttdtt|}W5QRX|rX|j |dz dVW5|rp| XdS)zgDEPRECATED: Use track_session instead Starts and stops a session automatically around a block. zeThis function is deprecated and will be removed in the next major release. Use track_session instead.rrNignore session_mode) rrrrrrcatch_warnings simplefilterr% start_session end_session)r r)r!r#r#r$r0s     rcCstjdtddt|S)zR DEPRECATED: Utility function to find out if session tracking is enabled. rrr)rrr!_is_auto_session_tracking_enabled)rr#r#r$&is_auto_session_tracking_enabled_scopeKs r/cCs(|j}|dkr$tj}|dd}|S)zF Utility function to find out if session tracking is enabled. NrF)rrZ get_clientrr)rr!r"r#r#r$r.\s   r.c cs2tjdtddt||d dVW5QRXdS)zDEPRECATED: This function is a deprecated alias for track_session. Starts and stops a session automatically around a block. zdThis function is a deprecated alias for track_session and will be removed in the next major release.rrr(N)rrr track_session)rr)r#r#r$auto_session_tracking_scopejsr1ccs6t|}|r|j|dz dVW5|r0|XdS)z Start a new session in the provided scope, assuming session tracking is enabled. This is a no-op context manager if session tracking is not enabled. r(N)r.r,r-)rr)r!r#r#r$r0{s  r0)exitedabnormalcrasheddcCst|t|dS)N)attrsZ aggregates)dictlistvalues)Zaggregate_statesr6r#r#r$make_aggregate_envelopesr:c@sFeZdZdddZddZddZdd Zd d Zd d ZddZ dS)SessionFlusher<cCs>||_||_g|_i|_d|_t|_t|_d|_d|_ dS)NT) capture_funcflush_intervalpending_sessionspending_aggregates_threadr _thread_lock_aggregate_lock_thread_for_pid_running)selfr=r>r#r#r$__init__szSessionFlusher.__init__c Cs|j}g|_|j|j}i|_W5QRXt}|D],}t|jtkrV||t}||q4|D]6\}}t|jtkr||t}| t ||qjt|jdkr||dS)Nr) r?rCr@rlenitemsMAX_ENVELOPE_ITEMSr= add_sessionZ add_sessionsr:)rFr?r@envelopesessionr6statesr#r#r$flushs$   zSessionFlusher.flushc sjtkrjdk rdSjjtkrJjdk rJW5QRdSfdd}t|d}d|_z |Wn&tk rd_ YW5QRdSX|_t_W5QRXdS)a% Check that we have an active thread to run in, or create one if not. 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. Ncs&jr"tjjrqdSN)rEtimesleepr>rOr#rFr#r$rAs z/SessionFlusher._ensure_running.._thread)targetTF) rDosgetpidrArBrdaemonstart RuntimeErrorrE)rFrAthreadr#rSr$_ensure_runnings    zSessionFlusher._ensure_runningc Cs|j|jdd}tt|}|j}|j|i}||i}d|krZt|j|d<|j dkrz| ddd|d<nT|j dkr| ddd|d<n4|j dkr| ddd|d<n| d dd|d <W5QRXdS) NF)Zwith_user_infostartedr4rr3Zerroredr2) rCZget_json_attrstuplesortedrIZtruncated_startedr@ setdefaultrstatusrerrors)rFrMr6Z primary_keyZ secondary_keyrNstater#r#r$add_aggregate_sessions      z$SessionFlusher.add_aggregate_sessioncCs2|jdkr||n|j||dS)Nrequest)r)rdr?appendto_jsonr[)rFrMr#r#r$rKs  zSessionFlusher.add_sessioncCs d|_dS)NF)rErSr#r#r$killszSessionFlusher.killcCs |dSrP)rhrSr#r#r$__del__szSessionFlusher.__del__N)r<) __name__ __module__ __qualname__rGrOr[rdrKrhrir#r#r#r$r;s % r;)N)Nr&)r&)r&)"rUrQr threadingrr contextlibrrZsentry_sdk.enveloperZsentry_sdk.sessionrZsentry_sdk.utilsrtypingrr r r r r rrr%rr/r.r1r0ZTERMINAL_SESSION_STATESrJr:r;r#r#r#r$s<