Ejemplo n.º 1
0
def _capture_exception(exception):
    with capture_internal_exceptions():
        hub = Hub.current
        event, hint = event_from_exception(
            exception,
            with_locals=hub.client.options["with_locals"],
            mechanism={
                "type": "sanic",
                "handled": False
            },
        )

        hub.capture_event(event, hint=hint)
Ejemplo n.º 2
0
    def event_processor(event, hint):
        request = weak_request()
        if request is None:
            return event

        try:
            if integration.transaction_style == "route_name":
                event["transaction"] = request.matched_route.name
            elif integration.transaction_style == "route_pattern":
                event["transaction"] = request.matched_route.pattern
        except Exception:
            pass

        with capture_internal_exceptions():
            PyramidRequestExtractor(request).extract_into_event(event)

        if _should_send_default_pii():
            with capture_internal_exceptions():
                user_info = event.setdefault("user", {})
                user_info["id"] = authenticated_userid(request)

        return event
Ejemplo n.º 3
0
    def event_processor(event, hint):
        with capture_internal_exceptions():
            event["transaction"] = task.name

        with capture_internal_exceptions():
            extra = event.setdefault("extra", {})
            extra["celery-job"] = {
                "task_name": task.name,
                "args": args,
                "kwargs": kwargs,
            }

        if "exc_info" in hint:
            with capture_internal_exceptions():
                if issubclass(hint["exc_info"][0], SoftTimeLimitExceeded):
                    event["fingerprint"] = [
                        "celery",
                        "SoftTimeLimitExceeded",
                        getattr(task, "name", task),
                    ]

        return event
Ejemplo n.º 4
0
def _process_ws(event, hint):
    if not hasattr(current, "websocket"):
        return event

    wrapper = current.websocket

    with capture_internal_exceptions():
        data = event.setdefault("request", {})
        _process_common(data, wrapper)

    event["transaction"] = wrapper.name

    return event
Ejemplo n.º 5
0
def _sentry_start_response(old_start_response,
                           span,
                           status,
                           response_headers,
                           exc_info=None):
    # type: (Callable[[str, U, Optional[E]], T], Span, str, U, Optional[E]) -> T
    with capture_internal_exceptions():
        status_int = int(status.split(" ", 1)[0])
        span.set_tag("http.status_code", status_int)
        if 500 <= status_int < 600:
            span.set_failure()

    return old_start_response(status, response_headers, exc_info)
Ejemplo n.º 6
0
        def sentry_report_done(*args, **kwargs):
            with capture_internal_exceptions():
                hub = Hub.current
                integration = hub.get_integration(AwsLambdaIntegration)
                if integration is not None:
                    # Flush out the event queue before AWS kills the
                    # process. This is not threadsafe.
                    # make new transport with empty queue
                    new_transport = hub.client.transport.copy()
                    hub.client.close()
                    hub.client.transport = new_transport

            return old_report_done(*args, **kwargs)
Ejemplo n.º 7
0
    def event_processor(event, hint):
        # 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.
        request = weak_request()
        if request is None:
            return event

        if "transaction" not in event:
            try:
                event["transaction"] = resolve(request.path).func.__name__
            except Exception:
                pass

        with capture_internal_exceptions():
            DjangoRequestExtractor(request).extract_into_event(event)

        if _should_send_default_pii():
            with capture_internal_exceptions():
                _set_user_info(request, event)

        return event
Ejemplo n.º 8
0
    def event_processor(event, hint):
        job = weak_job()
        if job is not None:
            with capture_internal_exceptions():
                event["transaction"] = job.func_name

            with capture_internal_exceptions():
                extra = event.setdefault("extra", {})
                extra["rq-job"] = {
                    "job_id": job.id,
                    "func": job.func_name,
                    "args": job.args,
                    "kwargs": job.kwargs,
                    "description": job.description,
                }

        if "exc_info" in hint:
            with capture_internal_exceptions():
                if issubclass(hint["exc_info"][0], JobTimeoutException):
                    event["fingerprint"] = ["rq", "JobTimeoutException", job.func_name]

        return event
