B ㊇cuP@sddlZddlZddlZddlZddlmZmZmZddlm Z e e Z GdddZGdddZGdd d ZGd d d eZGd d d eZGdddZGdddZdS)N) ensure_bytesensure_unicodeurlparse) EXCEPTION_MAPc@s2eZdZdddddgZddZdd Zd d Zd S) Monitorzbefore-parameter-buildzrequest-createdzresponse-receivedz after-callzafter-call-errorcCs||_||_dS)zAbstraction for monitoring clients API calls :param adapter: An adapter that takes event emitter events and produces monitor events :param publisher: A publisher for generated monitor events N)_adapter _publisher)selfadapterZ publisherr n/private/var/folders/8c/hx9_v10d5x38qmnzt13b7b8j1k3n5b/T/pip-target-x6xd5gna/lib/python/botocore/monitoring.py__init__!szMonitor.__init__cCs"x|jD]}|||jqWdS)z(Register an event emitter to the monitorN)_EVENTS_TO_REGISTERZ register_lastcapture)r Z event_emitterZevent_to_registerr r r register,s zMonitor.registerc Ks\y"|j||}|r |j|Wn4tk rV}ztjd||ddWdd}~XYnXdS)zCaptures an incoming event from the event emitter It will feed an event emitter event to the monitor's adaptor to create a monitor event and then publish that event to the monitor's publisher. z:Exception %s raised by client monitor in handling event %sT)exc_infoN)rfeedrpublish Exceptionloggerdebug)r event_namepayloadZ monitor_eventer r r r1szMonitor.captureN)__name__ __module__ __qualname__rr rrr r r r rs rc@sreZdZejfddZddZddZddZd d Zd d Z d dZ ddZ ddZ ddZ ddZddZdS)MonitorEventAdaptercCs ||_dS)zAdapts event emitter events to produce monitor events :type time: callable :param time: A callable that produces the current time N)_time)r timer r r r EszMonitorEventAdapter.__init__cCs||f|S)aFeed an event emitter event to generate a monitor event :type emitter_event_name: str :param emitter_event_name: The name of the event emitted :type emitter_payload: dict :param emitter_payload: The payload to associated to the event emitted :rtype: BaseMonitorEvent :returns: A monitor event based on the event emitter events fired ) _get_handler)r Zemitter_event_nameZemitter_payloadr r r rMszMonitorEventAdapter.feedcCs t|d|ddddS)NZ_handle_.r-_)getattrsplitreplace)r rr r r r ]sz MonitorEventAdapter._get_handlercKs t|jj|j|d|d<dS)N)service operation timestampcurrent_api_call_event) APICallEventZ service_modelZ service_idZ wire_name_get_current_time)r modelcontextkwargsr r r _handle_before_parameter_buildbsz2MonitorEventAdapter._handle_before_parameter_buildcKs6|j}|dj|d}|j|_|j|_||d<dS)Nr*)r)current_api_call_attempt_event)r.new_api_call_attemptr,headersrequest_headersurl)r requestr/r.Znew_attempt_eventr r r _handle_request_createdis z+MonitorEventAdapter._handle_request_createdcKsR|d}|||_|dk rH|dd|_|dd|_|d|_n||_|S)Nr1ResponseMetadataZHTTPStatusCodeZ HTTPHeadersError)pop _get_latencylatencyhttp_status_coderesponse_headersget parsed_errorwire_exception)r Zparsed_responser. exceptionr/ attempt_eventr r r _handle_response_receivedrs  z-MonitorEventAdapter._handle_response_receivedcKs |ddd|d_||S)Nr8ZMaxAttemptsReachedFr*)r?retries_exceeded_complete_api_call)r r.parsedr/r r r _handle_after_callsz&MonitorEventAdapter._handle_after_callcKs|||d_||S)Nr*)_is_retryable_exceptionrErF)r r.rBr/r r r _handle_after_call_errorsz,MonitorEventAdapter._handle_after_call_errorcCst|ttdS)NZGENERAL_CONNECTION_ERROR) isinstancetupleRETRYABLE_EXCEPTIONS)r rBr r r rIsz+MonitorEventAdapter._is_retryable_exceptioncCs|d}|||_|S)Nr*)r:r;r<)r r.Z call_eventr r r rFs  z&MonitorEventAdapter._complete_api_callcCs||jS)N)r,r))r eventr r r r;sz MonitorEventAdapter._get_latencycCst|dS)Ni)intr)r r r r r,sz%MonitorEventAdapter._get_current_timeN)rrrrr rr r0r7rDrHrJrIrFr;r,r r r r rDs  rc@s$eZdZddZddZddZdS)BaseMonitorEventcCs||_||_||_dS)aBase monitor event :type service: str :param service: A string identifying the service associated to the event :type operation: str :param operation: A string identifying the operation of service associated to the event :type timestamp: int :param timestamp: Epoch time in milliseconds from when the event began N)r'r(r))r r'r(r)r r r r szBaseMonitorEvent.__init__cCs|jjd|jdS)N()) __class__r__dict__)r r r r __repr__szBaseMonitorEvent.__repr__cCst||jr|j|jkSdS)NF)rKrSrT)r otherr r r __eq__s  zBaseMonitorEvent.__eq__N)rrrr rUrWr r r r rPsrPcs&eZdZdfdd ZddZZS)r+NFcs6tj|||d||_||_|dkr,g|_||_dS)aMonitor event for a single API call This event corresponds to a single client method call, which includes every HTTP requests attempt made in order to complete the client call :type service: str :param service: A string identifying the service associated to the event :type operation: str :param operation: A string identifying the operation of service associated to the event :type timestamp: int :param timestamp: Epoch time in milliseconds from when the event began :type latency: int :param latency: The time in milliseconds to complete the client call :type attempts: list :param attempts: The list of APICallAttempts associated to the APICall :type retries_exceeded: bool :param retries_exceeded: True if API call exceeded retries. False otherwise )r'r(r)N)superr r<attemptsrE)r r'r(r)r<rYrE)rSr r r s$ zAPICallEvent.__init__cCs"t|j|j|d}|j||S)zInstantiates APICallAttemptEvent associated to the APICallEvent :type timestamp: int :param timestamp: Epoch time in milliseconds to associate to the APICallAttemptEvent )r'r(r))APICallAttemptEventr'r(rYappend)r r)rCr r r r2s z!APICallEvent.new_api_call_attempt)NNF)rrrr r2 __classcell__r r )rSr r+s&r+cseZdZdfdd ZZS)rZNc s@tj|||d||_||_||_||_||_| |_| |_dS)aMonitor event for a single API call attempt This event corresponds to a single HTTP request attempt in completing the entire client method call. :type service: str :param service: A string identifying the service associated to the event :type operation: str :param operation: A string identifying the operation of service associated to the event :type timestamp: int :param timestamp: Epoch time in milliseconds from when the HTTP request started :type latency: int :param latency: The time in milliseconds to complete the HTTP request whether it succeeded or failed :type url: str :param url: The URL the attempt was sent to :type http_status_code: int :param http_status_code: The HTTP status code of the HTTP response if there was a response :type request_headers: dict :param request_headers: The HTTP headers sent in making the HTTP request :type response_headers: dict :param response_headers: The HTTP headers returned in the HTTP response if there was a response :type parsed_error: dict :param parsed_error: The error parsed if the service returned an error back :type wire_exception: Exception :param wire_exception: The exception raised in sending the HTTP request (i.e. ConnectionError) )r'r(r)N) rXr r<r5r=r4r>r@rA) r r'r(r)r<r5r=r4r>r@rA)rSr r r s9 zAPICallAttemptEvent.__init__)NNNNNNN)rrrr r\r r )rSr rZsrZc @s&eZdZdZdZdZdZdZddddZe d e d d Z d d ddddddddddg Z ddZ ddZddZddZd d!Zd"d#Zd$d%Zd&d'Zd(d)Zd*d+Zd,d-Zd.d/Zd0d1Zd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Z d@dAZ!dBdCZ"dDdEZ#dFdGZ$dHdIZ%dJS)K CSMSerializeriZXAmznRequestIdZ XAmzRequestIdZXAmzId2)zx-amzn-requestidzx-amz-request-idz x-amz-id-2zSAWS4-HMAC-SHA256 Credential=(?P\w+)/\d+/(?P[a-z0-9-]+)/zAWS (?P\w+):)v4Zs3r'r(r)rYr<rEr5r4r=r>r@rAcCs||||_dS)zSerializes monitor events to CSM (Client Side Monitoring) format :type csm_client_id: str :param csm_client_id: The application identifier to associate to the serialized events N)_validate_client_id csm_client_id)r rcr r r r ds zCSMSerializer.__init__cCs*t||jkr&td|d|jddS)Nz&The value provided for csm_client_id: z exceeds the maximum length of z characters)len_MAX_CLIENT_ID_LENGTH ValueError)r rcr r r rbnsz!CSMSerializer._validate_client_idcCsj||}||}||d<x:|jD]0}t||d}|dk r$t|d||||dq$Wttj|ddS)zSerializes a monitor event to the CSM format :type event: BaseMonitorEvent :param event: The event to serialize to bytes :rtype: bytes :returns: The CSM serialized form of the event TypeNZ _serialize_) event_type),:) separators)_get_base_event_dict_get_event_type_SERIALIZEABLE_EVENT_PROPERTIESr$rjsondumps)r rN event_dictrhattrvaluer r r serializeus     zCSMSerializer.serializecCs d|jdS)N)VersionZClientId)rc)r rNr r r rlsz"CSMSerializer._get_base_event_dictcKs ||d<dS)NZServicer )r r'rqr/r r r _serialize_servicesz CSMSerializer._serialize_servicecKs ||d<dS)NZApir )r r(rqr/r r r _serialize_operationsz"CSMSerializer._serialize_operationcKs ||d<dS)N Timestampr )r r)rqr/r r r _serialize_timestampsz"CSMSerializer._serialize_timestampcKs$t||d<|r |||ddS)NZ AttemptCount)rd_add_fields_from_last_attempt)r rYrqr/r r r _serialize_attemptss z!CSMSerializer._serialize_attemptscCs~|jr2||j}|dk r"||d<||j|d<|jdk rF|j|d<|jdk r`||j|d|jdk rz||j|ddS)NRegion UserAgentZFinalHttpStatusCodeApiCall)r4 _get_region_get_user_agentr=r@_serialize_parsed_errorrA_serialize_wire_exception)r rq last_attemptregionr r r r|s       z+CSMSerializer._add_fields_from_last_attemptcCs&|dkr||d<n|dkr"||d<dS)NrZLatencyApiCallAttemptZAttemptLatencyr )r r<rqrhr r r _serialize_latencys z CSMSerializer._serialize_latencycKs|rdnd|d<dS)NrurZMaxRetriesExceededr )r rErqr/r r r _serialize_retries_exceededsz)CSMSerializer._serialize_retries_exceededcKst|j|d<dS)NZFqdn)rnetloc)r r5rqr/r r r _serialize_urlszCSMSerializer._serialize_urlcKsX|||d<||r&|||d<||}|dk r@||d<d|krT|d|d<dS)NrZ AccessKeyr~zX-Amz-Security-TokenZ SessionToken)r _is_signed_get_access_keyr)r r4rqr/rr r r _serialize_request_headerss  z(CSMSerializer._serialize_request_headerscKs ||d<dS)NZHttpStatusCoder )r r=rqr/r r r _serialize_http_status_codesz)CSMSerializer._serialize_http_status_codecKs0x*|jD]\}}||kr ||||<q WdS)N)"_RESPONSE_HEADERS_TO_EVENT_ENTRIESitems)r r>rqr/headerentryr r r _serialize_response_headerssz)CSMSerializer._serialize_response_headerscKsH|dkr dnd}||d|j||d<||d|j||d<dS)NrFinalZCodeZ AwsExceptionMessageZAwsExceptionMessage) _truncate_MAX_ERROR_CODE_LENGTH_MAX_MESSAGE_LENGTH)r r@rqrhr/ field_prefixr r r rs z%CSMSerializer._serialize_parsed_errorcKsH|dkr dnd}||jj|j||d<|t||j||d<dS)NrrrZ SdkExceptionZSdkExceptionMessage)rrSr_MAX_EXCEPTION_CLASS_LENGTHstrr)r rArqrhr/rr r r rs z'CSMSerializer._serialize_wire_exceptioncCs t|trdSt|trdSdS)Nrr)rKr+rZ)r rNr r r rms  zCSMSerializer._get_event_typecCs"||}||\}}|dS)NZ access_key)_get_auth_value_get_auth_matchgroup)r r4auth_valr# auth_matchr r r rs zCSMSerializer._get_access_keycCs<||sdS||}||\}}|dkr2dS|dS)NraZsigning_region)rrrr)r r4rsignature_versionrr r r rs  zCSMSerializer._get_regioncCs|t|dd|jS)Nz User-Agentr)rrr?_MAX_USER_AGENT_LENGTH)r r4r r r rszCSMSerializer._get_user_agentcCsd|kS)N Authorizationr )r r4r r r r szCSMSerializer._is_signedcCs t|dS)Nr)r)r r4r r r r szCSMSerializer._get_auth_valuecCs2x,|jD]\}}||}|r ||fSq WdS)N)NN) _AUTH_REGEXSrmatch)r rrregexrr r r rs   zCSMSerializer._get_auth_matchcCs*t||kr&td|||d|S|S)Nz6Truncating following value to maximum length of %s: %s)rdrr)r text max_lengthr r r rs  zCSMSerializer._truncateN)&rrrrerrrrrrecompilerrnr rbrtrlrwrxrzr}r|rrrrrrrrrmrrrrrrrr r r r r]Bs`    r]c@s eZdZdZddZddZdS)SocketPublisheri cCs||_||f|_||_dS)a)Publishes monitor events to a socket :type socket: socket.socket :param socket: The socket object to use to publish events :type host: string :param host: The host to send events to :type port: integer :param port: The port on the host to send events to :param serializer: The serializer to use to serialize the event to a form that can be published to the socket. This must have a `serialize()` method that accepts a monitor event and return bytes N)_socket_address _serializer)r sockethostport serializerr r r r %s zSocketPublisher.__init__cCsF|j|}t||jkr2tdt||jdS|j||jdS)zPublishes a specified monitor event :type event: BaseMonitorEvent :param event: The monitor event to be sent over the publisher's socket to the desired address. z`Serialized event of size %s exceeds the maximum length allowed: %s. Not sending event to socket.N) rrtrd_MAX_MONITOR_EVENT_LENGTHrrrsendtor)r rNZserialized_eventr r r r:s zSocketPublisher.publishN)rrrrr rr r r r r"sr)rologgingrrZbotocore.compatrrrZbotocore.retryhandlerrrM getLoggerrrrrrPr+rZr]rr r r r  s  ,`<Fa