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
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
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
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
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
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
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
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]
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
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
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
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
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