U 췀g1@sZdZddlZddlZddlmZddlmZddlZddlm Z ddl m Z ddl m Z mZmZddlmZmZdd lmZdd lmZmZmZmZmZdd lmZmZmZmZm Z m!Z!m"Z"dd lm#Z#dd l$m%Z%e%r&ddl$m&Z&ddl$m'Z'ddl$m(Z(ddl$m)Z)ddl$m*Z*ddl+m,Z,m-Z-edZ.dZ/dZ0dddZ1ddZ2GdddZ3dS)ze An ASGI middleware. Based on Tom Christie's `sentry-asgi `. N)deepcopy)partial)continue_trace)OP) _get_headers_get_request_data_get_url)DEFAULT_HTTP_METHODS_TO_CAPTURE nullcontext) track_session)SOURCE_FOR_STYLETRANSACTION_SOURCE_ROUTETRANSACTION_SOURCE_URLTRANSACTION_SOURCE_COMPONENTTRANSACTION_SOURCE_CUSTOM) ContextVarevent_from_exceptionHAS_REAL_CONTEXTVARSCONTEXTVARS_ERROR_MESSAGEloggertransaction_from_function_get_installed_modules) Transaction) TYPE_CHECKING)Any)Callable)Dict)Optional)Tuple)EventHintZsentry_asgi_middleware_appliedzgeneric ASGI request)endpointurlasgicCs0t|tj|ddd\}}tj||ddS)NF)typeZhandled)Zclient_optionsZ mechanism)hint)r sentry_sdkZ get_clientoptionsZ capture_event)excmechanism_typeeventr%r+J/opt/hc_python/lib/python3.8/site-packages/sentry_sdk/integrations/asgi.py_capture_exception?s  r-cCsBt|rt|dSt|r(t|St|dd}t|SdS)z Try to figure out if an application object supports ASGI3. This is how uvicorn figures out the application version as well. __await____call__N)inspectisclasshasattr isfunctionasyncioiscoroutinefunctiongetattr)appcallr+r+r,_looks_like_asgi3Js      r9c@sLeZdZdZddddefddZdd Zd d Zd d ZddZ ddZ dS)SentryAsgiMiddleware)r7r/transaction_styler) span_originhttp_methods_to_captureFr!r#ZmanualcCs|ststdt|tkr,td|tf|dko.innerr+)rDrNrOr+rMr,rCszSentryAsgiMiddleware._run_asgi2cs|j|||ddIdHS)NrGrI)rDrNrKrLr+r+r,rBszSentryAsgiMiddleware._run_asgi3c std}|ddk}|s|rz:|dkr@|||IdHWS|||IdHWSWn6tk r}zt||jd|dW5d}~XYnXtdzt}t |dd| d |_ t |j |d } || |d} ||j|\} } |d d } d| |jkr| d krPtt|d| | | |jdtdn ttj| | |jdtdd| tdjjdk rtjd|idnt tdzfdd}|dkr||||IdHWW5QRW5QRW5QRWS||||IdHWW5QRW5QRW5QRW`SWn8tk r}zt||jd|dW5d}~XYnXW5QRXW5QRXW5QRXW5tdXdS)NFr$ZlifespanrF)r)Trequest)Z session_moder#) asgi_scopemethod)httpZ websocketz {}.server)opnamesourceoriginz1[ASGI] Created transaction (continuing trace): %sz$[ASGI] Created transaction (new): %sz asgi.typezB[ASGI] Set transaction name and source on transaction: '%s' / '%s'rR)Zcustom_sampling_contextz[ASGI] Started transaction: %scs>dk r0|ddkod|k}|r0|d|IdHS)Nr$zhttp.response.startstatus)getZset_http_status)r*Zis_http_responserL transactionr+r,_sentry_wrapped_sendsz;SentryAsgiMiddleware._run_app.._sentry_wrapped_send)!_asgi_middleware_appliedr[r7 Exceptionr-r)setr&Zisolation_scoper Zclear_breadcrumbs_namerevent_processorZadd_event_processor _get_transaction_name_and_sourcer;upperr=rrformatr<rdebugrrZ HTTP_SERVERZset_tagrWrXZstart_transactionr )rDrNrKrLrHZis_recursive_asgi_middlewareZ is_lifespanr(Z sentry_scope processortyZtransaction_nameZtransaction_sourcerSr^r+r\r,rJs           48:zSentryAsgiMiddleware._run_appcCs|di}|t|t||d<|dtkoH|ddtttfk}|s||j |\}}||d<d|i|d<t d|d|dd|S)NrQr]Ztransaction_inforXzF[ASGI] Set transaction name and source in event_processor: '%s' / '%s') r[updaterr_DEFAULT_TRANSACTION_NAMErr rrdr;rrg)rDr*r%rRZ request_dataZ already_setrWrXr+r+r,rc s4    z$SentryAsgiMiddleware.event_processorc Csd}t|}|d}|dkrZ|d}|r:t|p6d}qt||dkrJdnddd}t}nN|dkr|d}|rt|d d}|dk r|}nt||dkrdnddd}t}|dkrt}t}||fS||fS) Nr$r!rTrUws)hostr"routepath)r r[rrrr6rkr ) rDr;rRrWrXrir!rnror+r+r,rd-s,    z5SentryAsgiMiddleware._get_transaction_name_and_sourceN) __name__ __module__ __qualname__ __slots__r rErCrBrJrcrdr+r+r+r,r:Zs  3g#r:)r#)4__doc__r4r0copyr functoolsrr&Zsentry_sdk.apirZsentry_sdk.constsrZ$sentry_sdk.integrations._asgi_commonrrrZ$sentry_sdk.integrations._wsgi_commonr r Zsentry_sdk.sessionsr Zsentry_sdk.tracingr r rrrZsentry_sdk.utilsrrrrrrrrtypingrrrrrrZsentry_sdk._typesrr r_rkr?r-r9r:r+r+r+r,s6     $