Esempio n. 1
0
 def request_finished(self, app, response):
     if not self.app.debug or self.client.config.debug:
         rule = request.url_rule.rule if request.url_rule is not None else ""
         rule = build_name_with_http_method_prefix(rule, request)
         elasticapm.set_context(
             lambda: get_data_from_request(
                 request, capture_body=self.client.config.capture_body in ("transactions", "all")
             ),
             "request",
         )
         elasticapm.set_context(lambda: get_data_from_response(response), "response")
         if response.status_code:
             result = "HTTP {}xx".format(response.status_code // 100)
         else:
             result = response.status
         elasticapm.set_transaction_name(rule, override=False)
         elasticapm.set_transaction_result(result, override=False)
         # Instead of calling end_transaction here, we defer the call until the response is closed.
         # This ensures that we capture things that happen until the WSGI server closes the response.
         response.call_on_close(self.client.end_transaction)
Esempio n. 2
0
 def __call__(self, request):
     self.client.begin_transaction('request')
     try:
         response = self.handler(request)
         transaction_result = response.status[0] + 'xx'
         elasticapm.set_context(
             lambda: self.get_data_from_response(response), 'response')
         return response
     except Exception:
         transaction_result = '5xx'
         self.client.capture_exception(
             context={'request': self.get_data_from_request(request)},
             handled=False,
         )
         reraise(*sys.exc_info())
     finally:
         transaction_name = self.get_transaction_name(request)
         elasticapm.set_context(lambda: self.get_data_from_request(request),
                                'request')
         elasticapm.set_user_context(user_id=request.authenticated_userid, )
         self.client.end_transaction(transaction_name, transaction_result)
Esempio n. 3
0
 def process_response(self, request: HttpRequest, response: HttpResponse):
     if django_settings.DEBUG and not self.client.config.debug:
         return response
     try:
         if hasattr(response, "status_code"):
             if not getattr(request, "_elasticapm_name_set", False):
                 elasticapm.set_transaction_name(
                     self.get_transaction_name(request), override=False)
             elasticapm.set_context(
                 lambda: self.client.get_data_from_request(
                     request, constants.TRANSACTION), "request")
             elasticapm.set_context(
                 lambda: self.client.get_data_from_response(
                     response, constants.TRANSACTION), "response")
             elasticapm.set_context(
                 lambda: self.client.get_user_info(request), "user")
             elasticapm.set_transaction_result("HTTP {}xx".format(
                 response.status_code // 100),
                                               override=False)
             elasticapm.set_transaction_outcome(
                 http_status_code=response.status_code, override=False)
     except Exception:
         self.client.error_logger.error(
             "Exception during timing of request", exc_info=True)
     return response
Esempio n. 4
0
    def process_response(self, request, response):
        if django_settings.DEBUG and not self.client.config.debug:
            return response
        try:
            if hasattr(response, "status_code"):
                transaction_name = None
                if self.client.config.django_transaction_name_from_route and hasattr(request.resolver_match, "route"):
                    transaction_name = request.resolver_match.route
                elif getattr(request, "_elasticapm_view_func", False):
                    transaction_name = get_name_from_func(request._elasticapm_view_func)
                if transaction_name:
                    transaction_name = build_name_with_http_method_prefix(transaction_name, request)
                    elasticapm.set_transaction_name(transaction_name, override=False)

                elasticapm.set_context(
                    lambda: self.client.get_data_from_request(request, constants.TRANSACTION), "request"
                )
                elasticapm.set_context(
                    lambda: self.client.get_data_from_response(response, constants.TRANSACTION), "response"
                )
                elasticapm.set_context(lambda: self.client.get_user_info(request), "user")
                elasticapm.set_transaction_result("HTTP {}xx".format(response.status_code // 100), override=False)
                elasticapm.set_transaction_outcome(http_status_code=response.status_code, override=False)
        except Exception:
            self.client.error_logger.error("Exception during timing of request", exc_info=True)
        return response
Esempio n. 5
0
    def process_response(self, request, response):
        if django_settings.DEBUG and not self.client.config.debug:
            return response
        try:
            if hasattr(response, "status_code"):
                if getattr(request, "_elasticapm_view_func", False):
                    transaction_name = get_name_from_func(
                        request._elasticapm_view_func)
                    transaction_name = build_name_with_http_method_prefix(
                        transaction_name, request)
                    elasticapm.set_transaction_name(transaction_name,
                                                    override=False)

                elasticapm.set_context(
                    lambda: self.client.get_data_from_request(
                        request,
                        capture_body=self.client.config.capture_body in
                        ("all", "transactions")),
                    "request",
                )
                elasticapm.set_context(
                    lambda: self.client.get_data_from_response(response),
                    "response")
                elasticapm.set_context(
                    lambda: self.client.get_user_info(request), "user")
                elasticapm.set_transaction_result("HTTP {}xx".format(
                    response.status_code // 100),
                                                  override=False)
        except Exception:
            self.client.error_logger.error(
                "Exception during timing of request", exc_info=True)
        return response
Esempio n. 6
0
    def process_response(self, request, response):
        if django_settings.DEBUG and not self.client.config.debug:
            return response
        try:
            if hasattr(response, 'status_code'):
                if getattr(request, '_elasticapm_view_func', False):
                    transaction_name = get_name_from_func(
                        request._elasticapm_view_func
                    )
                    transaction_name = build_name_with_http_method_prefix(
                        transaction_name,
                        request
                    )
                    elasticapm.set_transaction_name(transaction_name, override=False)

                elasticapm.set_context(lambda: self.client.get_data_from_request(
                    request,
                    capture_body=self.client.config.capture_body in ('all', 'transactions')
                ), 'request')
                elasticapm.set_context(lambda: self.client.get_data_from_response(response), 'response')
                elasticapm.set_context(lambda: self.client.get_user_info(request), 'user')
                elasticapm.set_transaction_result('HTTP {}xx'.format(response.status_code // 100), override=False)
        except Exception:
            self.client.error_logger.error(
                'Exception during timing of request',
                exc_info=True,
            )
        return response
Esempio n. 7
0
    async def call(self, module, method, wrapped, instance, args, kwargs):
        if not hasattr(instance.application, "elasticapm_client"):
            # If tornado was instrumented but not as the main framework
            # (i.e. in Flower), we should skip it.
            return await wrapped(*args, **kwargs)

        # Late import to avoid ImportErrors
        from elasticapm.contrib.tornado.utils import get_data_from_request, get_data_from_response

        request = instance.request
        client = instance.application.elasticapm_client
        should_ignore = client.should_ignore_url(request.path)
        if not should_ignore:
            trace_parent = TraceParent.from_headers(request.headers)
            client.begin_transaction("request", trace_parent=trace_parent)
            elasticapm.set_context(
                lambda: get_data_from_request(instance, request, client.config,
                                              constants.TRANSACTION),
                "request")
            # TODO: Can we somehow incorporate the routing rule itself here?
            elasticapm.set_transaction_name("{} {}".format(
                request.method,
                type(instance).__name__),
                                            override=False)

        ret = await wrapped(*args, **kwargs)

        if not should_ignore:
            elasticapm.set_context(
                lambda: get_data_from_response(instance, client.config,
                                               constants.TRANSACTION),
                "response")
            status = instance.get_status()
            result = "HTTP {}xx".format(status // 100)
            elasticapm.set_transaction_result(result, override=False)
            elasticapm.set_transaction_outcome(http_status_code=status)
            client.end_transaction()

        return ret
Esempio n. 8
0
    async def handle_request(request, handler):
        elasticapm_client = app.get(CLIENT_KEY)
        if elasticapm_client:
            request[CLIENT_KEY] = elasticapm_client
            trace_parent = AioHttpTraceParent.from_headers(request.headers)
            elasticapm_client.begin_transaction("request", trace_parent=trace_parent)
            resource = request.match_info.route.resource
            name = request.method
            if resource:
                # canonical has been added in 3.3, and returns one of path, formatter, prefix
                for attr in ("canonical", "_path", "_formatter", "_prefix"):
                    if hasattr(resource, attr):
                        name += " " + getattr(resource, attr)
                        break
                else:
                    name += " unknown route"
            else:
                name += " unknown route"
            elasticapm.set_transaction_name(name, override=False)
            elasticapm.set_context(
                lambda: get_data_from_request(request, elasticapm_client.config, constants.TRANSACTION), "request"
            )

        try:
            response = await handler(request)
            elasticapm.set_transaction_result("HTTP {}xx".format(response.status // 100), override=False)
            elasticapm.set_transaction_outcome(http_status_code=response.status, override=False)
            elasticapm.set_context(
                lambda: get_data_from_response(response, elasticapm_client.config, constants.TRANSACTION), "response"
            )
            return response
        except Exception as exc:
            if elasticapm_client:
                elasticapm_client.capture_exception(
                    context={"request": get_data_from_request(request, elasticapm_client.config, constants.ERROR)}
                )
                elasticapm.set_transaction_result("HTTP 5xx", override=False)
                elasticapm.set_transaction_outcome(http_status_code=500, override=False)
                elasticapm.set_context({"status_code": 500}, "response")
                # some exceptions are response-like, e.g. have headers and status code. Let's try and capture them
                if isinstance(exc, (Response, HTTPException)):
                    elasticapm.set_context(
                        lambda: get_data_from_response(exc, elasticapm_client.config, constants.ERROR),  # noqa: F821
                        "response",
                    )

            raise
        finally:
            elasticapm_client.end_transaction()
Esempio n. 9
0
    async def handle_request(request, handler):
        elasticapm_client = app.get(CLIENT_KEY)
        if elasticapm_client:
            request[CLIENT_KEY] = elasticapm_client
            trace_parent = AioHttpTraceParent.from_headers(request.headers)
            elasticapm_client.begin_transaction("request",
                                                trace_parent=trace_parent)
            resource = request.match_info.route.resource
            name = request.method
            if resource:
                # canonical has been added in 3.3, and returns one of path, formatter, prefix
                for attr in ("canonical", "_path", "_formatter", "_prefix"):
                    if hasattr(resource, attr):
                        name += " " + getattr(resource, attr)
                        break
                else:
                    name += " unknown route"
            else:
                name += " unknown route"
            elasticapm.set_transaction_name(name, override=False)
            elasticapm.set_context(
                lambda: get_data_from_request(
                    request,
                    capture_body=elasticapm_client.config.capture_body in
                    ("transactions", "all"),
                    capture_headers=elasticapm_client.config.capture_headers,
                ),
                "request",
            )

        try:
            response = await handler(request)
            elasticapm.set_transaction_result("HTTP {}xx".format(
                response.status // 100),
                                              override=False)
            elasticapm.set_context(
                lambda: get_data_from_response(
                    response,
                    capture_headers=elasticapm_client.config.capture_headers),
                "response",
            )
            return response
        except Exception:
            if elasticapm_client:
                elasticapm_client.capture_exception(
                    context={
                        "request":
                        get_data_from_request(request,
                                              capture_body=elasticapm_client.
                                              config.capture_body in (
                                                  "all", "errors"))
                    })
                elasticapm.set_transaction_result("HTTP 5xx", override=False)
                elasticapm.set_context({"status_code": 500}, "response")
            raise
        finally:
            elasticapm_client.end_transaction()
Esempio n. 10
0
 def __call__(self, request):
     self.client.begin_transaction('request')
     try:
         response = self.handler(request)
         transaction_result = response.status[0] + "xx"
         elasticapm.set_context(lambda: get_data_from_response(response),
                                "response")
         return response
     except Exception:
         transaction_result = '5xx'
         self.client.capture_exception(
             context={"request": get_data_from_request(request)},
             handled=
             False,  # indicate that this exception bubbled all the way up to the user
         )
         reraise(*sys.exc_info())
     finally:
         transaction_name = request.matched_route.pattern if request.matched_route else request.view_name
         # prepend request method
         transaction_name = " ".join(
             (request.method, transaction_name)) if transaction_name else ""
         elasticapm.set_context(lambda: get_data_from_request(request),
                                "request")
         self.client.end_transaction(transaction_name, transaction_result)
Esempio n. 11
0
    async def dispatch(self, request: Request,
                       call_next: RequestResponseEndpoint) -> Response:
        """Processes the whole request APM capturing.

        Args:
            request (Request)
            call_next (RequestResponseEndpoint): Next request process in Starlette.

        Returns:
            Response
        """
        await self._request_started(request)

        try:
            response = await call_next(request)
            elasticapm.set_transaction_outcome(constants.OUTCOME.SUCCESS,
                                               override=False)
        except Exception:
            await self.capture_exception(
                context={
                    "request":
                    await get_data_from_request(request, self.client.config,
                                                constants.ERROR)
                })
            elasticapm.set_transaction_result("HTTP 5xx", override=False)
            elasticapm.set_transaction_outcome(constants.OUTCOME.FAILURE,
                                               override=False)
            elasticapm.set_context({"status_code": 500}, "response")

            raise
        else:
            await self._request_finished(response)
        finally:
            self.client.end_transaction()

        return response
Esempio n. 12
0
    def process_response(self, request, response):
        if django_settings.DEBUG and not self.client.config.debug:
            return response
        if request.META.get('HTTP_USER_AGENT') == 'mcod-heartbeat':
            return response
        try:
            if hasattr(response, "status_code"):
                try:
                    route = request.resolver_match.route
                except AttributeError:
                    route = request.path

                transaction_name = route_to_name(route,
                                                 prefix='admin',
                                                 method=request.method)
                if transaction_name:
                    elasticapm.set_transaction_name(transaction_name,
                                                    override=False)

                elasticapm.set_context(
                    lambda: self.client.get_data_from_request(
                        request,
                        capture_body=self.client.config.capture_body in
                        ("all", "transactions")),
                    "request",
                )
                elasticapm.set_context(
                    lambda: self.client.get_data_from_response(response),
                    "response")
                elasticapm.set_context(
                    lambda: self.client.get_user_info(request), "user")
                elasticapm.set_transaction_result("HTTP {}xx".format(
                    response.status_code // 100),
                                                  override=False)
        except Exception:
            self.client.error_logger.error(
                "Exception during timing of request", exc_info=True)
        return response
Esempio n. 13
0
    def process_response(self, request, response):
        try:
            if hasattr(response, 'status_code'):
                # check if _elasticapm_transaction_name is set
                if hasattr(request, '_elasticapm_transaction_name'):
                    transaction_name = request._elasticapm_transaction_name
                elif getattr(request, '_elasticapm_view_func', False):
                    transaction_name = get_name_from_func(
                        request._elasticapm_view_func)
                else:
                    transaction_name = ''

                status_code = response.status_code
                transaction_name = build_name_with_http_method_prefix(
                    transaction_name, request)
                request_data = lambda: self.client.get_data_from_request(
                    request,
                    capture_body=self.client.config.capture_body in
                    ('all', 'transactions'))
                response_data = lambda: self.client.get_data_from_response(
                    response)
                elasticapm.set_context(request_data, 'request')
                elasticapm.set_context(response_data, 'response')

                user_data = lambda: self.client.get_user_info(request)
                if user_data:
                    elasticapm.set_context(user_data, 'user')

                self.client.end_transaction(
                    transaction_name, 'HTTP {}xx'.format(status_code // 100))
        except Exception:
            self.client.error_logger.error(
                'Exception during timing of request',
                exc_info=True,
            )
        return response
Esempio n. 14
0
    def set_metadata_and_context(self, coldstart: bool) -> None:
        """
        Process the metadata and context fields for this request
        """
        metadata = {}
        cloud_context = {"origin": {"provider": "aws"}}
        service_context = {}
        message_context = {}

        faas = {}
        faas["coldstart"] = coldstart
        faas["trigger"] = {"type": "other"}
        faas["execution"] = self.context.aws_request_id

        if self.source == "api":
            faas["trigger"]["type"] = "http"
            faas["trigger"]["request_id"] = self.event["requestContext"][
                "requestId"]
            path = (self.event["requestContext"].get("resourcePath")
                    or self.event["requestContext"]["http"]["path"].split(
                        self.event["requestContext"]["stage"])[-1])
            service_context["origin"] = {
                "name":
                "{} {}/{}".format(
                    self.httpmethod,
                    self.event["requestContext"]["stage"],
                    path,
                )
            }
            service_context["origin"]["id"] = self.event["requestContext"][
                "apiId"]
            service_context["origin"]["version"] = self.event.get(
                "version", "1.0")
            cloud_context["origin"] = {}
            cloud_context["origin"]["service"] = {"name": "api gateway"}
            cloud_context["origin"]["account"] = {
                "id": self.event["requestContext"]["accountId"]
            }
            cloud_context["origin"]["provider"] = "aws"
        elif self.source == "sqs":
            record = self.event["Records"][0]
            faas["trigger"]["type"] = "pubsub"
            faas["trigger"]["request_id"] = record["messageId"]
            service_context["origin"] = {}
            service_context["origin"]["name"] = record["eventSourceARN"].split(
                ":")[5]
            service_context["origin"]["id"] = record["eventSourceARN"]
            cloud_context["origin"] = {}
            cloud_context["origin"]["service"] = {"name": "sqs"}
            cloud_context["origin"]["region"] = record["awsRegion"]
            cloud_context["origin"]["account"] = {
                "id": record["eventSourceARN"].split(":")[4]
            }
            cloud_context["origin"]["provider"] = "aws"
            message_context["queue"] = service_context["origin"]["name"]
            if "SentTimestamp" in record["attributes"]:
                message_context["age"] = {
                    "ms":
                    int((time.time() * 1000) -
                        int(record["attributes"]["SentTimestamp"]))
                }
            if self.client.config.capture_body in ("transactions",
                                                   "all") and "body" in record:
                message_context["body"] = record["body"]
            if self.client.config.capture_headers and record.get(
                    "messageAttributes"):
                message_context["headers"] = record["messageAttributes"]
        elif self.source == "sns":
            record = self.event["Records"][0]
            faas["trigger"]["type"] = "pubsub"
            faas["trigger"]["request_id"] = record["Sns"]["TopicArn"]
            service_context["origin"] = {}
            service_context["origin"]["name"] = record["Sns"][
                "TopicArn"].split(":")[5]
            service_context["origin"]["id"] = record["Sns"]["TopicArn"]
            service_context["origin"]["version"] = record["EventVersion"]
            service_context["origin"]["service"] = {"name": "sns"}
            cloud_context["origin"] = {}
            cloud_context["origin"]["region"] = record["Sns"][
                "TopicArn"].split(":")[3]
            cloud_context["origin"]["account_id"] = record["Sns"][
                "TopicArn"].split(":")[4]
            cloud_context["origin"]["provider"] = "aws"
            message_context["queue"] = service_context["origin"]["name"]
            if "Timestamp" in record["Sns"]:
                message_context["age"] = {
                    "ms":
                    int((datetime.datetime.now() - datetime.datetime.strptime(
                        record["Sns"]["Timestamp"],
                        r"%Y-%m-%dT%H:%M:%S.%fZ")).total_seconds() * 1000)
                }
            if self.client.config.capture_body in (
                    "transactions", "all") and "Message" in record["Sns"]:
                message_context["body"] = record["Sns"]["Message"]
            if self.client.config.capture_headers and record["Sns"].get(
                    "MessageAttributes"):
                message_context["headers"] = record["Sns"]["MessageAttributes"]
        elif self.source == "s3":
            record = self.event["Records"][0]
            faas["trigger"]["type"] = "datasource"
            faas["trigger"]["request_id"] = record["responseElements"][
                "x-amz-request-id"]
            service_context["origin"] = {}
            service_context["origin"]["name"] = record["s3"]["bucket"]["name"]
            service_context["origin"]["id"] = record["s3"]["bucket"]["arn"]
            service_context["origin"]["version"] = record["eventVersion"]
            cloud_context["origin"] = {}
            cloud_context["origin"]["service"] = {"name": "s3"}
            cloud_context["origin"]["region"] = record["awsRegion"]
            cloud_context["origin"]["provider"] = "aws"

        metadata["service"] = {}
        metadata["service"]["name"] = os.environ.get(
            "AWS_LAMBDA_FUNCTION_NAME")
        metadata["service"]["framework"] = {"name": "AWS Lambda"}
        metadata["service"]["runtime"] = {
            "name": os.environ.get("AWS_EXECUTION_ENV"),
            "version": platform.python_version(),
        }
        arn = self.context.invoked_function_arn
        if len(arn.split(":")) > 7:
            arn = ":".join(arn.split(":")[:7])
        metadata["service"]["id"] = arn
        metadata["service"]["version"] = os.environ.get(
            "AWS_LAMBDA_FUNCTION_VERSION")
        metadata["service"]["node"] = {
            "configured_name": os.environ.get("AWS_LAMBDA_LOG_STREAM_NAME")
        }
        # This is the one piece of metadata that requires deep merging. We add it manually
        # here to avoid having to deep merge in _transport.add_metadata()
        if self.client._transport._metadata:
            node_name = nested_key(self.client._transport._metadata, "service",
                                   "node", "name")
            if node_name:
                metadata["service"]["node"]["name"] = node_name

        metadata["cloud"] = {}
        metadata["cloud"]["provider"] = "aws"
        metadata["cloud"]["region"] = os.environ.get("AWS_REGION")
        metadata["cloud"]["service"] = {"name": "lambda"}
        metadata["cloud"]["account"] = {"id": arn.split(":")[4]}

        elasticapm.set_context(cloud_context, "cloud")
        elasticapm.set_context(service_context, "service")
        # faas doesn't actually belong in context, but we handle this in to_dict
        elasticapm.set_context(faas, "faas")
        if message_context:
            elasticapm.set_context(service_context, "message")
        self.client._transport.add_metadata(metadata)
Esempio n. 15
0
    async def __call__(self, scope, receive, send):
        """
        Args:
            scope: ASGI scope dictionary
            receive: receive awaitable callable
            send: send awaitable callable
        """
        # we only handle the http scope, skip anything else.
        if scope["type"] != "http":
            await self.app(scope, receive, send)
            return

        @functools.wraps(send)
        async def wrapped_send(message):
            if message.get("type") == "http.response.start":
                await set_context(
                    lambda: get_data_from_response(message, self.client.config,
                                                   constants.TRANSACTION),
                    "response")
                result = "HTTP {}xx".format(message["status"] // 100)
                elasticapm.set_transaction_result(result, override=False)
            await send(message)

        # When we consume the body from receive, we replace the streaming
        # mechanism with a mocked version -- this workaround came from
        # https://github.com/encode/starlette/issues/495#issuecomment-513138055
        body = b""
        while True:
            message = await receive()
            if not message:
                break
            if message["type"] == "http.request":
                b = message.get("body", b"")
                if b:
                    body += b
                if not message.get("more_body", False):
                    break
            if message["type"] == "http.disconnect":
                break

        async def _receive() -> Message:
            await asyncio.sleep(0)
            return {"type": "http.request", "body": body}

        request = Request(scope, receive=_receive)
        await self._request_started(request)

        try:
            await self.app(scope, _receive, wrapped_send)
            elasticapm.set_transaction_outcome(constants.OUTCOME.SUCCESS,
                                               override=False)
        except Exception:
            await self.capture_exception(
                context={
                    "request":
                    await get_data_from_request(request, self.client.config,
                                                constants.ERROR)
                })
            elasticapm.set_transaction_result("HTTP 5xx", override=False)
            elasticapm.set_transaction_outcome(constants.OUTCOME.FAILURE,
                                               override=False)
            elasticapm.set_context({"status_code": 500}, "response")

            raise
        finally:
            self.client.end_transaction()
Esempio n. 16
0
    async def handle_request(request, handler):
        elasticapm_client = get_client() if client is None else client
        should_trace = elasticapm_client and not elasticapm_client.should_ignore_url(
            request.path)
        if should_trace:
            trace_parent = AioHttpTraceParent.from_headers(request.headers)
            elasticapm_client.begin_transaction("request",
                                                trace_parent=trace_parent)
            resource = request.match_info.route.resource
            name = request.method
            if resource:
                # canonical has been added in 3.3, and returns one of path, formatter, prefix
                for attr in ("canonical", "_path", "_formatter", "_prefix"):
                    if hasattr(resource, attr):
                        name += " " + getattr(resource, attr)
                        break
                else:
                    name += " unknown route"
            else:
                name += " unknown route"
            elasticapm.set_transaction_name(name, override=False)
            elasticapm.set_context(
                lambda: get_data_from_request(request, elasticapm_client.
                                              config, constants.TRANSACTION),
                "request")

        try:
            response = await handler(request)
            if should_trace:
                elasticapm.set_transaction_result("HTTP {}xx".format(
                    response.status // 100),
                                                  override=False)
                elasticapm.set_transaction_outcome(
                    http_status_code=response.status, override=False)
                elasticapm.set_context(
                    lambda:
                    get_data_from_response(response, elasticapm_client.config,
                                           constants.TRANSACTION),
                    "response",
                )
            return response
        except HTTPException as exc:
            # HTTPExceptions are response-like, e.g. have headers and status code. They can represent an HTTP
            # response below a 500 status code and therefore not something to capture as exception. Like
            # HTTPOk can be raised but will most likely be wrongly tagged as an APM error. Let's try and
            # capture this according to the status.
            if exc.status_code < 500 and not should_trace:
                raise
            if elasticapm_client:
                elasticapm.set_transaction_result("HTTP {}xx".format(
                    exc.status_code // 100),
                                                  override=False)
                elasticapm.set_transaction_outcome(
                    http_status_code=exc.status_code, override=False)
                elasticapm.set_context(
                    lambda: get_data_from_response(
                        exc,  # noqa: F821
                        elasticapm_client.config,
                        constants.ERROR if exc.status_code >= 500 else
                        constants.TRANSACTION,  # noqa: F821
                    ),
                    "response",
                )
                if exc.status_code >= 500:
                    elasticapm_client.capture_exception(
                        context={
                            "request":
                            get_data_from_request(request, elasticapm_client.
                                                  config, constants.ERROR)
                        })
            raise
        except Exception:
            if elasticapm_client:
                elasticapm.set_transaction_result("HTTP 5xx", override=False)
                elasticapm.set_transaction_outcome(http_status_code=500,
                                                   override=False)
                elasticapm.set_context({"status_code": 500}, "response")
                elasticapm_client.capture_exception(
                    context={
                        "request":
                        get_data_from_request(
                            request, elasticapm_client.config, constants.ERROR)
                    })
            raise
        finally:
            elasticapm_client.end_transaction()
Esempio n. 17
0
def test_dedot_context_keys(elasticapm_client):
    elasticapm_client.begin_transaction("test")
    elasticapm.set_context({"d.o.t": "d_o_t", "s*t*a*r": "s_t_a_r", "q*u*o*t*e": "q_u_o_t_e"})
    elasticapm_client.end_transaction("foo", 200)
    transaction = elasticapm_client.events[TRANSACTION][0]
    assert transaction["context"]["custom"] == {"s_t_a_r": "s_t_a_r", "q_u_o_t_e": "q_u_o_t_e", "d_o_t": "d_o_t"}
Esempio n. 18
0
def set_context(data, key="custom"):
    if data:
        elasticapm.set_context(json.loads(data), key)