Exemple #1
0
    def event_processor(self, event, hint, asgi_scope):
        # type: (Event, Hint, Any) -> Optional[Event]
        request_info = event.get("request", {})

        if asgi_scope["type"] in ("http", "websocket"):
            request_info["url"] = self.get_url(asgi_scope)
            request_info["method"] = asgi_scope["method"]
            request_info["headers"] = _filter_headers(
                self.get_headers(asgi_scope))
            request_info["query_string"] = self.get_query(asgi_scope)

        if asgi_scope.get("client") and _should_send_default_pii():
            request_info["env"] = {"REMOTE_ADDR": asgi_scope["client"][0]}

        if asgi_scope.get("endpoint"):
            # Webframeworks like Starlette mutate the ASGI env once routing is
            # done, which is sometime after the request has started. If we have
            # an endpoint, overwrite our path-based transaction name.
            event["transaction"] = self.get_transaction(asgi_scope)

        event["request"] = partial_serialize(Hub.current.client,
                                             request_info,
                                             should_repr_strings=False)

        return event
    def sanic_processor(event, hint):
        # type: (Event, Optional[Hint]) -> Optional[Event]

        try:
            if hint and issubclass(hint["exc_info"][0], SanicException):
                return None
        except KeyError:
            pass

        request = weak_request()
        if request is None:
            return event

        with capture_internal_exceptions():
            extractor = SanicRequestExtractor(request)
            extractor.extract_into_event(event)

            request_info = event["request"]
            urlparts = urlparse.urlsplit(request.url)

            request_info["url"] = "%s://%s%s" % (
                urlparts.scheme,
                urlparts.netloc,
                urlparts.path,
            )

            request_info["query_string"] = urlparts.query
            request_info["method"] = request.method
            request_info["env"] = {"REMOTE_ADDR": request.remote_addr}
            request_info["headers"] = _filter_headers(dict(request.headers))

        return event
Exemple #3
0
    def tornado_processor(event, hint):
        # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]
        handler = weak_handler()
        if handler is None:
            return event

        request = handler.request

        with capture_internal_exceptions():
            method = getattr(handler, handler.request.method.lower())
            event["transaction"] = transaction_from_function(method)

        with capture_internal_exceptions():
            extractor = TornadoRequestExtractor(request)
            extractor.extract_into_event(event)

            request_info = event["request"]

            request_info["url"] = "%s://%s%s" % (
                request.protocol,
                request.host,
                request.path,
            )

            request_info["query_string"] = request.query
            request_info["method"] = request.method
            request_info["env"] = {"REMOTE_ADDR": request.remote_ip}
            request_info["headers"] = _filter_headers(dict(request.headers))

        with capture_internal_exceptions():
            if handler.current_user and _should_send_default_pii():
                event.setdefault("user", {})["is_authenticated"] = True

        return event
Exemple #4
0
    def event_processor(event, hint):
        with capture_internal_exceptions():
            # if the code below fails halfway through we at least have some data
            request_info = event.setdefault("request", {})

            if _should_send_default_pii():
                user_info = event.setdefault("user", {})
                if "ip_address" not in user_info:
                    user_info["ip_address"] = get_client_ip(environ)

            if "url" not in request_info:
                request_info["url"] = get_request_url(environ)

            if "query_string" not in request_info:
                request_info["query_string"] = environ.get("QUERY_STRING")

            if "method" not in request_info:
                request_info["method"] = environ.get("REQUEST_METHOD")

            if "env" not in request_info:
                request_info["env"] = dict(_get_environ(environ))

            if "headers" not in request_info:
                request_info["headers"] = _filter_headers(dict(_get_headers(environ)))

        return event
    def aiohttp_processor(
            event,  # type: Dict[str, Any]
            hint,  # type: Dict[str, Tuple[type, BaseException, Any]]
    ):
        # type: (...) -> Dict[str, Any]
        request = weak_request()
        if request is None:
            return event

        with capture_internal_exceptions():
            # TODO: Figure out what to do with request body. Methods on request
            # are async, but event processors are not.

            request_info = event.setdefault("request", {})

            request_info["url"] = "%s://%s%s" % (
                request.scheme,
                request.host,
                request.path,
            )

            request_info["query_string"] = request.query_string
            request_info["method"] = request.method
            request_info["env"] = {"REMOTE_ADDR": request.remote}
            request_info["headers"] = _filter_headers(dict(request.headers))

        return event
