Exemplo n.º 1
0
    def process(self, **kwargs):
        from sentry.helpers import get_filters

        kwargs.setdefault("level", logging.ERROR)
        kwargs.setdefault("server_name", conf.NAME)

        checksum = construct_checksum(**kwargs)

        if conf.THRASHING_TIMEOUT and conf.THRASHING_LIMIT:
            cache_key = "sentry:%s:%s" % (kwargs.get("class_name") or "", checksum)
            added = cache.add(cache_key, 1, conf.THRASHING_TIMEOUT)
            try:
                if not added and cache.incr(cache_key) > conf.THRASHING_LIMIT:
                    return
            except KeyError:
                pass

        for filter_ in get_filters():
            kwargs = filter_(None).process(kwargs) or kwargs

        # Make sure all additional data is coerced
        if "data" in kwargs:
            kwargs["data"] = transform(kwargs["data"])

        return self.send(**kwargs)
Exemplo n.º 2
0
    def process(self, **kwargs):
        from sentry.helpers import get_filters

        kwargs.setdefault('level', logging.ERROR)
        kwargs.setdefault('server_name', conf.NAME)

        if 'checksum' not in kwargs:
            checksum = construct_checksum(**kwargs)
        else:
            checksum = kwargs['checksum']

        if conf.THRASHING_TIMEOUT and conf.THRASHING_LIMIT:
            cache_key = 'sentry:%s:%s' % (kwargs.get('class_name') or '', checksum)
            added = cache.add(cache_key, 1, conf.THRASHING_TIMEOUT)
            if not added:
                try:
                    thrash_count = cache.incr(cache_key)
                except (KeyError, ValueError):
                    # cache.incr can fail. Assume we aren't thrashing yet, and
                    # if we are, hope that the next error has a successful
                    # cache.incr call.
                    thrash_count = 0
                if thrash_count > conf.THRASHING_LIMIT:
                    return

        for filter_ in get_filters():
            kwargs = filter_(None).process(kwargs) or kwargs
        
        # Make sure all additional data is coerced
        if 'data' in kwargs:
            kwargs['data'] = transform(kwargs['data'])

        return self.send(**kwargs)
Exemplo n.º 3
0
    def process(self, **kwargs):
        from sentry.helpers import get_filters

        kwargs.setdefault('level', logging.ERROR)
        kwargs.setdefault('server_name', conf.NAME)

        if 'checksum' not in kwargs:
            checksum = construct_checksum(**kwargs)
        else:
            checksum = kwargs['checksum']

        if conf.THRASHING_TIMEOUT and conf.THRASHING_LIMIT:
            cache_key = 'sentry:%s:%s' % (kwargs.get('class_name') or '', checksum)
            added = cache.add(cache_key, 1, conf.THRASHING_TIMEOUT)
            try:
                if not added and cache.incr(cache_key) > conf.THRASHING_LIMIT:
                    return
            except KeyError:
                pass

        for filter_ in get_filters():
            kwargs = filter_(None).process(kwargs) or kwargs
        
        # Make sure all additional data is coerced
        if 'data' in kwargs:
            kwargs['data'] = transform(kwargs['data'])

        return self.send(**kwargs)
Exemplo n.º 4
0
    def process(self, **kwargs):
        from sentry.helpers import get_filters

        for filter_ in get_filters():
            kwargs = filter_(None).process(kwargs) or kwargs

        kwargs.setdefault('level', logging.ERROR)
        kwargs.setdefault('server_name', socket.gethostname())

        checksum = construct_checksum(**kwargs)

        if settings.THRASHING_TIMEOUT and settings.THRASHING_LIMIT:
            cache_key = 'sentry:%s:%s' % (kwargs.get('class_name'), checksum)
            added = cache.add(cache_key, 1, settings.THRASHING_TIMEOUT)
            if not added and cache.incr(cache_key) > settings.THRASHING_LIMIT:
                return

        if settings.REMOTE_URL:
            data = {
                'data': base64.b64encode(pickle.dumps(transform(kwargs)).encode('zlib')),
                'key': settings.KEY,
            }
            req = urllib2.Request(settings.REMOTE_URL, urllib.urlencode(data))

            try:
                response = urllib2.urlopen(req, None, settings.REMOTE_TIMEOUT).read()
            except urllib2.URLError, e:
                logger.exception('Unable to reach Sentry log server')
            except urllib2.HTTPError, e:
                logger.exception('Unable to reach Sentry log server', extra={'body': e.read()})
