| Viewing file:  models.py (9.19 KB)      -rw-r--r-- Select action/file-type:
 
  (+) |  (+) |  (+) | Code (+) | Session (+) |  (+) | SDB (+) |  (+) |  (+) |  (+) |  (+) |  (+) | 
 
"""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()
 
 |