예제 #1
0
    def generic_rpc_response_handler(self, response_headers: dict,
                                     response_body, span: Span) -> Span:
        '''Add extended response rpc data to span'''
        logger.debug(
            'Entering BaseInstrumentationWrapper.genericRpcResponseHandler().')
        try:
            # is the span currently recording?
            if not span.is_recording():
                return span

            logger.debug('Span is Recording!')
            lowercased_headers = self.lowercase_headers(response_headers)
            # Log rpc metadata if requested?
            if self._process_response_headers:

                logger.debug('Dumping Response Headers:')
                self.add_headers_to_span(self.RPC_RESPONSE_METADATA_PREFIX,
                                         span, lowercased_headers)
            # Log rpc body if requested
            if self._process_response_body:
                response_body_str = str(response_body)
                logger.debug('Processing response body')
                response_body_str = self.grab_first_n_bytes(response_body_str)
                span.set_attribute(self.RPC_RESPONSE_BODY_PREFIX,
                                   response_body_str)
        except:  # pylint: disable=W0702
            logger.debug(
                'An error occurred in genericResponseHandler: exception=%s, stacktrace=%s',
                sys.exc_info()[0], traceback.format_exc())
            # Not rethrowing to avoid causing runtime errors
        finally:
            return span  # pylint: disable=W0150
def _apply_response_attributes(span: Span, result):
    if result is None or not span.is_recording():
        return

    metadata = result.get("ResponseMetadata")
    if metadata is None:
        return

    request_id = metadata.get("RequestId")
    if request_id is None:
        headers = metadata.get("HTTPHeaders")
        if headers is not None:
            request_id = (headers.get("x-amzn-RequestId")
                          or headers.get("x-amz-request-id")
                          or headers.get("x-amz-id-2"))
    if request_id:
        # TODO: update when semantic conventions exist
        span.set_attribute("aws.request_id", request_id)

    retry_attempts = metadata.get("RetryAttempts")
    if retry_attempts is not None:
        # TODO: update when semantic conventinos exists
        span.set_attribute("retry_attempts", retry_attempts)

    status_code = metadata.get("HTTPStatusCode")
    if status_code is not None:
        span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code)
예제 #3
0
    def on_success(self, span: Span, result: _BotoResultT):
        if not span.is_recording():
            return

        if self._op is None:
            return

        self._add_attributes(result, self._op.response_attributes,
                             span.set_attribute)
예제 #4
0
    def before_service_call(self, span: Span):
        if not span.is_recording() or self._op is None:
            return

        self._add_attributes(
            self._call_context.params,
            self._op.request_attributes,
            span.set_attribute,
        )
예제 #5
0
def use_span(
    span: Span,
    end_on_exit: bool = False,
    record_exception: bool = True,
    set_status_on_exception: bool = True,
) -> Iterator[Span]:
    """Takes a non-active span and activates it in the current context.

    Args:
        span: The span that should be activated in the current context.
        end_on_exit: Whether to end the span automatically when leaving the
            context manager scope.
        record_exception: Whether to record any exceptions raised within the
            context as error event on the span.
        set_status_on_exception: Only relevant if the returned span is used
            in a with/context manager. Defines wether the span status will
            be automatically set to ERROR when an uncaught exception is
            raised in the span with block. The span status won't be set by
            this mechanism if it was previously set manually.
    """
    try:
        token = context_api.attach(context_api.set_value(_SPAN_KEY, span))
        try:
            yield span
        finally:
            context_api.detach(token)

    except Exception as exc:  # pylint: disable=broad-except
        if isinstance(span, Span) and span.is_recording():
            # Record the exception as an event
            if record_exception:
                span.record_exception(exc)

            # Set status in case exception was raised
            if set_status_on_exception:
                span.set_status(
                    Status(
                        status_code=StatusCode.ERROR,
                        description=f"{type(exc).__name__}: {exc}",
                    )
                )
        raise

    finally:
        if end_on_exit:
            span.end()
예제 #6
0
    def _generic_handler(
            self,
            record_headers: bool,
            header_prefix: str,  # pylint:disable=R0913
            record_body: bool,
            body_prefix: str,
            span: Span,
            headers: dict,
            body):
        logger.debug('Entering BaseInstrumentationWrapper.generic_handler().')
        try:  # pylint: disable=R1702
            if not span.is_recording():
                return span

            logger.debug('Span is Recording!')
            lowercased_headers = self.lowercase_headers(headers)
            if record_headers:
                self.add_headers_to_span(header_prefix, span,
                                         lowercased_headers)

            if record_body:
                content_type = self.eligible_based_on_content_type(
                    lowercased_headers)

                if content_type is False:
                    return span

                body_str = None
                if isinstance(body, bytes):
                    body_str = body.decode('UTF8', 'backslashreplace')
                else:
                    body_str = body

                request_body_str = self.grab_first_n_bytes(body_str)
                span.set_attribute(body_prefix, request_body_str)

        except:  # pylint: disable=W0702
            logger.debug(
                'An error occurred in genericRequestHandler: exception=%s, stacktrace=%s',
                sys.exc_info()[0], traceback.format_exc())
        finally:
            return span  # pylint: disable=W0150
예제 #7
0
def _apply_status_code(span: Span, status_code: int) -> None:
    if not span.is_recording():
        return

    span.set_attribute(SpanAttributes.HTTP_STATUS_CODE, status_code)
    span.set_status(Status(http_status_to_status_code(status_code)))