Ejemplo n.º 9
0
    def inner(event, hint):
        request = weak_request()

        # 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():
            ClasticRequestExtractor(request).extract_into_event(event)

        return event
Ejemplo n.º 10
0
    def _emit(self, record):
        if not self.can_record(record):
            return

        hub = Hub.current
        integration = hub.get_integration(LoggingIntegration)
        if integration is None:
            return

        if self._should_create_event(record):
            with capture_internal_exceptions():
                hint = None
                # exc_info might be None or (None, None, None)
                if record.exc_info is not None and record.exc_info[
                        0] is not None:
                    event, hint = event_from_exception(
                        record.exc_info,
                        client_options=hub.client.options,
                        mechanism={
                            "type": "logging",
                            "handled": True
                        },
                    )
                else:
                    event = {}

                event["level"] = self._logging_to_event_level(record.levelname)
                event["logger"] = record.name
                event["logentry"] = {
                    "message": to_string(record.msg),
                    "params": record.args,
                }

                hub.capture_event(event, hint=hint)

        with capture_internal_exceptions():
            hub.add_breadcrumb(self._breadcrumb_from_record(record),
                               hint={"log_record": record})
Ejemplo n.º 11
0
    def sentry_sdk_excepthook(exctype, value, traceback):
        with capture_internal_exceptions():
            hub = Hub.current
            event, hint = event_from_exception(
                (exctype, value, traceback),
                with_locals=hub.client.options["with_locals"],
                mechanism={
                    "type": "excepthook",
                    "handled": False
                },
            )
            hub.capture_event(event, hint=hint)

        return old_excepthook(exctype, value, traceback)
Ejemplo n.º 12
0
    def sentry_sdk_excepthook(exctype, value, traceback):
        hub = Hub.current
        integration = hub.get_integration(ExcepthookIntegration)

        if integration is not None and _should_send(integration.always_run):
            with capture_internal_exceptions():
                event, hint = event_from_exception(
                    (exctype, value, traceback),
                    client_options=hub.client.options,
                    mechanism={"type": "excepthook", "handled": False},
                )
                hub.capture_event(event, hint=hint)

        return old_excepthook(exctype, value, traceback)
Ejemplo n.º 13
0
    def inner(event, hint):
        request = weak_request()

        # 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

        if "transaction" not in event:
            try:
                event["transaction"] = request.url_rule.endpoint
            except Exception:
                pass

        with capture_internal_exceptions():
            FlaskRequestExtractor(request).extract_into_event(event)

        if _should_send_default_pii():
            with capture_internal_exceptions():
                _add_user_to_event(event)

        return event
Ejemplo n.º 14
0
    def sentry_handler(event, context, *args, **kwargs):
        # type: (Any, Any, *Any, **Any) -> Any
        hub = Hub.current
        integration = hub.get_integration(AwsLambdaIntegration)
        if integration is None:
            return handler(event, context, *args, **kwargs)

        # If an integration is there, a client has to be there.
        client = hub.client  # type: Any
        configured_time = context.get_remaining_time_in_millis()

        with hub.push_scope() as scope:
            with capture_internal_exceptions():
                scope.clear_breadcrumbs()
                scope.add_event_processor(
                    _make_request_event_processor(event, context,
                                                  configured_time))
                scope.set_tag("aws_region",
                              context.invoked_function_arn.split(":")[3])
                # Starting the Timeout thread only if the configured time is greater than Timeout warning
                # buffer and timeout_warning parameter is set True.
                if (integration.timeout_warning
                        and configured_time > TIMEOUT_WARNING_BUFFER):
                    waiting_time = (configured_time -
                                    TIMEOUT_WARNING_BUFFER) / MILLIS_TO_SECONDS

                    timeout_thread = TimeoutThread(
                        waiting_time, configured_time / MILLIS_TO_SECONDS)

                    # Starting the thread to raise timeout warning exception
                    timeout_thread.start()

            headers = event.get("headers", {})
            transaction = Transaction.continue_from_headers(
                headers, op="serverless.function", name=context.function_name)
            with hub.start_transaction(transaction):
                try:
                    return handler(event, context, *args, **kwargs)
                except Exception:
                    exc_info = sys.exc_info()
                    event, hint = event_from_exception(
                        exc_info,
                        client_options=client.options,
                        mechanism={
                            "type": "aws_lambda",
                            "handled": False
                        },
                    )
                    hub.capture_event(event, hint=hint)
                    reraise(*exc_info)
