%PDF- %PDF-
Direktori : /opt/alt/python37/lib/python3.7/site-packages/raven/contrib/django/ |
Current File : //opt/alt/python37/lib/python3.7/site-packages/raven/contrib/django/models.py |
""" raven.contrib.django.models ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Acts as an implicit hook for Django installs. :copyright: (c) 2010-2012 by the Sentry Team, see AUTHORS for more details. :license: BSD, see LICENSE for more details. """ # flake8: noqa from __future__ import absolute_import, unicode_literals import logging import sys import warnings import django from django.conf import settings from django.core.signals import got_request_exception, request_started from threading import Lock from raven.utils.conf import convert_options from raven.utils.compat import PY2, binary_type, text_type from raven.utils.imports import import_string logger = logging.getLogger('sentry.errors.client') def get_installed_apps(): """ Modules in settings.INSTALLED_APPS as a set. """ return set(settings.INSTALLED_APPS) _client = (None, None) class ProxyClient(object): """ A proxy which represents the currently client at all times. """ # introspection support: __members__ = property(lambda x: x.__dir__()) # Need to pretend to be the wrapped class, for the sake of objects that care # about this (especially in equality tests) __class__ = property(lambda x: get_client().__class__) __dict__ = property(lambda o: get_client().__dict__) __repr__ = lambda x: repr(get_client()) __getattr__ = lambda x, o: getattr(get_client(), o) __setattr__ = lambda x, o, v: setattr(get_client(), o, v) __delattr__ = lambda x, o: delattr(get_client(), o) __lt__ = lambda x, o: get_client() < o __le__ = lambda x, o: get_client() <= o __eq__ = lambda x, o: get_client() == o __ne__ = lambda x, o: get_client() != o __gt__ = lambda x, o: get_client() > o __ge__ = lambda x, o: get_client() >= o if PY2: __cmp__ = lambda x, o: cmp(get_client(), o) # NOQA __hash__ = lambda x: hash(get_client()) # attributes are currently not callable # __call__ = lambda x, *a, **kw: get_client()(*a, **kw) __nonzero__ = lambda x: bool(get_client()) __len__ = lambda x: len(get_client()) __getitem__ = lambda x, i: get_client()[i] __iter__ = lambda x: iter(get_client()) __contains__ = lambda x, i: i in get_client() __getslice__ = lambda x, i, j: get_client()[i:j] __add__ = lambda x, o: get_client() + o __sub__ = lambda x, o: get_client() - o __mul__ = lambda x, o: get_client() * o __floordiv__ = lambda x, o: get_client() // o __mod__ = lambda x, o: get_client() % o __divmod__ = lambda x, o: get_client().__divmod__(o) __pow__ = lambda x, o: get_client() ** o __lshift__ = lambda x, o: get_client() << o __rshift__ = lambda x, o: get_client() >> o __and__ = lambda x, o: get_client() & o __xor__ = lambda x, o: get_client() ^ o __or__ = lambda x, o: get_client() | o __div__ = lambda x, o: get_client().__div__(o) __truediv__ = lambda x, o: get_client().__truediv__(o) __neg__ = lambda x: -(get_client()) __pos__ = lambda x: +(get_client()) __abs__ = lambda x: abs(get_client()) __invert__ = lambda x: ~(get_client()) __complex__ = lambda x: complex(get_client()) __int__ = lambda x: int(get_client()) if PY2: __long__ = lambda x: long(get_client()) # NOQA __float__ = lambda x: float(get_client()) __str__ = lambda x: binary_type(get_client()) __unicode__ = lambda x: text_type(get_client()) __oct__ = lambda x: oct(get_client()) __hex__ = lambda x: hex(get_client()) __index__ = lambda x: get_client().__index__() __coerce__ = lambda x, o: x.__coerce__(x, o) __enter__ = lambda x: x.__enter__() __exit__ = lambda x, *a, **kw: x.__exit__(*a, **kw) client = ProxyClient() def get_client(client=None, reset=False): global _client tmp_client = client is not None if not tmp_client: client = getattr(settings, 'SENTRY_CLIENT', 'raven.contrib.django.DjangoClient') if _client[0] != client or reset: options = convert_options( settings, defaults={ 'include_paths': get_installed_apps(), }, ) try: Client = import_string(client) except ImportError: logger.exception('Failed to import client: %s', client) if not _client[1]: # If there is no previous client, set the default one. client = 'raven.contrib.django.DjangoClient' _client = (client, get_client(client)) else: instance = Client(**options) if not tmp_client: _client = (client, instance) return instance return _client[1] def sentry_exception_handler(request=None, **kwargs): try: client.captureException(exc_info=sys.exc_info(), request=request) except Exception as exc: try: logger.exception('Unable to process log entry: %s' % (exc,)) except Exception as exc: warnings.warn('Unable to process log entry: %s' % (exc,)) class SentryDjangoHandler(object): def __init__(self, client=client): self.client = client try: import celery except ImportError: self.has_celery = False else: self.has_celery = celery.VERSION >= (2, 5) self.celery_handler = None def install_celery(self): from raven.contrib.celery import ( SentryCeleryHandler, register_logger_signal ) ignore_expected = getattr(settings, 'SENTRY_CELERY_IGNORE_EXPECTED', False) self.celery_handler = SentryCeleryHandler(client, ignore_expected=ignore_expected)\ .install() # try: # ga = lambda x, d=None: getattr(settings, 'SENTRY_%s' % x, d) # options = getattr(settings, 'RAVEN_CONFIG', {}) # loglevel = options.get('celery_loglevel', # ga('CELERY_LOGLEVEL', logging.ERROR)) # register_logger_signal(client, loglevel=loglevel) # except Exception: # logger.exception('Failed to install Celery error handler') def install(self): request_started.connect(self.before_request, weak=False) got_request_exception.connect(self.exception_handler, weak=False) if self.has_celery: try: self.install_celery() except Exception: logger.exception('Failed to install Celery error handler') def uninstall(self): request_started.disconnect(self.before_request) got_request_exception.disconnect(self.exception_handler) if self.celery_handler: self.celery_handler.uninstall() def exception_handler(self, request=None, **kwargs): try: self.client.captureException(exc_info=sys.exc_info(), request=request) except Exception as exc: try: logger.exception('Unable to process log entry: %s' % (exc,)) except Exception as exc: warnings.warn('Unable to process log entry: %s' % (exc,)) def before_request(self, *args, **kwargs): self.client.context.activate() def register_serializers(): # force import so serializers can call register import raven.contrib.django.serializers # NOQA def install_middleware(middleware_name, lookup_names=None): """ Install specified middleware """ if lookup_names is None: lookup_names = (middleware_name,) # default settings.MIDDLEWARE is None middleware_attr = 'MIDDLEWARE' if getattr(settings, 'MIDDLEWARE', None) is not None \ else 'MIDDLEWARE_CLASSES' # make sure to get an empty tuple when attr is None middleware = getattr(settings, middleware_attr, ()) or () if set(lookup_names).isdisjoint(set(middleware)): setattr(settings, middleware_attr, type(middleware)((middleware_name,)) + middleware) _setup_lock = Lock() _initialized = False def initialize(): global _initialized with _setup_lock: if _initialized: return # mark this as initialized immediatley to avoid recursive import issues _initialized = True try: register_serializers() install_middleware( 'raven.contrib.django.middleware.SentryMiddleware', ( 'raven.contrib.django.middleware.SentryMiddleware', 'raven.contrib.django.middleware.SentryLogMiddleware')) install_middleware( 'raven.contrib.django.middleware.DjangoRestFrameworkCompatMiddleware') # XXX(dcramer): maybe this setting should disable ALL of this? if not getattr(settings, 'DISABLE_SENTRY_INSTRUMENTATION', False): handler = SentryDjangoHandler() handler.install() # instantiate client so hooks get registered get_client() # NOQA except Exception: _initialized = False # Django 1.8 uses ``raven.contrib.apps.RavenConfig`` if django.VERSION < (1, 7, 0): initialize()