Exemplo n.º 5
0
    def process(self, **kwargs):
        from sentry.helpers import get_filters

        kwargs.setdefault('level', logging.ERROR)
        kwargs.setdefault('server_name', conf.NAME)

        # save versions of all installed apps
        if 'data' not in kwargs or '__sentry__' not in (kwargs['data'] or {}):
            if kwargs.get('data') is None:
                kwargs['data'] = {}
            kwargs['data']['__sentry__'] = {}

        versions = get_versions()
        kwargs['data']['__sentry__']['versions'] = versions

        if kwargs.get('view'):
            # get list of modules from right to left
            parts = kwargs['view'].split('.')
            module_list = ['.'.join(parts[:idx]) for idx in xrange(1, len(parts)+1)][::-1]
            version = None
            for m in module_list:
                if m in versions:
                    version = versions[m]

            # store our "best guess" for application version
            if version:
                kwargs['data']['__sentry__']['version'] = version

        if 'checksum' not in kwargs:
            checksum = construct_checksum(**kwargs)
        else:
            checksum = kwargs['checksum']

        if conf.THRASHING_TIMEOUT and conf.THRASHING_LIMIT:
            cache_key = 'sentry:%s:%s' % (kwargs.get('class_name') or '', checksum)
            added = cache.add(cache_key, 1, conf.THRASHING_TIMEOUT)
            if not added:
                try:
                    thrash_count = cache.incr(cache_key)
                except (KeyError, ValueError):
                    # cache.incr can fail. Assume we aren't thrashing yet, and
                    # if we are, hope that the next error has a successful
                    # cache.incr call.
                    thrash_count = 0
                if thrash_count > conf.THRASHING_LIMIT:
                    return

        for filter_ in get_filters():
            kwargs = filter_(None).process(kwargs) or kwargs
        
        # Make sure all data is coerced
        kwargs = transform(kwargs)

        return self.send(**kwargs)
Exemplo n.º 6
0
 def testUngzippedData(self):
     kwargs = {'message': 'hello', 'server_name': 'not_dcramer.local', 'level': 40}
     resp = self.client.post(reverse('sentry-store'), {
         'data': base64.b64encode(pickle.dumps(transform(kwargs))),
         'key': settings.KEY,
     })
     self.assertEquals(resp.status_code, 200)
     instance = Message.objects.get()
     self.assertEquals(instance.message, 'hello')
     self.assertEquals(instance.server_name, 'not_dcramer.local')
     self.assertEquals(instance.level, 40)
Exemplo n.º 7
0
    def test_transform_handles_gettext_lazy(self):
        from sentry.helpers import transform
        from django.utils.functional import lazy

        def fake_gettext(to_translate):
            return u'Igpay Atinlay'
        fake_gettext_lazy = lazy(fake_gettext, str)
        self.assertEquals(
            pickle.loads(pickle.dumps(
                    transform(fake_gettext_lazy("something")))),
            u'Igpay Atinlay')
