def setup_once(): # type: () -> None if DJANGO_VERSION < (1, 6): raise DidNotEnable("Django 1.6 or newer is required.") install_sql_hook() # Patch in our custom middleware. # logs an error for every 500 ignore_logger("django.server") ignore_logger("django.request") from django.core.handlers.wsgi import WSGIHandler old_app = WSGIHandler.__call__ def sentry_patched_wsgi_handler(self, environ, start_response): # type: (Any, Dict[str, str], Callable[..., Any]) -> _ScopedResponse if Hub.current.get_integration(DjangoIntegration) is None: return old_app(self, environ, start_response) bound_old_app = old_app.__get__(self, WSGIHandler) from django.conf import settings use_x_forwarded_for = settings.USE_X_FORWARDED_HOST return SentryWsgiMiddleware(bound_old_app, use_x_forwarded_for)(environ, start_response) WSGIHandler.__call__ = sentry_patched_wsgi_handler _patch_get_response() _patch_django_asgi_handler() signals.got_request_exception.connect(_got_request_exception) @add_global_event_processor def process_django_templates(event, hint): # type: (Event, Optional[Hint]) -> Optional[Event] if hint is None: return event exc_info = hint.get("exc_info", None) if exc_info is None: return event exception = event.get("exception", None) if exception is None: return event values = exception.get("values", None) if values is None: return event for exception, (_, exc_value, _) in zip(reversed(values), walk_exception_chain(exc_info)): frame = get_template_frame_from_exception(exc_value) if frame is not None: frames = exception.get("stacktrace", {}).get("frames", []) for i in reversed(range(len(frames))): f = frames[i] if (f.get("function") in ("Parser.parse", "parse", "render") and f.get("module") == "django.template.base"): i += 1 break else: i = len(frames) frames.insert(i, frame) return event @add_global_repr_processor def _django_queryset_repr(value, hint): # type: (Any, Dict[str, Any]) -> Union[NotImplementedType, str] try: # Django 1.6 can fail to import `QuerySet` when Django settings # have not yet been initialized. # # If we fail to import, return `NotImplemented`. It's at least # unlikely that we have a query set in `value` when importing # `QuerySet` fails. from django.db.models.query import QuerySet except Exception: return NotImplemented if not isinstance(value, QuerySet) or value._result_cache: return NotImplemented # Do not call Hub.get_integration here. It is intentional that # running under a new hub does not suddenly start executing # querysets. This might be surprising to the user but it's likely # less annoying. return u"<%s from %s at 0x%x>" % ( value.__class__.__name__, value.__module__, id(value), ) _patch_channels() patch_django_middlewares() patch_views() patch_templates()
def setup_once(): # type: () -> None install_sql_hook() # Patch in our custom middleware. # logs an error for every 500 ignore_logger("django.server") ignore_logger("django.request") from django.core.handlers.wsgi import WSGIHandler old_app = WSGIHandler.__call__ def sentry_patched_wsgi_handler(self, environ, start_response): # type: (Any, Dict[str, str], Callable) -> _ScopedResponse if Hub.current.get_integration(DjangoIntegration) is None: return old_app(self, environ, start_response) bound_old_app = old_app.__get__(self, WSGIHandler) return SentryWsgiMiddleware(bound_old_app)(environ, start_response) WSGIHandler.__call__ = sentry_patched_wsgi_handler # patch get_response, because at that point we have the Django request # object from django.core.handlers.base import BaseHandler # type: ignore old_get_response = BaseHandler.get_response def sentry_patched_get_response(self, request): # type: (Any, WSGIRequest) -> Union[HttpResponse, BaseException] hub = Hub.current integration = hub.get_integration(DjangoIntegration) if integration is not None: _patch_drf() with hub.configure_scope() as scope: # Rely on WSGI middleware to start a trace try: if integration.transaction_style == "function_name": scope.transaction = transaction_from_function( resolve(request.path).func) elif integration.transaction_style == "url": scope.transaction = LEGACY_RESOLVER.resolve( request.path) except Exception: pass scope.add_event_processor( _make_event_processor(weakref.ref(request), integration)) return old_get_response(self, request) BaseHandler.get_response = sentry_patched_get_response signals.got_request_exception.connect(_got_request_exception) @add_global_event_processor def process_django_templates(event, hint): # type: (Event, Optional[Hint]) -> Optional[Event] if hint is None: return event exc_info = hint.get("exc_info", None) if exc_info is None: return event exception = event.get("exception", None) if exception is None: return event values = exception.get("values", None) if values is None: return event for exception, (_, exc_value, _) in zip(reversed(values), walk_exception_chain(exc_info)): frame = get_template_frame_from_exception(exc_value) if frame is not None: frames = exception.get("stacktrace", {}).get("frames", []) for i in reversed(range(len(frames))): f = frames[i] if (f.get("function") in ("parse", "render") and f.get("module") == "django.template.base"): i += 1 break else: i = len(frames) frames.insert(i, frame) return event @add_global_repr_processor def _django_queryset_repr(value, hint): try: # Django 1.6 can fail to import `QuerySet` when Django settings # have not yet been initialized. # # If we fail to import, return `NotImplemented`. It's at least # unlikely that we have a query set in `value` when importing # `QuerySet` fails. from django.db.models.query import QuerySet # type: ignore except Exception: return NotImplemented if not isinstance(value, QuerySet) or value._result_cache: return NotImplemented # Do not call Hub.get_integration here. It is intentional that # running under a new hub does not suddenly start executing # querysets. This might be surprising to the user but it's likely # less annoying. return u"<%s from %s at 0x%x>" % ( value.__class__.__name__, value.__module__, id(value), ) _patch_channels() patch_django_middlewares()