Beispiel #1
0
def _handle_exception(request):
    global in_lambda_ctx
    global _recorder

    if not request.exception:
        return
    segment = None
    try:
        if in_lambda_ctx:
            try:
                segment = _recorder.current_subsegment()
            except SegmentNotFoundException:
                segment = __create_segment(request,
                                           _recorder,
                                           lambda_ctx=in_lambda_ctx)
        else:
            try:
                segment = _recorder.current_segment()
            except SegmentNotFoundException:
                segment = __create_segment(request,
                                           _recorder,
                                           lambda_ctx=in_lambda_ctx)
    except Exception:
        pass
    if not segment:
        return

    segment.put_http_meta(http.STATUS, 500)
    stack = stacktrace.get_stacktrace(limit=_recorder._max_trace_back)
    segment.add_exception(request.exception, stack)
    if in_lambda_ctx:
        _recorder.end_subsegment()
    else:
        _recorder.end_segment()
    def process_exception(self, request, exception):
        """
        Add exception information and fault flag to the
        current segment.
        """
        segment = xray_recorder.current_segment()
        segment.put_http_meta(http.STATUS, 500)

        stack = stacktrace.get_stacktrace(limit=xray_recorder._max_trace_back)
        segment.add_exception(exception, stack)
Beispiel #3
0
async def end_subsegment_with_exception(session, trace_config_ctx, params):
    if trace_config_ctx.give_up:
        return

    subsegment = xray_recorder.current_subsegment()
    subsegment.add_exception(
        params.exception,
        stacktrace.get_stacktrace(limit=xray_recorder._max_trace_back))

    if isinstance(params.exception, LOCAL_EXCEPTIONS):
        subsegment.namespace = LOCAL_NAMESPACE

    xray_recorder.end_subsegment()
Beispiel #4
0
    def process_exception(self, request, exception):
        """
        Add exception information and fault flag to the
        current segment.
        """

        if not environ.get('AWS_EXECUTION_ENV', '').startswith('AWS_Lambda_'):
            return

        segment = xray_recorder.current_subsegment()
        segment.put_http_meta(http.STATUS, 500)

        stack = stacktrace.get_stacktrace(limit=xray_recorder._max_trace_back)
        segment.add_exception(exception, stack)
Beispiel #5
0
    def _handle_exception(self, exception):
        if not exception:
            return
        segment = None
        try:
            segment = self._recorder.current_segment()
        except Exception:
            pass
        if not segment:
            return

        segment.put_http_meta(http.STATUS, 500)
        stack = stacktrace.get_stacktrace(limit=self._recorder._max_trace_back)
        segment.add_exception(exception, stack)
        self._recorder.end_segment()
Beispiel #6
0
def _process_request(wrapped, engine_instance, args, kwargs):
    name, sql = _sql_meta(engine_instance, args)
    if sql is not None:
        subsegment = xray_recorder.begin_subsegment(name, namespace='remote')
    else:
        subsegment = None
    try:
        res = wrapped(*args, **kwargs)
    except Exception:
        if subsegment is not None:
            exception = sys.exc_info()[1]
            stack = stacktrace.get_stacktrace(limit=xray_recorder._max_trace_back)
            subsegment.add_exception(exception, stack)
        raise
    finally:
        if subsegment is not None:
            subsegment.set_sql(sql)
            xray_recorder.end_subsegment()
    return res
Beispiel #7
0
    def _teardown_request(self, exception):
        segment = None
        try:
            if self.in_lambda_ctx:
                segment = self._recorder.current_subsegment()
            else:
                segment = self._recorder.current_segment()
        except Exception:
            pass
        if not segment:
            return

        if exception:
            segment.put_http_meta(http.STATUS, 500)
            stack = stacktrace.get_stacktrace(limit=self._recorder._max_trace_back)
            segment.add_exception(exception, stack)

        if self.in_lambda_ctx:
            self._recorder.end_subsegment()
        else:
            self._recorder.end_segment()