Exemple #6
0
    def aiohttp_processor(event, hint):
        request = weak_request()
        if request is None:
            return event

        with capture_internal_exceptions():
            # TODO: Figure out what to do with request body. Methods on request
            # are async, but event processors are not.

            request_info = event.setdefault("request", {})

            if "url" not in request_info:
                request_info["url"] = "%s://%s%s" % (
                    request.scheme,
                    request.host,
                    request.path,
                )

            if "query_string" not in request_info:
                request_info["query_string"] = request.query_string

            if "method" not in request_info:
                request_info["method"] = request.method

            if "env" not in request_info:
                request_info["env"] = {"REMOTE_ADDR": request.remote}

            if "headers" not in request_info:
                request_info["headers"] = _filter_headers(dict(
                    request.headers))

        return event
Exemple #7
0
    def event_processor(self, event, hint, asgi_scope):
        # type: (Event, Hint, Any) -> Optional[Event]
        request_info = event.get("request", {})

        ty = asgi_scope["type"]
        if ty in ("http", "websocket"):
            request_info["method"] = asgi_scope.get("method")
            request_info["headers"] = headers = _filter_headers(
                self._get_headers(asgi_scope))
            request_info["query_string"] = self._get_query(asgi_scope)

            request_info["url"] = self._get_url(
                asgi_scope, "http" if ty == "http" else "ws",
                headers.get("host"))

        client = asgi_scope.get("client")
        if client and _should_send_default_pii():
            request_info["env"] = {"REMOTE_ADDR": self._get_ip(asgi_scope)}

        if (event.get("transaction",
                      _DEFAULT_TRANSACTION_NAME) == _DEFAULT_TRANSACTION_NAME):
            endpoint = asgi_scope.get("endpoint")
            # Webframeworks like Starlette mutate the ASGI env once routing is
            # done, which is sometime after the request has started. If we have
            # an endpoint, overwrite our generic transaction name.
            if endpoint:
                event["transaction"] = transaction_from_function(endpoint)

        event["request"] = request_info

        return event
Exemple #8
0
    def aiohttp_processor(
            event,  # type: Dict[str, Any]
            hint,  # type: Dict[str, Tuple[type, BaseException, Any]]
    ):
        # type: (...) -> Dict[str, Any]
        request = weak_request()
        if request is None:
            return event

        with capture_internal_exceptions():
            request_info = event.setdefault("request", {})

            request_info["url"] = "%s://%s%s" % (
                request.scheme,
                request.host,
                request.path,
            )

            request_info["query_string"] = request.query_string
            request_info["method"] = request.method
            request_info["env"] = {"REMOTE_ADDR": request.remote}

            hub = Hub.current
            request_info["headers"] = _filter_headers(dict(request.headers))

            # Just attach raw data here if it is within bounds, if available.
            # Unfortunately there's no way to get structured data from aiohttp
            # without awaiting on some coroutine.
            request_info["data"] = get_aiohttp_request_data(hub, request)

        return event
Exemple #9
0
    def sanic_processor(event, hint):
        # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]
        request = weak_request()
        if request is None:
            return event

        with capture_internal_exceptions():
            extractor = SanicRequestExtractor(request)
            extractor.extract_into_event(event)

            request_info = event["request"]
            urlparts = urlparse.urlsplit(request.url)

            request_info["url"] = "%s://%s%s" % (
                urlparts.scheme,
                urlparts.netloc,
                urlparts.path,
            )

            request_info["query_string"] = urlparts.query
            request_info["method"] = request.method
            request_info["env"] = {"REMOTE_ADDR": request.remote_addr}
            request_info["headers"] = _filter_headers(dict(request.headers))

        return event
    def event_processor(sentry_event, hint, start_time=start_time):
        # type: (Event, Hint, datetime) -> Optional[Event]
        remaining_time_in_milis = aws_context.get_remaining_time_in_millis()
        exec_duration = configured_timeout - remaining_time_in_milis

        extra = sentry_event.setdefault("extra", {})
        extra["lambda"] = {
            "function_name": aws_context.function_name,
            "function_version": aws_context.function_version,
            "invoked_function_arn": aws_context.invoked_function_arn,
            "aws_request_id": aws_context.aws_request_id,
            "execution_duration_in_millis": exec_duration,
            "remaining_time_in_millis": remaining_time_in_milis,
        }

        extra["cloudwatch logs"] = {
            "url": _get_cloudwatch_logs_url(aws_context, start_time),
            "log_group": aws_context.log_group_name,
            "log_stream": aws_context.log_stream_name,
        }

        request = sentry_event.get("request", {})

        if "httpMethod" in aws_event:
            request["method"] = aws_event["httpMethod"]

        request["url"] = _get_url(aws_event, aws_context)

        if "queryStringParameters" in aws_event:
            request["query_string"] = aws_event["queryStringParameters"]

        if "headers" in aws_event:
            request["headers"] = _filter_headers(aws_event["headers"])

        if _should_send_default_pii():
            user_info = sentry_event.setdefault("user", {})

            id = aws_event.get("identity", {}).get("userArn")
            if id is not None:
                user_info.setdefault("id", id)

            ip = aws_event.get("identity", {}).get("sourceIp")
            if ip is not None:
                user_info.setdefault("ip_address", ip)

            if "body" in aws_event:
                request["data"] = aws_event.get("body", "")
        else:
            if aws_event.get("body", None):
                # Unfortunately couldn't find a way to get structured body from AWS
                # event. Meaning every body is unstructured to us.
                request["data"] = AnnotatedValue(
                    "", {"rem": [["!raw", "x", 0, 0]]})

        sentry_event["request"] = request

        return sentry_event