Exemplo n.º 8
0
 def testUngzippedData(self):
     kwargs = {'message': 'hello', 'server_name': 'not_dcramer.local', 'level': 40, 'site': 'not_a_real_site'}
     resp = self.client.post(reverse('sentry-store'), {
         'data': base64.b64encode(pickle.dumps(transform(kwargs))),
         'key': conf.KEY,
     })
     self.assertEquals(resp.status_code, 200)
     instance = Message.objects.get()
     self.assertEquals(instance.message, 'hello')
     self.assertEquals(instance.server_name, 'not_dcramer.local')
     self.assertEquals(instance.site, 'not_a_real_site')
     self.assertEquals(instance.level, 40)
Exemplo n.º 9
0
 def testCorrectData(self):
     kwargs = {'message': 'hello', 'server_name': 'not_dcramer.local', 'level': 40, 'site': 'not_a_real_site'}
     resp = self.client.post(reverse('sentry-store'), {
         'data': base64.b64encode(pickle.dumps(transform(kwargs)).encode('zlib')),
         'key': conf.KEY,
     })
     self.assertEquals(resp.status_code, 200)
     instance = Message.objects.get()
     self.assertEquals(instance.message, 'hello')
     self.assertEquals(instance.server_name, 'not_dcramer.local')
     self.assertEquals(instance.level, 40)
     self.assertEquals(instance.site, 'not_a_real_site')
Exemplo n.º 10
0
    def send(self, **kwargs):
        if settings.REMOTE_URL:
            for url in settings.REMOTE_URL:
                data = {"data": base64.b64encode(pickle.dumps(transform(kwargs)).encode("zlib")), "key": settings.KEY}
                req = urllib2.Request(url, urllib.urlencode(data))

                try:
                    response = urllib2.urlopen(req, None, settings.REMOTE_TIMEOUT).read()
                except urllib2.URLError, e:
                    logger.exception("Unable to reach Sentry log server: %s" % (e,), extra={"remote_url": url})
                    logger.log(kwargs.pop("level", None) or logging.ERROR, kwargs.pop("message", None))
                except urllib2.HTTPError, e:
                    logger.exception(
                        "Unable to reach Sentry log server: %s" % (e,), extra={"body": e.read(), "remote_url": url}
                    )
                    logger.log(kwargs.pop("level", None) or logging.ERROR, kwargs.pop("message", None))
Exemplo n.º 11
0
 def testByteSequence(self):
     """
     invalid byte sequence for encoding "UTF8": 0xedb7af
     """
     fname = os.path.join(os.path.dirname(__file__), 'fixtures/encode_error.json')
     kwargs = simplejson.load(open(fname))
     
     resp = self.client.post(reverse('sentry-store'), {
         'data': base64.b64encode(pickle.dumps(transform(kwargs)).encode('zlib')),
         'key': settings.KEY,
     })
     self.assertEquals(resp.status_code, 200)
     instance = Message.objects.get()
     self.assertEquals(instance.message, 'hello')
     self.assertEquals(instance.server_name, 'localhost')
     self.assertEquals(instance.level, 40)
     self.assertTrue(instance.data['__sentry__']['exc'])
Exemplo n.º 12
0
    def send(self, **kwargs):
        if settings.REMOTE_URL:
            for url in settings.REMOTE_URL:
                data = {
                    'data': base64.b64encode(pickle.dumps(transform(kwargs)).encode('zlib')),
                    'key': settings.KEY,
                }
                req = urllib2.Request(url, urllib.urlencode(data))

                try:
                    response = urllib2.urlopen(req, None, settings.REMOTE_TIMEOUT).read()
                except urllib2.URLError, e:
                    logger.error('Unable to reach Sentry log server: %s' % (e,), exc_info=sys.exc_info(), extra={'remote_url': url})
                    logger.log(kwargs.pop('level', None) or logging.ERROR, kwargs.pop('message', None))
                except urllib2.HTTPError, e:
                    logger.error('Unable to reach Sentry log server: %s' % (e,), exc_info=sys.exc_info(), extra={'body': e.read(), 'remote_url': url})
                    logger.log(kwargs.pop('level', None) or logging.ERROR, kwargs.pop('message', None))