Beispiel #8
0
    async def record_subsegment_async(self, wrapped, instance, args, kwargs, name,
                                      namespace, meta_processor):

        subsegment = self.begin_subsegment(name, namespace)

        exception = None
        stack = None
        return_value = None

        try:
            return_value = await wrapped(*args, **kwargs)
            return return_value
        except Exception as e:
            exception = e
            stack = stacktrace.get_stacktrace(limit=self._max_trace_back)
            raise
        finally:
            # No-op if subsegment is `None` due to `LOG_ERROR`.
            if subsegment is not None:
                end_time = time.time()
                if callable(meta_processor):
                    meta_processor(
                        wrapped=wrapped,
                        instance=instance,
                        args=args,
                        kwargs=kwargs,
                        return_value=return_value,
                        exception=exception,
                        subsegment=subsegment,
                        stack=stack,
                    )
                elif exception:
                    if subsegment:
                        subsegment.add_exception(exception, stack)

                self.end_subsegment(end_time)
async def middleware(request, handler):
    """
    Main middleware function, deals with all the X-Ray segment logic
    """
    # Create X-Ray headers
    xray_header = construct_xray_header(request.headers)
    # Get name of service or generate a dynamic one from host
    name = calculate_segment_name(request.headers['host'].split(':', 1)[0],
                                  xray_recorder)

    sampling_req = {
        'host': request.headers['host'],
        'method': request.method,
        'path': request.path,
        'service': name,
    }

    sampling_decision = calculate_sampling_decision(
        trace_header=xray_header,
        recorder=xray_recorder,
        sampling_req=sampling_req,
    )

    # Start a segment
    segment = xray_recorder.begin_segment(
        name=name,
        traceid=xray_header.root,
        parent_id=xray_header.parent,
        sampling=sampling_decision,
    )

    segment.save_origin_trace_header(xray_header)
    # Store request metadata in the current segment
    segment.put_http_meta(http.URL, str(request.url))
    segment.put_http_meta(http.METHOD, request.method)

    if 'User-Agent' in request.headers:
        segment.put_http_meta(http.USER_AGENT, request.headers['User-Agent'])

    if 'X-Forwarded-For' in request.headers:
        segment.put_http_meta(http.CLIENT_IP,
                              request.headers['X-Forwarded-For'])
        segment.put_http_meta(http.X_FORWARDED_FOR, True)
    elif 'remote_addr' in request.headers:
        segment.put_http_meta(http.CLIENT_IP, request.headers['remote_addr'])
    else:
        segment.put_http_meta(http.CLIENT_IP, request.remote)

    try:
        # Call next middleware or request handler
        response = await handler(request)
    except HTTPException as exc:
        # Non 2XX responses are raised as HTTPExceptions
        response = exc
        raise
    except Exception as err:
        # Store exception information including the stacktrace to the segment
        response = None
        segment.put_http_meta(http.STATUS, 500)
        stack = stacktrace.get_stacktrace(limit=xray_recorder.max_trace_back)
        segment.add_exception(err, stack)
        raise
    finally:
        if response is not None:
            segment.put_http_meta(http.STATUS, response.status)
            if 'Content-Length' in response.headers:
                length = int(response.headers['Content-Length'])
                segment.put_http_meta(http.CONTENT_LENGTH, length)

            header_str = prepare_response_header(xray_header, segment)
            response.headers[http.XRAY_HEADER] = header_str

        xray_recorder.end_segment()

    return response