Ejemplo n.º 15
0
    def _emit(self, record):
        # type: (LogRecord) -> None
        if not _can_record(record):
            return

        hub = Hub.current
        if hub.client is None:
            return

        client_options = hub.client.options

        # exc_info might be None or (None, None, None)
        if record.exc_info is not None and record.exc_info[0] is not None:
            event, hint = event_from_exception(
                record.exc_info,
                client_options=client_options,
                mechanism={
                    "type": "logging",
                    "handled": True
                },
            )
        elif record.exc_info and record.exc_info[0] is None:
            event = {}
            hint = {}
            with capture_internal_exceptions():
                event["threads"] = {
                    "values": [{
                        "stacktrace":
                        current_stacktrace(client_options["with_locals"]),
                        "crashed":
                        False,
                        "current":
                        True,
                    }]
                }
        else:
            event = {}
            hint = {}

        hint["log_record"] = record

        event["level"] = _logging_to_event_level(record.levelname)
        event["logger"] = record.name
        event["logentry"] = {
            "message": to_string(record.msg),
            "params": record.args
        }
        event["extra"] = _extra_from_record(record)

        hub.capture_event(event, hint=hint)
Ejemplo n.º 16
0
def add_context(event: 'Event', hint: 'Hint') -> Optional['Event']:
    if "exc_info" in hint:
        _, exc_value, _ = hint["exc_info"]
        # Ignore GeneratorExit, KeyboardInterrupt, and SystemExit exceptions
        if not isinstance(exc_value, Exception):
            return None
    from zerver.models import get_user_profile_by_id
    with capture_internal_exceptions():
        user_info = event.get("user", {})
        if user_info.get("id"):
            user_profile = get_user_profile_by_id(user_info["id"])
            user_info["realm"] = user_profile.realm.string_id or 'root'
            user_info["role"] = user_profile.get_role_name()
    return event
Ejemplo n.º 17
0
def _patch_drf():
    """
    Patch Django Rest Framework for more/better request data. DRF's request
    type is a wrapper around Django's request type. The attribute we're
    interested in is `request.data`, which is a cached property containing a
    parsed request body. Reading a request body from that property is more
    reliable than reading from any of Django's own properties, as those don't
    hold payloads in memory and therefore can only be accessed once.

    We patch the Django request object to include a weak backreference to the
    DRF request object, such that we can later use either in
    `DjangoRequestExtractor`.

    This function is not called directly on SDK setup, because importing almost
    any part of Django Rest Framework will try to access Django settings (where
    `sentry_sdk.init()` might be called from in the first place). Instead we
    run this function on every request and do the patching on the first
    request.
    """

    global _DRF_PATCHED

    if _DRF_PATCHED:
        # Double-checked locking
        return

    with _DRF_PATCH_LOCK:
        if _DRF_PATCHED:
            return

        # We set this regardless of whether the code below succeeds or fails.
        # There is no point in trying to patch again on the next request.
        _DRF_PATCHED = True

        with capture_internal_exceptions():
            try:
                from rest_framework.views import APIView  # type: ignore
            except ImportError:
                pass
            else:
                old_drf_initial = APIView.initial

                def sentry_patched_drf_initial(self, request, *args, **kwargs):
                    with capture_internal_exceptions():
                        request._request._sentry_drf_request_backref = weakref.ref(
                            request)
                        pass
                    return old_drf_initial(self, request, *args, **kwargs)

                APIView.initial = sentry_patched_drf_initial