Exemple #11
0
def _process_common(data, wrapper):
    data["url"] = "%s://%s%s" % (wrapper.scheme, wrapper.host, wrapper.path)
    data["query_string"] = urllib.parse.unquote(
        wrapper._scope["query_string"].decode("latin-1"))
    data["env"] = {}
    data["headers"] = _filter_headers(dict(wrapper.headers.items()))

    if wrapper._scope.get("client") and _should_send_default_pii():
        data["env"]["REMOTE_ADDR"] = wrapper._scope["client"][0]
Exemple #12
0
    def event_processor(event, hint):
        # type: (Event, Hint) -> Optional[Event]

        final_time = datetime.utcnow()
        time_diff = final_time - initial_time

        execution_duration_in_millis = time_diff.microseconds / MILLIS_TO_SECONDS

        extra = event.setdefault("extra", {})
        extra["google cloud functions"] = {
            "function_name": environ.get("FUNCTION_NAME"),
            "function_entry_point": environ.get("ENTRY_POINT"),
            "function_identity": environ.get("FUNCTION_IDENTITY"),
            "function_region": environ.get("FUNCTION_REGION"),
            "function_project": environ.get("GCP_PROJECT"),
            "execution_duration_in_millis": execution_duration_in_millis,
            "configured_timeout_in_seconds": configured_timeout,
        }

        extra["google cloud logs"] = {
            "url": _get_google_cloud_logs_url(final_time),
        }

        request = event.get("request", {})

        request["url"] = "gcp:///{}".format(environ.get("FUNCTION_NAME"))

        if hasattr(gcp_event, "method"):
            request["method"] = gcp_event.method

        if hasattr(gcp_event, "query_string"):
            request["query_string"] = gcp_event.query_string.decode("utf-8")

        if hasattr(gcp_event, "headers"):
            request["headers"] = _filter_headers(gcp_event.headers)

        if _should_send_default_pii():
            if hasattr(gcp_event, "data"):
                request["data"] = gcp_event.data
        else:
            if hasattr(gcp_event, "data"):
                # Unfortunately couldn't find a way to get structured body from GCP
                # event. Meaning every body is unstructured to us.
                request["data"] = AnnotatedValue(
                    "", {"rem": [["!raw", "x", 0, 0]]})

        event["request"] = request

        return event
Exemple #13
0
    def event_processor(event, hint):
        # type: (Event, Hint) -> Optional[Event]
        extra = event.setdefault("extra", {})
        extra["lambda"] = {
            "remaining_time_in_millis":
            aws_context.get_remaining_time_in_millis(),
            "function_name": aws_context.function_name,
            "function_version": aws_context.function_version,
            "invoked_function_arn": aws_context.invoked_function_arn,
            "aws_request_id": aws_context.aws_request_id,
        }

        request = event.get("request", {})

        if "httpMethod" in aws_event:
            request["method"] = aws_event["httpMethod"]

        request["url"] = _get_url(aws_event, aws_context)

        if "queryStringParameters" in aws_event:
            request["query_string"] = aws_event["queryStringParameters"]

        if "headers" in aws_event:
            request["headers"] = _filter_headers(aws_event["headers"])

        if aws_event.get("body", None):
            # Unfortunately couldn't find a way to get structured body from AWS
            # event. Meaning every body is unstructured to us.
            request["data"] = AnnotatedValue("",
                                             {"rem": [["!raw", "x", 0, 0]]})

        if _should_send_default_pii():
            user_info = event.setdefault("user", {})

            id = aws_event.get("identity", {}).get("userArn")
            if id is not None:
                user_info["id"] = id

            ip = aws_event.get("identity", {}).get("sourceIp")
            if ip is not None:
                user_info["ip_address"] = ip

        event["request"] = partial_serialize(Hub.current.client,
                                             request,
                                             should_repr_strings=False)

        return event