Exemplo n.º 13
0
    def process(self, **kwargs):
        from sentry.helpers import get_filters

        kwargs.setdefault('level', logging.ERROR)
        kwargs.setdefault('server_name', settings.NAME)

        checksum = construct_checksum(**kwargs)

        if settings.THRASHING_TIMEOUT and settings.THRASHING_LIMIT:
            cache_key = 'sentry:%s:%s' % (kwargs.get('class_name'), checksum)
            added = cache.add(cache_key, 1, settings.THRASHING_TIMEOUT)
            if not added and cache.incr(cache_key) > settings.THRASHING_LIMIT:
                return

        for filter_ in get_filters():
            kwargs = filter_(None).process(kwargs) or kwargs

        # Make sure all additional data is coerced
        if 'data' in kwargs:
            kwargs['data'] = transform(kwargs['data'])

        return self.send(**kwargs)
Exemplo n.º 14
0
    def process(self, **kwargs):
        "Processes the message before passing it on to the server"
        from sentry.helpers import get_filters

        if kwargs.get('data'):
            # Ensure we're not changing the original data which was passed
            # to Sentry
            kwargs['data'] = kwargs['data'].copy()

        request = kwargs.pop('request', None)
        if request:
            if not kwargs.get('data'):
                kwargs['data'] = {}
            kwargs['data'].update(
                dict(
                    META=request.META,
                    POST=request.POST,
                    GET=request.GET,
                    COOKIES=request.COOKIES,
                ))

            if not kwargs.get('url'):
                kwargs['url'] = request.build_absolute_uri()

        kwargs.setdefault('level', logging.ERROR)
        kwargs.setdefault('server_name', conf.NAME)

        # save versions of all installed apps
        if 'data' not in kwargs or '__sentry__' not in (kwargs['data'] or {}):
            if kwargs.get('data') is None:
                kwargs['data'] = {}
            kwargs['data']['__sentry__'] = {}

        versions = get_versions()
        kwargs['data']['__sentry__']['versions'] = versions

        if kwargs.get('view'):
            # get list of modules from right to left
            parts = kwargs['view'].split('.')
            module_list = [
                '.'.join(parts[:idx]) for idx in xrange(1,
                                                        len(parts) + 1)
            ][::-1]
            version = None
            module = None
            for m in module_list:
                if m in versions:
                    module = m
                    version = versions[m]

            # store our "best guess" for application version
            if version:
                kwargs['data']['__sentry__'].update({
                    'version': version,
                    'module': module,
                })

        if 'checksum' not in kwargs:
            checksum = construct_checksum(**kwargs)
        else:
            checksum = kwargs['checksum']

        if conf.THRASHING_TIMEOUT and conf.THRASHING_LIMIT:
            cache_key = 'sentry:%s:%s' % (kwargs.get('class_name')
                                          or '', checksum)
            added = cache.add(cache_key, 1, conf.THRASHING_TIMEOUT)
            if not added:
                try:
                    thrash_count = cache.incr(cache_key)
                except (KeyError, ValueError):
                    # cache.incr can fail. Assume we aren't thrashing yet, and
                    # if we are, hope that the next error has a successful
                    # cache.incr call.
                    thrash_count = 0
                if thrash_count > conf.THRASHING_LIMIT:
                    message_id = cache.get('%s:last_message_id' % cache_key)
                    if request:
                        # attach the sentry object to the request
                        request.sentry = {
                            'id': message_id,
                            'thrashed': True,
                        }
                    return message_id

        for filter_ in get_filters():
            kwargs = filter_(None).process(kwargs) or kwargs

        # create ID client-side so that it can be passed to application
        message_id = uuid.uuid4().hex
        kwargs['message_id'] = message_id

        # Make sure all data is coerced
        kwargs = transform(kwargs)

        self.send(**kwargs)

        if request:
            # attach the sentry object to the request
            request.sentry = {
                'id': message_id,
            }

        if conf.THRASHING_TIMEOUT and conf.THRASHING_LIMIT:
            # store the last message_id incase we hit thrashing limits
            cache.set('%s:last_message_id' % cache_key, message_id,
                      conf.THRASHING_LIMIT + 5)

        return message_id