Beispiel #10
0
    async def dispatch(self, request: Request,
                       call_next: RequestResponseEndpoint) -> Response:
        """
        Main middleware function, deals with all the X-Ray segment logic
        """

        # Create X-Ray headers
        headers = request.headers

        xray_header = construct_xray_header(headers)
        # Get name of service or generate a dynamic one from host
        name = calculate_segment_name(headers["host"].split(":", 1)[0],
                                      self._recorder)

        sampling_req = {
            "host": headers["host"],
            "method": request.method,
            "path": request.url.path,
            "service": name,
        }

        sampling_decision = calculate_sampling_decision(
            trace_header=xray_header,
            recorder=self._recorder,
            sampling_req=sampling_req)

        # Start a segment
        if self.in_lambda_ctx:
            segment = self._recorder.begin_subsegment(name)
        else:
            segment = self._recorder.begin_segment(
                name=name,
                traceid=xray_header.root,
                parent_id=xray_header.parent,
                sampling=sampling_decision,
            )

        # Store request metadata in the current segment
        segment.save_origin_trace_header(xray_header)
        segment.put_http_meta(http.URL, str(request.url))
        segment.put_http_meta(http.METHOD, request.method)

        if "User-Agent" in request.headers:
            segment.put_http_meta(http.USER_AGENT,
                                  request.headers["User-Agent"])

        if "X-Forwarded-For" in request.headers:
            segment.put_http_meta(http.CLIENT_IP,
                                  request.headers["X-Forwarded-For"])
            segment.put_http_meta(http.X_FORWARDED_FOR, True)
        elif "remote_addr" in request.headers:
            segment.put_http_meta(http.CLIENT_IP,
                                  request.headers["remote_addr"])
        else:
            segment.put_http_meta(http.CLIENT_IP,
                                  f"{request.client[0]}:{request.client[1]}")

        try:
            # Call next middleware or request handler
            response = await call_next(request)

            segment.put_http_meta(http.STATUS, response.status_code)
            if "Content-Length" in response.headers:
                length = int(response.headers["Content-Length"])
                segment.put_http_meta(http.CONTENT_LENGTH, length)

            header_str = prepare_response_header(xray_header, segment)
            response.headers[http.XRAY_HEADER] = header_str
        except HTTPException as exc:
            segment.put_http_meta(http.STATUS, exc.status_code)
            raise
        except Exception as err:
            # Store exception information including the stacktrace to the segment
            segment.put_http_meta(http.STATUS, 500)
            stack = stacktrace.get_stacktrace(
                limit=xray_recorder.max_trace_back)
            segment.add_exception(err, stack)
            raise
        finally:

            if self.in_lambda_ctx:
                self._recorder.end_subsegment()
            else:
                self._recorder.end_segment()

        return response
Beispiel #11
0
        def wrapper(*a, **ka):
            headers = request.headers
            xray_header = construct_xray_header(headers)
            name = calculate_segment_name(request.urlparts[1], self._recorder)

            sampling_req = {
                'host': request.urlparts[1],
                'method': request.method,
                'path': request.path,
                'service': name,
            }
            sampling_decision = calculate_sampling_decision(
                trace_header=xray_header,
                recorder=self._recorder,
                sampling_req=sampling_req,
            )

            if self._in_lambda_ctx:
                segment = self._recorder.begin_subsegment(name)
            else:
                segment = self._recorder.begin_segment(
                    name=name,
                    traceid=xray_header.root,
                    parent_id=xray_header.parent,
                    sampling=sampling_decision,
                )

            segment.save_origin_trace_header(xray_header)
            segment.put_http_meta(http.URL, request.url)
            segment.put_http_meta(http.METHOD, request.method)
            segment.put_http_meta(http.USER_AGENT, headers.get('User-Agent'))

            client_ip = request.environ.get(
                'HTTP_X_FORWARDED_FOR') or request.environ.get('REMOTE_ADDR')
            if client_ip:
                segment.put_http_meta(http.CLIENT_IP, client_ip)
                segment.put_http_meta(http.X_FORWARDED_FOR, True)
            else:
                segment.put_http_meta(http.CLIENT_IP, request.remote_addr)

            try:
                rv = callback(*a, **ka)
            except Exception as resp:
                segment.put_http_meta(http.STATUS,
                                      getattr(resp, 'status_code', 500))
                stack = stacktrace.get_stacktrace(
                    limit=self._recorder._max_trace_back)
                segment.add_exception(resp, stack)
                if self._in_lambda_ctx:
                    self._recorder.end_subsegment()
                else:
                    self._recorder.end_segment()

                raise resp

            segment.put_http_meta(http.STATUS, response.status_code)

            origin_header = segment.get_origin_trace_header()
            resp_header_str = prepare_response_header(origin_header, segment)
            response.set_header(http.XRAY_HEADER, resp_header_str)

            cont_len = response.headers.get('Content-Length')
            if cont_len:
                segment.put_http_meta(http.CONTENT_LENGTH, int(cont_len))

            if self._in_lambda_ctx:
                self._recorder.end_subsegment()
            else:
                self._recorder.end_segment()

            return rv