Exemple #14
0
def _make_wsgi_event_processor(environ):
    # type: (Dict[str, str]) -> EventProcessor
    # It's a bit unfortunate that we have to extract and parse the request data
    # from the environ so eagerly, but there are a few good reasons for this.
    #
    # We might be in a situation where the scope/hub never gets torn down
    # properly. In that case we will have an unnecessary strong reference to
    # all objects in the environ (some of which may take a lot of memory) when
    # we're really just interested in a few of them.
    #
    # Keeping the environment around for longer than the request lifecycle is
    # also not necessarily something uWSGI can deal with:
    # https://github.com/unbit/uwsgi/issues/1950

    client_ip = get_client_ip(environ)
    request_url = get_request_url(environ)
    query_string = environ.get("QUERY_STRING")
    method = environ.get("REQUEST_METHOD")
    env = dict(_get_environ(environ))
    headers = _filter_headers(dict(_get_headers(environ)))

    def event_processor(event, hint):
        # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]
        with capture_internal_exceptions():
            # if the code below fails halfway through we at least have some data
            request_info = event.setdefault("request", {})

            if _should_send_default_pii():
                user_info = event.setdefault("user", {})
                if client_ip:
                    user_info["ip_address"] = client_ip

            request_info["url"] = request_url
            request_info["query_string"] = query_string
            request_info["method"] = method
            request_info["env"] = env
            request_info["headers"] = headers

        return event

    return event_processor
Exemple #15
0
    def inner(event, hint):
        # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]
        # if the request is gone we are fine not logging the data from
        # it.  This might happen if the processor is pushed away to
        # another thread.
        if request is None:
            return event

        with capture_internal_exceptions():
            # TODO: Figure out what to do with request body. Methods on request
            # are async, but event processors are not.

            request_info = event.setdefault("request", {})
            request_info["url"] = request.url
            request_info["query_string"] = request.query_string
            request_info["method"] = request.method
            request_info["headers"] = _filter_headers(dict(request.headers))

            if _should_send_default_pii():
                request_info["env"] = {"REMOTE_ADDR": request.access_route[0]}
                _add_user_to_event(event)

        return event
Exemple #16
0
    def sanic_processor(event, hint):
        request = weak_request()
        if request is None:
            return event

        with capture_internal_exceptions():
            extractor = SanicRequestExtractor(request)
            extractor.extract_into_event(event)

            request_info = event["request"]
            if "query_string" not in request_info:
                request_info["query_string"] = extractor.urlparts.query

            if "method" not in request_info:
                request_info["method"] = request.method

            if "env" not in request_info:
                request_info["env"] = {"REMOTE_ADDR": request.remote_addr}

            if "headers" not in request_info:
                request_info["headers"] = _filter_headers(dict(
                    request.headers))

        return event
    def event_processor(event, hint):
        extra = event.setdefault("extra", {})
        extra["lambda"] = {
            "remaining_time_in_millis":
            aws_context.get_remaining_time_in_millis(),
            "function_name": aws_context.function_name,
            "function_version": aws_context.function_version,
            "invoked_function_arn": aws_context.invoked_function_arn,
            "aws_request_id": aws_context.aws_request_id,
        }

        request = event.setdefault("request", {})

        if "httpMethod" in aws_event and "method" not in request:
            request["method"] = aws_event["httpMethod"]
        if "url" not in request:
            request["url"] = _get_url(aws_event, aws_context)
        if "queryStringParameters" in aws_event and "query_string" not in request:
            request["query_string"] = aws_event["queryStringParameters"]
        if "headers" in aws_event and "headers" not in request:
            request["headers"] = _filter_headers(aws_event["headers"])
        if aws_event.get("body", None):
            # Unfortunately couldn't find a way to get structured body from AWS
            # event. Meaning every body is unstructured to us.
            request["data"] = AnnotatedValue("",
                                             {"rem": [["!raw", "x", 0, 0]]})

        if _should_send_default_pii():
            user_info = event.setdefault("user", {})
            if "id" not in user_info:
                user_info["id"] = aws_event.get("identity", {}).get("userArn")
            if "ip_address" not in user_info:
                user_info["ip_address"] = aws_event.get("identity",
                                                        {}).get("sourceIp")

        return event