Ejemplo n.º 18
0
    def event_processor(event, hint):
        # type: (Event, Hint) -> Optional[Event]

        with capture_internal_exceptions():
            tags = event.setdefault("tags", {})
            tags["celery_task_id"] = uuid
            extra = event.setdefault("extra", {})
            extra["celery-job"] = {
                "task_name": task.name,
                "args": args,
                "kwargs": kwargs,
            }

        if "exc_info" in hint:
            with capture_internal_exceptions():
                if issubclass(hint["exc_info"][0], SoftTimeLimitExceeded):
                    event["fingerprint"] = [
                        "celery",
                        "SoftTimeLimitExceeded",
                        getattr(task, "name", task),
                    ]

        return event
Ejemplo n.º 19
0
def _process_http(event, hint):
    if not hasattr(current, "request"):
        return event

    wrapper = current.request

    with capture_internal_exceptions():
        data = event.setdefault("request", {})
        _process_common(data, wrapper)
        data["method"] = wrapper.method
        data["content_length"] = wrapper.content_length

    event["transaction"] = wrapper.name

    return event
Ejemplo n.º 20
0
def run_wsgi_app(app, environ, start_response):
    hub = Hub.current
    hub.push_scope()
    with capture_internal_exceptions():
        with hub.configure_scope() as scope:
            scope.add_event_processor(_make_wsgi_event_processor(environ))

    try:
        rv = app(environ, start_response)
    except Exception:
        einfo = _capture_exception(hub)
        hub.pop_scope_unsafe()
        reraise(*einfo)

    return _ScopePoppingResponse(hub, rv)
Ejemplo n.º 21
0
    def _serialize_node(self, obj, max_depth=None, max_breadth=None):
        # type: (Any, Optional[int], Optional[int]) -> Any
        with capture_internal_exceptions():
            with self.memo.memoize(obj) as result:
                if result:
                    return CYCLE_MARKER

                return self._serialize_node_impl(obj,
                                                 max_depth=max_depth,
                                                 max_breadth=max_breadth)

        if self.meta_node.is_databag():
            return u"<failed to serialize, use init(debug=True) to see error logs>"

        return None
