B Yt@sdZddlmZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ddl m Z ddl mZddlmZddlmZejd krddlZnddlZydd lmZWn ek rdd lmZYnXddlZdd lmZdd lmZdd l m!Z!m"Z"ddl#m$Z$m%Z%m&Z&m'Z'ddl(m)Z)m*Z*ddl+m,Z,ddl-m.Z.ddl/m0Z0m1Z1ddl2m3Z3ddl4m5Z5m6Z6ddl7ZdZ8da9dZ:dej;dZZ?ddZ@GdddeAZBGdddeCZDGdd d eCZEGd!d"d"eEZFdS)#z raven.base ~~~~~~~~~~ :copyright: (c) 2010-2012 by the Sentry Team, see AUTHORS for more details. :license: BSD, see LICENSE for more details. )absolute_importN)datetime)isclass)Random) FunctionType)local)) get_ident)defaults) RemoteConfig)APIError RateLimited)json get_versionsget_auth_header merge_dicts) text_type iteritems) to_unicode) transform)get_stack_infoiter_stack_frames)TransactionStack)TransportRegistrydefault_transports)Clientpythonz raven-python)nameversioncCs"tj}t|dd}|dk r|SdS)N raven_client)sys excepthookgetattr)hookclientr&;/opt/alt/python37/lib/python3.7/site-packages/raven/base.pyget_excepthook_clientEs r(c@seZdZddZdS)ModuleProxyCachecCs2|dd\}}tt|ii|g|}|||<|S)N.)rsplitr# __import__)selfkeymodule class_namehandlerr&r&r' __missing__Ms zModuleProxyCache.__missing__N)__name__ __module__ __qualname__r3r&r&r&r'r)Lsr)c@s>eZdZdZdZddZddZdddZd d Zd d Z d S) ClientStater+rcCs|j|_d|_d|_d|_dS)Nr)ONLINEstatus last_check retry_number retry_after)r.r&r&r'__init__\szClientState.__init__cCs@|j|jkrdS|jp$t|jdd}t|j|krd?Z(dcd@dAZ)dddBdCZ*dedDdEZ+dFdGZ,dHdIZ-dJdKZ.dLdMZ/dfdNdOZ0dPdQZ1dgdRdSZ2dhdUdVZ3dWdXZ4dYdZZ5e5Z6ed[d\Z7e7j8d]d\Z7dS)iraU The base Raven client. Will read default configuration from the environment variable ``SENTRY_DSN`` if available. >>> from raven import Client >>> # Read configuration from ``os.environ['SENTRY_DSN']`` >>> client = Client() >>> # Specify a DSN explicitly >>> client = Client(dsn='https://public_key:secret_key@sentry.local/project_id') >>> # Record an exception >>> try: >>> 1/0 >>> except ZeroDivisionError: >>> ident = client.get_ident(client.captureException()) >>> print "Exception caught; reference is %s" % ident raven6)Z transportsNFTc Ks~| } t|_||_|j} t|_td| j| j f|_ td|_ td|_ i|_ |||t| dppg|_t| dpg|_t| dp| dptj|_t| dptj|_t| d tj|_t| d ptj|_t| d ptj|_ | d |_!| d d|_"| d|_#|j#dkr:tj$|_#| d} | dkrfdt%t&dgddi} | |_'| dpzi|_(| dpd|_)| dpt*j+d|_,|-| d|_.| ddk r| dnd|_/t0|_1t| dpd|_2t3|_4t5||_6|7s"|j 8dt9dkr0|a9t:|_;||_} | ||_?|rb|@|rp|A|B|dS)Nz%s.%sz sentry.errorszsentry.errors.uncaught include_paths exclude_pathsrmachineauto_log_stackscapture_localsstring_max_lengthlist_max_lengthsiteinclude_versionsT processorscontextzsys.argvargvtags environmentreleaseZHEROKU_SLUG_COMMITrepos sample_rater+ignore_exceptionsr&zaRaven is not configured (logging is disabled). Please see the documentation for more information.r)Context)Cr _local_stateraise_send_errors __class__r7statelogging getLoggerr5r4logger error_loggeruncaught_logger_transport_cacheset_dsnsetgetrIrJrr NAMErboolZAUTO_LOG_STACKSrLZCAPTURE_LOCALSrMintZMAX_LENGTH_STRINGrNZMAX_LENGTH_LISTrOrPrQrRZ PROCESSORSr#r!extrarUrVosenvironrW _format_reposrXrYr transactionrZr) module_cacher_random is_enabledinfoRavenget_thread_identZmain_thread_idenable_breadcrumbsZ raven.contextr[_contextinstall_sys_hookinstall_logging_hookhook_libraries)r.dsnr] transportryrzr{rwZ _random_seedoptionsoclsrSr[r&r&r'r=sn              zClient.__init__cCsL|siSi}x:t|D].\}}|ddkr.handle_exception)rr!r"r )r.rr&)r.r'rys  zClient.install_sys_hookcCsddlm}|dS)Nr)rz)raven.breadcrumbsrz)r.rzr&r&r'rzs zClient.install_logging_hookcCsddlm}||dS)Nr)r{)rr{)r. librariesr{r&r&r'r{s zClient.hook_librariescCs|j||dS)N)rregister_scheme)rschemeZtransport_classr&r&r'r"szClient.register_schemeccs$x|jD]}|j||VqWdS)N)rRrq)r. processorr&r&r'get_processors&s zClient.get_processorscCs<|js iStj}t|j}d|d|d|d|d<|S)Nz {0}.{1}.{2}rr+r r)rQr! version_inforrIr)r.rmodulesr&r&r'get_module_versions*s zClient.get_module_versionscCstdt|S)z Returns a searchable string representing a message. >>> result = client.capture(**kwargs) >>> ident = client.get_ident(result) zVClient.get_ident is deprecated. The event ID is now returned as the result of capture.)warningswarnDeprecationWarning)r.rr&r&r'r 7szClient.get_identcCs|j||S)N)rq)r.rr&r&r' get_handlerCszClient.get_handlercCs*|s dS|j}|s|Sd||fS)z Returns a public DSN which is consumable by raven-js >>> # Return scheme-less DSN >>> print client.get_public_dsn() >>> # Specify a scheme to use (http or https) >>> print client.get_public_dsn('https') Nz%s:%s)rsrget_public_dsn)r.rurlr&r&r'rFs  zClient.get_public_dsnc Csvd}d}y2t|do|djj}|dr4|djp6d}Wnttfk rRYnX|dt|d|t|d|fS)Nrr r+)idtb_framef_codetb_lastiAttributeError IndexError)r.rZcode_idZlast_idr&r&r'_get_exception_keyWs  zClient._get_exception_keycCs||}||jjkS)N)rrSexceptions_to_skip)r.rr/r&r&r'skip_error_for_loggingis zClient.skip_error_for_loggingcCs||}|jj|dS)N)rrSradd)r.rr/r&r&r'record_exception_seenms zClient.record_exception_seenc  stj} t|jj|}|di|did|kr@d|}||} | jf| } | dd}| drt|d}x$t | D]\}}||kr~|||<q~W|dkrd|kr|j }|rd|kr|d krt }n|}t||j|jd }|d|i|jrx||D]|}| d dk rq| d s0qd rFd|d <n8tfdd|jDoxtfdd|jD |d <qW|s|j}| ds| dptj|d<| ds|j|d<| ds||d<|jdk r|j|d<|jdk r|j|d<t|j|d||d<t|j |d||d<| ddpN|j!}|rf|dd||rt||d<| r| |d<x"|"D]}||#|qWd|kr| d| $||d<x*t |dD]\}}t%||d|<qWx,t |dD]\}}|||d|<qW|d|j&j'|d|pBt()|d||d| |dt*|dt+|d |j,|j-r|jj./}|r|d!d"|i|S)#z Captures, processes and serializes an event into a dict object The result of ``build_msg`` should be a standardized dict, with all default values available. rUrlr*zraven.events.%sculpritN exception stacktraceT)Z transformerrMZin_appr0zraven.Fc3s|]}|VqdS)N) startswith).0x)rr&r' sz#Client.build_msg..c3s|]}|VqdS)N)r)rr)rr&r'rsrZ server_namerrWrVrP fingerprintmessageproject timestamp time_spentevent_idplatformZsdkrX breadcrumbsvalues)0uuidZuuid4hexrrSdata setdefaultrcapturepoprhrrLrrrrMupdaterI _iter_framesranyrJrppeekr`rCrrrWrVrUrlrPrprocessZ to_stringrrrrutcnow PLATFORM_NAME SDK_VALUErXrwrZ get_buffer)r. event_typerdaterrlstack public_keyrUrkwargsrr2rrkvframes stack_infoframerPrr/rZcrumbsr&)rr' build_msgqs              $                zClient.build_msgcCst||j|jdS)N)rOrN)rrOrN)r.rr&r&r'rszClient.transformcCs|jS)aT Updates this clients thread-local context for future events. >>> def view_handler(view_func, *args, **kwargs): >>> client.context.merge(tags={'key': 'value'}) >>> try: >>> return view_func(*args, **kwargs) >>> finally: >>> client.context.clear() )rx)r.r&r&r'rSs zClient.contextcCs|jd|iS)z{ Update the user context for future events. >>> client.user_context({'email': 'foo@example.com'}) user)rSmerge)r.rr&r&r' user_contextszClient.user_contextcKs|jd|iS)z| Update the http context for future events. >>> client.http_context({'url': 'http://example.com'}) Zrequest)rSr)r.rrr&r&r' http_contextszClient.http_contextcKs|jd|iS)zo Update the extra context for future events. >>> client.extra_context({'foo': 'bar'}) rl)rSr)r.rrr&r&r' extra_context$szClient.extra_contextcKs|jd|iS)zr Update the tags context for future events. >>> client.tags_context({'version': '1.0'}) rU)rSr)r.rrr&r&r' tags_context.szClient.tags_contextc Ks|s dS| d} | dk r^|| r,dS|| sT|jjd| dtddS|| |j ||||||fd|i| }|dkr|j }|j |kr|j f||d|j_|dS)a Captures and processes an event and pipes it off to SentryClient.send. To use structured data (interfaces) with capture: >>> capture('raven.events.Message', message='foo', data={ >>> 'request': { >>> 'url': '...', >>> 'data': {}, >>> 'query_string': '...', >>> 'method': 'POST', >>> }, >>> 'logger': 'logger.name', >>> }, extra={ >>> 'key': 'value', >>> }) The finalized ``data`` structure contains the following (some optional) builtin values: >>> { >>> # the culprit and version information >>> 'culprit': 'full.module.name', # or /arbitrary/path >>> >>> # all detectable installed modules >>> 'modules': { >>> 'full.module.name': 'version string', >>> }, >>> >>> # arbitrary data provided by user >>> 'extra': { >>> 'key': 'value', >>> } >>> } :param event_type: the module path to the Event class. Builtins can use shorthand class notation and exclude the full module path. :param data: the data base, useful for specifying structured data interfaces. Any key which contains a '.' will be assumed to be a data interface. :param date: the datetime of this event :param time_spent: a integer value representing the duration of the event (in milliseconds) :param extra: a dictionary of additional standard metadata :param stack: a stacktrace for the event :param tags: dict of extra tags :param sample_rate: a float in the range [0, 1] to sample this message :return: a tuple with a 32-length string identifying this event Nrz*Not capturing exception due to filters: %sr)rrUr)rsrhrshould_capturerbrtr!rrrrYrrrandomsendr\ last_event_id) r.rrrrrlrrUrYrrr&r&r'r9s*5       zClient.capturecCs |jS)zg Return a boolean describing whether the client should attempt to send events. )rZ is_active)r.r&r&r'rsszClient.is_enabledccs\d|kr$x|ddD] }|VqWd|krXx*|dddddgD] }|VqJWdS)Nrrrr)rh)r.rrr&r&r'rs  "zClient._iter_framescCs|jdS)N)r_rE)r.r&r&r'_successful_sendszClient._successful_sendcCsnd}t|tr8t|tr|j}|jdt|j|jn|jjd||dd|id| ||j j |ddS)Nrz*Sentry responded with an API error: %s(%s)z,Sentry responded with an error: %s (url: %s)Tr)rrl)r<) isinstancer rr<rcerrortyper4r_log_failed_submissionr_rD)r.excrrr<r&r&r' _failed_sends    zClient._failed_sendc Cs|dd}|g}d|krd|dddkrxR|dddddgD]2}|d|d d |d d|d d dqLW|j|dS)zj Log a reasonable representation of an event that should have been sent to Sentry rzrrrrrz- File "%(fn)s", line %(lineno)s, in %(func)sfilenameZunknown_filenamelinenofunctionZunknown_function)fnrfuncN)rrhappendrdr)r.rroutputrr&r&r'rs "  zClient._log_failed_submissionc s|dkr i}js4js4dSjdtfdd}y@j }|j r| |j |n| | Wn2tk r}zjr||Wdd}~XYnXdS)Nz"Sending message of length %d to %scs|dS)N)rdecode)e)rr.rr&r' failed_sendsz'Client.send_remote..failed_send)r]r_rBrrrbrlenrZ get_transportZis_asyncZ async_sendrr Exception)r.rrheadersrr}rr&)rr.rr' send_remotes&    zClient.send_remotecKs||}|j||dS)zV Serializes the message and passes the payload onto ``send_encoded``. ) auth_header)encode send_encoded)r.rrrr&r&r'rs z Client.sendcKsbdtjf}|s4t}t|j|||jj|jjd}|||dd}|j f|jj ||d|S)z Given an already serialized message, signs the message and passes the payload off to ``send_remote``. zraven-python/%s)protocolrr%Zapi_keyZ api_secretzapplication/octet-stream)z User-Agentz X-Sentry-AuthzContent-Encodingz Content-Type)rrr) rGVERSIONr@rprotocol_versionrrZ secret_keyget_content_encodingrZstore_endpoint)r.rrrZ client_stringrrr&r&r'rs$  zClient.send_encodedcCsdS)Ndeflater&)r.r&r&r'rszClient.get_content_encodingcCstt|dS)z8 Serializes ``data`` into a raw string. utf8)zlibcompressrdumpsr)r.rr&r&r'r sz Client.encodecCstt|dS)z2 Unserializes a string, ``data``. r)rloadsr decompressr)r.rr&r&r'rsz Client.decodecKs|jdd|i|S)zr Creates an event from ``message``. >>> client.captureMessage('My event just happened!') raven.events.Messager)r)r)r.rrr&r&r'captureMessageszClient.captureMessagecKs,|dks|dkrt}|jdd|i|S)a Creates an event from an exception. >>> try: >>> exc_info = sys.exc_info() >>> client.captureException(exc_info) >>> finally: >>> del exc_info If exc_info is not provided, or is set to True, then this method will perform the ``exc_info = sys.exc_info()`` and the requisite clean-up for you. ``kwargs`` are passed through to ``.capture``. NTraven.events.Exceptionr)r)r!rr)r.rrr&r&r'rszClient.captureExceptioncs|ddjjf|j}dd|D}dd|D}dd|D}|krTdSj|krbdS|krndStfdd|DrdStfd d|DrdSd S) Nrz%s.%scss|]}t|tr|VqdS)N)r basestring)rrr&r&r'r8sz(Client.should_capture..css|]}|dr|VqdS)*N)endswith)rrr&r&r'r9scss|]}t|r|VqdS)N)r)rrr&r&r'r:sFc3s|]}t|VqdS)N) issubclass)rr)exc_typer&r'rBsc3s |]}|ddVqdS)Nr)r)rr)exc_namer&r'rDsT)r5r4rZr)r.rZ exclusionsZstring_exclusionsZwildcard_exclusionsZclass_exclusionsr&)r r r'r4s" zClient.should_capturec sRd}tf}t|tr|}n |dk r&|}tjfdd}||}|rN||S|S)a Wrap a function or code block in try/except and automatically call ``.captureException`` if it raises an exception, then the exception is reraised. By default, it will capture ``Exception`` >>> @client.capture_exceptions >>> def foo(): >>> raise Exception() >>> with client.capture_exceptions(): >>> raise Exception() You can also specify exceptions to be caught specifically >>> @client.capture_exceptions((IOError, LookupError)) >>> def bar(): >>> ... >>> with client.capture_exceptions((IOError, LookupError)): >>> ... ``kwargs`` are passed through to ``.captureException``. Nc3s2y dVWn"|k r,jfYnXdS)N)r) exceptions)rr.r&r'make_decoratorjs   z1Client.capture_exceptions..make_decorator)rrr contextlibcontextmanager)r.Zfunction_or_exceptionsrrr r decoratorr&)rr.r'capture_exceptionsHs zClient.capture_exceptionsr&cKs|jd|||d|S)zi Creates an event for a SQL query. >>> client.captureQuery('SELECT * FROM foo') raven.events.Query)queryparamsengine)r)r)r.rrrrr&r&r' captureQueryxs zClient.captureQuerycKstdt|jf|S)Nz8captureExceptions is deprecated, used context() instead.)rrrrS)r.rr&r&r'captureExceptionsszClient.captureExceptionscOs|jjj||dS)zp Records a breadcrumb with the current context. They will be sent with the next event. N)rSrrecord)r.argsrr&r&r'captureBreadcrumbszClient.captureBreadcrumbcCst|jddS)Nr)r#r\)r.r&r&r'rszClient.last_event_idcCs ||j_dS)N)r\r)r.rr&r&r'rs)NFNTTNTN)NN)N)NNNNNNNN)NNNNNNN)N)N)N)N)N)r&N)9r4r5r6__doc__r`rarbrrrrr=rorfryrzr{ classmethodrrrr rrrrrrrpropertyrSrrrrrrsrrrrrrrrrrrrrrrrrZcapture_breadcrumbrsetterr&r&r&r'r}sn   Q              Q     0   rc@seZdZdZddZdS) DummyClientz"Sends messages into an empty void.cKsdS)Nr&)r.rr&r&r'rszDummyClient.sendN)r4r5r6rrr&r&r&r'r sr )Gr __future__rrr`rmr!r@rrrinspectrrrtypesr threadingrrr contextlib2threadr rv ImportError_threadrGZ raven.confr Zraven.conf.remoter Zraven.exceptionsr rZ raven.utilsrrrrZraven.utils.compatrrZraven.utils.encodingrZraven.utils.serializerrZraven.utils.stacksrrZraven.utils.transactionrZraven.transport.registryrrZ raven.events__all__rrrrrustrrr(dictr)objectr7rr r&r&r&r'sf                %&