Exemplo n.º 15
0
 def shorten(var):
     var = transform(var)
     if isinstance(var, basestring) and len(var) > 200:
         var = var[:200] + '...'
     return var
Exemplo n.º 16
0
    def create_from_exception(self, exc_info=None, **kwargs):
        """
        Creates an error log from an exception.
        """
        if not exc_info:
            exc_info = sys.exc_info()

        exc_type, exc_value, exc_traceback = exc_info

        def shorten(var):
            var = transform(var)
            if isinstance(var, basestring) and len(var) > 200:
                var = var[:200] + '...'
            return var

        reporter = ExceptionReporter(None, exc_type, exc_value, exc_traceback)
        frames = varmap(shorten, reporter.get_traceback_frames())

        if not kwargs.get('view'):
            # This should be cached
            modules = get_installed_apps()
            if conf.INCLUDE_PATHS:
                modules = set(list(modules) + conf.INCLUDE_PATHS)

            def iter_tb_frames(tb):
                while tb:
                    yield tb.tb_frame
                    tb = tb.tb_next

            def contains(iterator, value):
                for k in iterator:
                    if value.startswith(k):
                        return True
                return False

            # We iterate through each frame looking for an app in INSTALLED_APPS
            # When one is found, we mark it as last "best guess" (best_guess) and then
            # check it against SENTRY_EXCLUDE_PATHS. If it isnt listed, then we
            # use this option. If nothing is found, we use the "best guess".
            best_guess = None
            view = None
            for frame in iter_tb_frames(exc_traceback):
                try:
                    view = '.'.join(
                        [frame.f_globals['__name__'], frame.f_code.co_name])
                except:
                    continue
                if contains(modules, view):
                    if not (contains(conf.EXCLUDE_PATHS, view) and best_guess):
                        best_guess = view
                elif best_guess:
                    break
            if best_guess:
                view = best_guess

            if view:
                kwargs['view'] = view

        data = kwargs.pop('data', {}) or {}
        if hasattr(exc_type, '__class__'):
            exc_module = exc_type.__class__.__module__
        else:
            exc_module = None
        data['__sentry__'] = {
            'exc': map(transform, [exc_module, exc_value.args, frames]),
        }

        if (isinstance(exc_value, TemplateSyntaxError) and \
            isinstance(getattr(exc_value, 'source', None), (tuple, list)) and isinstance(exc_value.source[0], LoaderOrigin)):
            origin, (start, end) = exc_value.source
            data['__sentry__'].update({
                'template': (origin.reload(), start, end, origin.name),
            })
            kwargs['view'] = origin.loadname

        tb_message = '\n'.join(
            traceback.format_exception(exc_type, exc_value, exc_traceback))

        kwargs.setdefault('message', transform(force_unicode(exc_value)))

        return self.process(class_name=exc_type.__name__,
                            traceback=tb_message,
                            data=data,
                            **kwargs)