Ejemplo n.º 22
0
    def event_processor(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.
        request = weak_request()
        if request is None:
            return event

        try:
            drf_request = request._sentry_drf_request_backref()
            if drf_request is not None:
                request = drf_request
        except AttributeError:
            pass

        with capture_internal_exceptions():
            DjangoRequestExtractor(request).extract_into_event(event)

        if _should_send_default_pii():
            with capture_internal_exceptions():
                _set_user_info(request, event)

        return event
Ejemplo n.º 23
0
    def apply_to_event(self, event, hint=None):
        # type: (Dict[str, Any], Dict[str, Any]) -> Optional[Dict[str, Any]]
        """Applies the information contained on the scope to the given event."""
        def _drop(event, cause, ty):
            # type: (Dict[str, Any], Callable, str) -> Optional[Any]
            logger.info("%s (%s) dropped event (%s)", ty, cause, event)
            return None

        if self._level is not None:
            event["level"] = self._level

        event.setdefault("breadcrumbs", []).extend(self._breadcrumbs)
        if event.get("user") is None and self._user is not None:
            event["user"] = self._user

        if event.get("transaction") is None and self._transaction is not None:
            event["transaction"] = self._transaction

        if event.get("fingerprint") is None and self._fingerprint is not None:
            event["fingerprint"] = self._fingerprint

        if self._extras:
            event.setdefault("extra", {}).update(object_to_json(self._extras))

        if self._tags:
            event.setdefault("tags", {}).update(self._tags)

        if self._contexts:
            event.setdefault("contexts", {}).update(self._contexts)

        exc_info = hint.get("exc_info") if hint is not None else None
        if exc_info is not None:
            for processor in self._error_processors:
                new_event = processor(event, exc_info)
                if new_event is None:
                    return _drop(event, processor, "error processor")
                event = new_event

        for processor in chain(global_event_processors,
                               self._event_processors):
            new_event = event
            with capture_internal_exceptions():
                new_event = processor(event, hint)
            if new_event is None:
                return _drop(event, processor, "event processor")
            event = new_event

        return event
Ejemplo n.º 24
0
    def __call__(self, environ, start_response):
        hub = Hub(Hub.current)

        with hub:
            with capture_internal_exceptions():
                with hub.configure_scope() as scope:
                    scope._name = "wsgi"
                    scope.add_event_processor(
                        _make_wsgi_event_processor(environ))

            try:
                rv = self.app(environ, start_response)
            except Exception:
                reraise(*_capture_exception(hub))

        return _ScopedResponse(hub, rv)
Ejemplo n.º 25
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", {})
                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
Ejemplo n.º 26
0
def _capture_exception(exception):
    if isinstance(exception, SanicException):
        return

    hub = Hub.current
    integration = hub.get_integration(SanicIntegration)
    if integration is None:
        return

    with capture_internal_exceptions():
        event, hint = event_from_exception(
            exception,
            client_options=hub.client.options,
            mechanism={"type": "sanic", "handled": False},
        )
        hub.capture_event(event, hint=hint)
Ejemplo n.º 27
0
    def sentry_patched_popen_init(self, *a, **kw):
        # type: (subprocess.Popen[Any], *Any, **Any) -> None

        hub = Hub.current
        if hub.get_integration(StdlibIntegration) is None:
            return old_popen_init(self, *a, **kw)  # type: ignore

        # Convert from tuple to list to be able to set values.
        a = list(a)

        args = _init_argument(a, kw, "args", 0) or []
        cwd = _init_argument(a, kw, "cwd", 9)

        # if args is not a list or tuple (and e.g. some iterator instead),
        # let's not use it at all. There are too many things that can go wrong
        # when trying to collect an iterator into a list and setting that list
        # into `a` again.
        #
        # Also invocations where `args` is not a sequence are not actually
        # legal. They just happen to work under CPython.
        description = None

        if isinstance(args, (list, tuple)) and len(args) < 100:
            with capture_internal_exceptions():
                description = " ".join(map(str, args))

        if description is None:
            description = safe_repr(args)

        env = None

        with hub.start_span(op="subprocess", description=description) as span:

            for k, v in hub.iter_trace_propagation_headers(span):
                if env is None:
                    env = _init_argument(
                        a, kw, "env", 10, lambda x: dict(x or os.environ)
                    )
                env["SUBPROCESS_" + k.upper().replace("-", "_")] = v

            if cwd:
                span.set_data("subprocess.cwd", cwd)

            rv = old_popen_init(self, *a, **kw)  # type: ignore

            span.set_tag("subprocess.pid", self.pid)
            return rv
Ejemplo n.º 28
0
    def _capture_event(self, event):
        with capture_internal_exceptions():
            key = self.project_key
            if key is None:
                return

            if not is_current_event_safe():
                metrics.incr("internal.uncaptured.events", skip_internal=False)
                sdk_logger.warn("internal-error.unsafe-stacktrace")
                return

            auth = Auth(
                scheme="https",
                host="localhost",
                project_id=key.project_id,
                public_key=key.public_key,
                secret_key=key.secret_key,
                client="sentry-python/%s" % SDK_VERSION,
            )

            headers = {
                "HTTP_X_SENTRY_AUTH": auth.to_header(),
                "HTTP_CONTENT_ENCODING": "deflate"
            }

            request = self.request_factory.post(
                "/api/{}/store/".format(key.project_id),
                data=zlib.compress(json.dumps(event).encode("utf8")),
                content_type="application/octet-stream",
                **headers)

            from sentry.web.api import StoreView

            resp = StoreView.as_view()(request,
                                       project_id=six.text_type(
                                           key.project_id))

            if resp.status_code != 200:
                sdk_logger.warn(
                    "internal-error.invalid-response",
                    extra={
                        "project_id": settings.SENTRY_PROJECT,
                        "project_key": settings.SENTRY_PROJECT_KEY,
                        "status_code": resp.status_code,
                    },
                )
Ejemplo n.º 29
0
    def inner(event, hint):
        # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]

        try:
            if integration.transaction_style == "endpoint":
                event[
                    "transaction"] = request.route.name or transaction_from_function(
                        request.route.callback)
            elif integration.transaction_style == "url":
                event["transaction"] = request.route.rule
        except Exception:
            pass

        with capture_internal_exceptions():
            BottleRequestExtractor(request).extract_into_event(event)

        return event
Ejemplo n.º 30
0
def _capture_exception(exception):
    # type: (Union[Tuple[Optional[type], Optional[BaseException], Any], BaseException]) -> None
    hub = Hub.current
    integration = hub.get_integration(SanicIntegration)
    if integration is None:
        return

    # If an integration is there, a client has to be there.
    client = hub.client  # type: Any

    with capture_internal_exceptions():
        event, hint = event_from_exception(
            exception,
            client_options=client.options,
            mechanism={"type": "sanic", "handled": False},
        )
        hub.capture_event(event, hint=hint)
Ejemplo n.º 31
0
    def event_processor(event, hint):
        request = weak_request()
        if request is None:
            return event

        with capture_internal_exceptions():
            _set_user_info(request, event)
            request_info = event.setdefault("request", {})
            request_info["cookies"] = dict(request.COOKIES)

        scrub_data(event.get("request", {}))
        if 'exception' in event:
            exc = event.get("exception", {})
            for val in exc.get('values', []):
                stack = val.get('stacktrace', {})
                for frame in stack.get('frames', []):
                    scrub_data(frame['vars'])
        return event
Ejemplo n.º 32
0
Archivo: sdk.py Proyecto: yaoqi/sentry
    def _capture_event(self, event):
        with capture_internal_exceptions():
            key = self.project_key
            if key is None:
                return

            if not is_current_event_safe():
                metrics.incr('internal.uncaptured.events', skip_internal=False)
                sdk_logger.warn('internal-error.unsafe-stacktrace')
                return

            auth = Auth(
                scheme="https",
                host="localhost",
                project_id=key.project_id,
                public_key=key.public_key,
                secret_key=key.secret_key,
                client="sentry-python/%s" % SDK_VERSION
            )

            headers = {
                'HTTP_X_SENTRY_AUTH': auth.to_header(),
                'HTTP_CONTENT_ENCODING': 'deflate'
            }

            request = self.request_factory.post(
                '/api/{}/store/'.format(key.project_id),
                data=zlib.compress(json.dumps(event).encode('utf8')),
                content_type='application/octet-stream',
                **headers
            )

            from sentry.web.api import StoreView
            resp = StoreView.as_view()(
                request,
                project_id=six.text_type(key.project_id),
            )

            if resp.status_code != 200:
                sdk_logger.warn('internal-error.invalid-response', extra={
                    'project_id': settings.SENTRY_PROJECT,
                    'project_key': settings.SENTRY_PROJECT_KEY,
                    'status_code': resp.status_code,
                })
Ejemplo n.º 33
0
def ignore_retry(event, hint):
    with capture_internal_exceptions():
        if isinstance(hint["exc_info"][1], Retry):
            return None
    return event
Ejemplo n.º 34
0
Archivo: sdk.py Proyecto: yaoqi/sentry
 def transport(event):
     with capture_internal_exceptions():
         metrics.incr('internal.uncaptured.events', skip_internal=False)
         sdk_logger.warn('internal-error.noop-hub')