Exemplo n.º 17
0
    def process(self, **kwargs):
        "Processes the message before passing it on to the server"
        from sentry.helpers import get_filters

        if kwargs.get('data'):
            # Ensure we're not changing the original data which was passed
            # to Sentry
            kwargs['data'] = kwargs['data'].copy()

        request = kwargs.pop('request', None)
        if request:
            if not kwargs.get('data'):
                kwargs['data'] = {}

            if not request.POST and request.raw_post_data:
                post_data = request.raw_post_data
            else:
                post_data = request.POST

            kwargs['data'].update(dict(
                META=request.META,
                POST=post_data,
                GET=request.GET,
                COOKIES=request.COOKIES,
                REQUEST_USER=request.user,
            ))

            if not kwargs.get('url'):
                kwargs['url'] = request.build_absolute_uri()

        kwargs.setdefault('level', logging.ERROR)
        kwargs.setdefault('server_name', conf.NAME)

        # save versions of all installed apps
        if 'data' not in kwargs or '__sentry__' not in (kwargs['data'] or {}):
            if kwargs.get('data') is None:
                kwargs['data'] = {}
            kwargs['data']['__sentry__'] = {}

        versions = get_versions()
        kwargs['data']['__sentry__']['versions'] = versions

        # Shorten lists/strings
        for k, v in kwargs['data'].iteritems():
            if k == '__sentry__':
                continue
            kwargs['data'][k] = shorten(v)

        if kwargs.get('view'):
            # get list of modules from right to left
            parts = kwargs['view'].split('.')
            module_list = ['.'.join(parts[:idx]) for idx in xrange(1, len(parts)+1)][::-1]
            version = None
            module = None
            for m in module_list:
                if m in versions:
                    module = m
                    version = versions[m]

            # store our "best guess" for application version
            if version:
                kwargs['data']['__sentry__'].update({
                    'version': version,
                    'module': module,
                })

        if 'checksum' not in kwargs:
            checksum = construct_checksum(**kwargs)
        else:
            checksum = kwargs['checksum']

        if conf.THRASHING_TIMEOUT and conf.THRASHING_LIMIT:
            cache_key = 'sentry:%s:%s' % (kwargs.get('class_name') or '', checksum)
            added = cache.add(cache_key, 1, conf.THRASHING_TIMEOUT)
            if not added:
                try:
                    thrash_count = cache.incr(cache_key)
                except (KeyError, ValueError):
                    # cache.incr can fail. Assume we aren't thrashing yet, and
                    # if we are, hope that the next error has a successful
                    # cache.incr call.
                    thrash_count = 0
                if thrash_count > conf.THRASHING_LIMIT:
                    message_id = cache.get('%s:last_message_id' % cache_key)
                    if request:
                        # attach the sentry object to the request
                        request.sentry = {
                            'id': message_id,
                            'thrashed': True,
                        }
                    return message_id

        for filter_ in get_filters():
            kwargs = filter_(None).process(kwargs) or kwargs

        # create ID client-side so that it can be passed to application
        message_id = uuid.uuid4().hex
        kwargs['message_id'] = message_id

        # Make sure all data is coerced
        kwargs = transform(kwargs)

        self.send(**kwargs)

        if request:
            # attach the sentry object to the request
            request.sentry = {
                'id': message_id,
            }

        if conf.THRASHING_TIMEOUT and conf.THRASHING_LIMIT:
            # store the last message_id incase we hit thrashing limits
            cache.set('%s:last_message_id' % cache_key, message_id, conf.THRASHING_LIMIT+5)

        return message_id
Exemplo n.º 18
0
    def create_from_exception(self, exc_info=None, **kwargs):
        """
        Creates an error log from an exception.
        """
        if not exc_info:
            exc_info = sys.exc_info()

        exc_type, exc_value, exc_traceback = exc_info

        reporter = ExceptionReporter(None, exc_type, exc_value, exc_traceback)
        frames = varmap(shorten, reporter.get_traceback_frames())

        if not kwargs.get('view'):
            # This should be cached
            modules = get_installed_apps()
            if conf.INCLUDE_PATHS:
                modules = set(list(modules) + conf.INCLUDE_PATHS)

            def iter_tb_frames(tb):
                while tb:
                    yield tb.tb_frame
                    tb = tb.tb_next

            def contains(iterator, value):
                for k in iterator:
                    if value.startswith(k):
                        return True
                return False

            # We iterate through each frame looking for an app in INSTALLED_APPS
            # When one is found, we mark it as last "best guess" (best_guess) and then
            # check it against SENTRY_EXCLUDE_PATHS. If it isnt listed, then we
            # use this option. If nothing is found, we use the "best guess".
            best_guess = None
            view = None
            for frame in iter_tb_frames(exc_traceback):
                try:
                    view = '.'.join([frame.f_globals['__name__'], frame.f_code.co_name])
                except:
                    continue
                if contains(modules, view):
                    if not (contains(conf.EXCLUDE_PATHS, view) and best_guess):
                        best_guess = view
                elif best_guess:
                    break
            if best_guess:
                view = best_guess

            if view:
                kwargs['view'] = view

        data = kwargs.pop('data', {}) or {}
        if hasattr(exc_type, '__class__'):
            exc_module = exc_type.__class__.__module__
        else:
            exc_module = None
        data['__sentry__'] = {
            'exc': map(transform, [exc_module, exc_value.args, frames]),
        }

        if (isinstance(exc_value, TemplateSyntaxError) and \
            isinstance(getattr(exc_value, 'source', None), (tuple, list)) and isinstance(exc_value.source[0], LoaderOrigin)):
            origin, (start, end) = exc_value.source
            data['__sentry__'].update({
                'template': (origin.reload(), start, end, origin.name),
            })
            kwargs['view'] = origin.loadname

        tb_message = '\n'.join(traceback.format_exception(exc_type, exc_value, exc_traceback))

        kwargs.setdefault('message', transform(force_unicode(exc_value)))

        return self.process(
            class_name=exc_type.__name__,
            traceback=tb_message,
            data=data,
            **kwargs
        )
Exemplo n.º 19
0
    def process(self, **kwargs):
        "Processes the message before passing it on to the server"
        from sentry.helpers import get_filters

        if kwargs.get("data"):
            # Ensure we're not changing the original data which was passed
            # to Sentry
            kwargs["data"] = kwargs["data"].copy()

        request = kwargs.pop("request", None)
        if request:
            if not kwargs.get("data"):
                kwargs["data"] = {}
            kwargs["data"].update(dict(META=request.META, POST=request.POST, GET=request.GET, COOKIES=request.COOKIES))

            if not kwargs.get("url"):
                kwargs["url"] = request.build_absolute_uri()

        kwargs.setdefault("level", logging.ERROR)
        kwargs.setdefault("server_name", conf.NAME)

        # save versions of all installed apps
        if "data" not in kwargs or "__sentry__" not in (kwargs["data"] or {}):
            if kwargs.get("data") is None:
                kwargs["data"] = {}
            kwargs["data"]["__sentry__"] = {}

        versions = get_versions()
        kwargs["data"]["__sentry__"]["versions"] = versions

        if kwargs.get("view"):
            # get list of modules from right to left
            parts = kwargs["view"].split(".")
            module_list = [".".join(parts[:idx]) for idx in xrange(1, len(parts) + 1)][::-1]
            version = None
            module = None
            for m in module_list:
                if m in versions:
                    module = m
                    version = versions[m]

            # store our "best guess" for application version
            if version:
                kwargs["data"]["__sentry__"].update({"version": version, "module": module})

        if "checksum" not in kwargs:
            checksum = construct_checksum(**kwargs)
        else:
            checksum = kwargs["checksum"]

        if conf.THRASHING_TIMEOUT and conf.THRASHING_LIMIT:
            cache_key = "sentry:%s:%s" % (kwargs.get("class_name") or "", checksum)
            added = cache.add(cache_key, 1, conf.THRASHING_TIMEOUT)
            if not added:
                try:
                    thrash_count = cache.incr(cache_key)
                except (KeyError, ValueError):
                    # cache.incr can fail. Assume we aren't thrashing yet, and
                    # if we are, hope that the next error has a successful
                    # cache.incr call.
                    thrash_count = 0
                if thrash_count > conf.THRASHING_LIMIT:
                    message_id = cache.get("%s:last_message_id" % cache_key)
                    if request:
                        # attach the sentry object to the request
                        request.sentry = {"id": message_id, "thrashed": True}
                    return message_id

        for filter_ in get_filters():
            kwargs = filter_(None).process(kwargs) or kwargs

        # create ID client-side so that it can be passed to application
        message_id = uuid.uuid4().hex
        kwargs["message_id"] = message_id

        # Make sure all data is coerced
        kwargs = transform(kwargs)

        self.send(**kwargs)

        if request:
            # attach the sentry object to the request
            request.sentry = {"id": message_id}

        if conf.THRASHING_TIMEOUT and conf.THRASHING_LIMIT:
            # store the last message_id incase we hit thrashing limits
            cache.set("%s:last_message_id" % cache_key, message_id, conf.THRASHING_LIMIT + 5)

        return message_id
Exemplo n.º 20
0
 def shorten(var):
     var = transform(var)
     if isinstance(var, basestring) and len(var) > 200:
         var = var[:200] + "..."
     return var
Exemplo n.º 21
0
    def create_from_exception(self, exc_info=None, **kwargs):
        """
        Creates an error log from an exception.
        """
        if not exc_info:
            exc_info = sys.exc_info()

        exc_type, exc_value, exc_traceback = exc_info

        def shorten(var):
            var = transform(var)
            if isinstance(var, basestring) and len(var) > 200:
                var = var[:200] + "..."
            return var

        reporter = ExceptionReporter(None, exc_type, exc_value, exc_traceback)
        frames = varmap(shorten, reporter.get_traceback_frames())

        if not kwargs.get("view"):
            # This should be cached
            modules = get_installed_apps()
            if conf.INCLUDE_PATHS:
                modules = set(list(modules) + conf.INCLUDE_PATHS)

            def iter_tb_frames(tb):
                while tb:
                    yield tb.tb_frame
                    tb = tb.tb_next

            def contains(iterator, value):
                for k in iterator:
                    if value.startswith(k):
                        return True
                return False

            # We iterate through each frame looking for an app in INSTALLED_APPS
            # When one is found, we mark it as last "best guess" (best_guess) and then
            # check it against SENTRY_EXCLUDE_PATHS. If it isnt listed, then we
            # use this option. If nothing is found, we use the "best guess".
            best_guess = None
            view = None
            for frame in iter_tb_frames(exc_traceback):
                try:
                    view = ".".join([frame.f_globals["__name__"], frame.f_code.co_name])
                except:
                    continue
                if contains(modules, view):
                    if not (contains(conf.EXCLUDE_PATHS, view) and best_guess):
                        best_guess = view
                elif best_guess:
                    break
            if best_guess:
                view = best_guess

            if view:
                kwargs["view"] = view

        data = kwargs.pop("data", {}) or {}
        if hasattr(exc_type, "__class__"):
            exc_module = exc_type.__class__.__module__
        else:
            exc_module = None
        data["__sentry__"] = {"exc": map(transform, [exc_module, exc_value.args, frames])}

        if isinstance(exc_value, TemplateSyntaxError) and hasattr(exc_value, "source"):
            origin, (start, end) = exc_value.source
            data["__sentry__"].update({"template": (origin.reload(), start, end, origin.name)})
            kwargs["view"] = origin.loadname

        tb_message = "\n".join(traceback.format_exception(exc_type, exc_value, exc_traceback))

        kwargs.setdefault("message", transform(force_unicode(exc_value)))

        return self.process(class_name=exc_type.__name__, traceback=tb_message, data=data, **kwargs)
Exemplo n.º 22
0
 def get_prep_value(self, value):
     if value is None: return
     return base64.b64encode(pickle.dumps(transform(value)).encode('zlib'))
Exemplo n.º 23
0
 def get_prep_value(self, value):
     if value is None: return
     return base64.b64encode(pickle.dumps(transform(value)).encode('zlib'))