Exemplo n.º 1
0
def get_stack_info(frames):
    results = []
    for frame in frames:
        # Support hidden frames
        if frame.f_locals.get('__traceback_hide__'):
            continue

        filename = frame.f_code.co_filename
        function = frame.f_code.co_name
        lineno = frame.f_lineno - 1
        loader = frame.f_globals.get('__loader__')
        module_name = frame.f_globals.get('__name__') or '?'
        pre_context_lineno, pre_context, context_line, post_context = get_lines_from_file(filename, lineno, 7, loader, module_name)
        if pre_context_lineno is not None:
            results.append({
                'id': id(frame),
                'filename': filename,
                'module': module_name,
                'function': function,
                'lineno': lineno + 1,
                # TODO: vars need to be references
                'vars': transform(frame.f_locals.items()),
                'pre_context': pre_context,
                'context_line': context_line,
                'post_context': post_context,
                'pre_context_lineno': pre_context_lineno + 1,
            })
    return results
Exemplo n.º 2
0
    def capture(self, exc_info=None, **kwargs):
        if exc_info is None:
            exc_info = sys.exc_info()
        
        exc_type, exc_value, exc_traceback = exc_info
        
        tags = [('level', 'error')]
        
        culprit = self._get_culprit(exc_info[2])

        if hasattr(exc_type, '__class__'):
            exc_module = exc_type.__class__.__module__
            if exc_module == '__builtin__':
                exc_type = exc_type.__name__
            else:
                exc_type = '%s.%s' % (exc_module, exc_type.__name__)
        else:
            exc_module = None
            exc_type = exc_type.__name__

        # if isinstance(exc_value, TemplateSyntaxError) and hasattr(exc_value, 'source'):
        #     origin, (start, end) = exc_value.source
        #     result['template'] = (origin.reload(), start, end, origin.name)
        #     result['tags'].append(('template', origin.loadname))

        return {
            'culprit': culprit,
            'tags': tags,
            'sentry.interfaces.Exception': {
                'value': transform(exc_value),
                'type': exc_type,
                'frames': self._get_traceback_frames(exc_traceback)
            },
        }
Exemplo n.º 3
0
def get_stack_info(frames):
    results = []
    for frame in frames:
        # Support hidden frames
        if frame.f_locals.get('__traceback_hide__'):
            continue

        filename = frame.f_code.co_filename
        function = frame.f_code.co_name
        lineno = frame.f_lineno - 1
        loader = frame.f_globals.get('__loader__')
        module_name = frame.f_globals.get('__name__')
        pre_context_lineno, pre_context, context_line, post_context = get_lines_from_file(filename, lineno, 7, loader, module_name)
        if pre_context_lineno is not None:
            results.append({
                'id': id(frame),
                'filename': filename,
                'module': module_name,
                'function': function,
                'lineno': lineno + 1,
                # TODO: vars need to be references
                'vars': transform(frame.f_locals.items()),
                'pre_context': pre_context,
                'context_line': context_line,
                'post_context': post_context,
                'pre_context_lineno': pre_context_lineno + 1,
            })
    return results
Exemplo n.º 4
0
Arquivo: events.py Projeto: dmr/sentry
    def capture(self, exc_info=None, **kwargs):
        def contains(iterator, value):
            for k in iterator:
                if value.startswith(k):
                    return True
            return False

        if exc_info is None:
            exc_info = sys.exc_info()

        exc_type, exc_value, exc_traceback = exc_info

        tags = [("level", "error")]

        if app.config["INCLUDE_PATHS"]:
            modules = app.config["INCLUDE_PATHS"]
        else:
            modules = []

        # 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 tb in self._iter_tb(exc_info[2]):
            frame = tb.tb_frame
            try:
                view = ".".join([frame.f_globals["__name__"], frame.f_code.co_name])
            except:
                continue
            if contains(modules, view):
                if not (contains(app.config["EXCLUDE_PATHS"], view) and best_guess):
                    best_guess = view
            elif best_guess:
                break
        if best_guess:
            view = best_guess

        if view:
            tags.append(("culprit", view))

        if hasattr(exc_type, "__class__"):
            exc_module = exc_type.__class__.__module__
            if exc_module == "__builtin__":
                exc_type = exc_type.__name__
            else:
                exc_type = "%s.%s" % (exc_module, exc_type.__name__)
        else:
            exc_module = None
            exc_type = exc_type.__name__

        result = {"value": transform(exc_value), "type": exc_type, "frames": self._get_traceback_frames(exc_traceback)}

        # if isinstance(exc_value, TemplateSyntaxError) and hasattr(exc_value, 'source'):
        #     origin, (start, end) = exc_value.source
        #     result['template'] = (origin.reload(), start, end, origin.name)
        #     result['tags'].append(('template', origin.loadname))

        return {"data": result, "tags": tags}
Exemplo n.º 5
0
 def _postWithKey(self, data):
     resp = self.client.post(
         reverse('sentry-store'), {
             'data': base64.b64encode(pickle.dumps(transform(data))),
             'key': settings.KEY,
         })
     return resp
Exemplo n.º 6
0
    def test_dict_keys(self):
        x = {u'foo': 'bar'}

        result = transform(x)
        keys = result.keys()
        self.assertEquals(len(keys), 1)
        self.assertEquals(keys[0], 'foo')
        self.assertTrue(isinstance(keys[0], str))
Exemplo n.º 7
0
    def test_handles_gettext_lazy(self):
        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 test_transform_handles_gettext_lazy(self):
        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.º 9
0
 def _postWithSignature(self, data):
     ts = time.time()
     message = base64.b64encode(json.dumps(transform(data)))
     sig = get_signature(message, ts)
     
     resp = self.client.post(reverse('sentry-store'), message,
         content_type='application/octet-stream',
         HTTP_AUTHORIZATION=get_auth_header(sig, ts, '_postWithSignature'),
     )
     return resp
Exemplo n.º 10
0
 def _postWithSignature(self, data):
     ts = time.time()
     message = base64.b64encode(json.dumps(transform(data)))
     sig = get_signature(message, ts)
     
     resp = self.client.post(reverse('sentry-store'), message,
         content_type='application/octet-stream',
         HTTP_AUTHORIZATION=get_auth_header(sig, ts, '_postWithSignature'),
     )
     return resp
Exemplo n.º 11
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.º 12
0
    def create_from_exception(self, exc_info=None, **kwargs):
        """
        Creates an error log from an exception.
        """
        new_exc = bool(exc_info)
        if not exc_info or exc_info is True:
            exc_info = sys.exc_info()

        data = kwargs.pop('data', {}) or {}

        try:
            exc_type, exc_value, exc_traceback = exc_info

            frames = varmap(
                shorten, get_stack_info(iter_traceback_frames(exc_traceback)))

            if hasattr(exc_type, '__class__'):
                exc_module = exc_type.__class__.__module__
            else:
                exc_module = None

            data['__sentry__'] = {}
            data['__sentry__']['frames'] = frames
            data['__sentry__']['exception'] = [exc_module, exc_value.args]

            # As of r16833 (Django) all exceptions may contain a ``django_template_source`` attribute (rather than the
            # legacy ``TemplateSyntaxError.source`` check) which describes template information.
            if hasattr(exc_value, 'django_template_source') or ((isinstance(exc_value, TemplateSyntaxError) and \
                isinstance(getattr(exc_value, 'source', None), (tuple, list)) and isinstance(exc_value.source[0], LoaderOrigin))):
                origin, (start, end) = getattr(exc_value,
                                               'django_template_source',
                                               exc_value.source)
                data['__sentry__']['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)
        finally:
            if new_exc:
                try:
                    del exc_info
                except Exception, e:
                    logger.exception(e)
Exemplo n.º 13
0
    def create_from_exception(self, exc_info=None, **kwargs):
        """
        Creates an error log from an exception.
        """
        new_exc = bool(exc_info)
        if not exc_info or exc_info is True:
            exc_info = sys.exc_info()

        data = kwargs.pop('data', {}) or {}

        try:
            exc_type, exc_value, exc_traceback = exc_info

            frames = varmap(shorten, get_stack_info(iter_traceback_frames(exc_traceback)))

            if hasattr(exc_type, '__class__'):
                exc_module = exc_type.__class__.__module__
            else:
                exc_module = None

            data['__sentry__'] = {}
            data['__sentry__']['frames'] = frames
            data['__sentry__']['exception'] = [exc_module, exc_value.args]

            # As of r16833 (Django) all exceptions may contain a ``django_template_source`` attribute (rather than the
            # legacy ``TemplateSyntaxError.source`` check) which describes template information.
            if hasattr(exc_value, 'django_template_source') or ((isinstance(exc_value, TemplateSyntaxError) and \
                isinstance(getattr(exc_value, 'source', None), (tuple, list)) and isinstance(exc_value.source[0], LoaderOrigin))):
                origin, (start, end) = getattr(exc_value, 'django_template_source', exc_value.source)
                data['__sentry__']['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
            )
        finally:
            if new_exc:
                try:
                    del exc_info
                except Exception, e:
                    logger.exception(e)
Exemplo n.º 14
0
    def capture(self, exc_info=None, **kwargs):
        if exc_info is None:
            exc_info = sys.exc_info()
        
        exc_type, exc_value, exc_traceback = exc_info
        
        tags = [('level', 'error')]
        
        culprit = self._get_culprit(exc_info[2])

        if hasattr(exc_type, '__class__'):
            exc_module = exc_type.__class__.__module__
            if exc_module == '__builtin__':
                exc_type = exc_type.__name__
            else:
                exc_type = '%s.%s' % (exc_module, exc_type.__name__)
        else:
            exc_module = None
            exc_type = exc_type.__name__

        # if isinstance(exc_value, TemplateSyntaxError) and hasattr(exc_value, 'source'):
        #     origin, (start, end) = exc_value.source
        #     result['template'] = (origin.reload(), start, end, origin.name)
        #     result['tags'].append(('template', origin.loadname))

        return {
            'culprit': culprit,
            'tags': tags,
            'sentry.interfaces.Exception': {
                'value': transform(exc_value),
                'type': exc_type,
            },
            'sentry.interfaces.Stacktrace': {
                'frames': self._get_traceback_frames(exc_traceback)
            },
        }
Exemplo n.º 15
0
 def get_prep_value(self, value):
     if value is None: return
     return base64.b64encode(pickle.dumps(transform(value)).encode('zlib'))
Exemplo n.º 16
0
    def process(self, **kwargs):
        "Processes the message before passing it on to the server"
        from sentry.utils 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,
                ))

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

        kwargs.setdefault('level', logging.ERROR)
        kwargs.setdefault('server_name', settings.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']

        (is_thrashing, message_id) = self.check_throttle(checksum)

        if is_thrashing:
            if request and message_id:
                # 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['data'] = transform(kwargs['data'])

        if 'timestamp' not in kwargs:
            kwargs['timestamp'] = datetime.datetime.now()

        self.send(**kwargs)

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

        # store the last message_id incase we hit thrashing limits
        self.set_last_message_id(checksum, message_id)

        return message_id
Exemplo n.º 17
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 settings.INCLUDE_PATHS:
                modules = set(list(modules) + settings.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(settings.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.º 18
0
    def handle(self, exc_info=None):
        # TODO: remove Django specifics
        from django.template import TemplateSyntaxError
        from django.views.debug import ExceptionReporter

        if exc_info is None:
            exc_info = sys.exc_info()

        exc_type, exc_value, exc_traceback = exc_info

        result = {
            'tags': [('level', 'error')],
        }

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

        # This should be cached
        # modules = get_installed_apps()
        modules = []
        if app.config['INCLUDE_PATHS']:
            modules = set(list(modules) + app.config['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(app.config['EXCLUDE_PATHS'], view) and best_guess):
                    best_guess = view
            elif best_guess:
                break
        if best_guess:
            view = best_guess

        if view:
            result['tags'].append(('view', view))

        if hasattr(exc_type, '__class__'):
            exc_module = exc_type.__class__.__module__
            if exc_module == '__builtin__':
                exc_type = exc_type.__name__
            else:
                exc_type = '%s.%s' % (exc_module, exc_type.__name__)
        else:
            exc_module = None
            exc_type = exc_type.__name__

        if isinstance(exc_value, TemplateSyntaxError) and hasattr(exc_value, 'source'):
            origin, (start, end) = exc_value.source
            result['exc_template'] = (origin.reload(), start, end, origin.name)
            result['tags'].append(('template', origin.loadname))

        result['exc_value'] = transform(exc_value)
        result['exc_type'] = exc_type
        result['exc_frames'] = self.get_traceback_frames(exc_traceback)

        return result
Exemplo n.º 19
0
    def process(self, tags=[], date=None, time_spent=None, request=None, **data):
        "Processes the message before passing it on to the server"
        if request:
            data.update(dict(
                s_meta=request.META,
                s_post=request.POST,
                s_get=request.GET,
                s_cookies=request.COOKIES,
            ))
            tags.append(('url', request.build_absolute_uri()))

        tags.append(('server', app.config['NAME']))

        versions = get_versions()

        data['s_versions'] = versions

        if data.get('s_view'):
            # get list of modules from right to left
            parts = data['s_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]

            # data['s_view'] = view

            # store our "best guess" for application version
            if version:
                data.update({
                    's_version': version,
                    's_module': module,
                })

        # TODO: Cache should be handled by the db backend by default (as we expect a fast access backend)
        # if app.config['THRASHING_TIMEOUT'] and app.config['THRASHING_LIMIT']:
        #     cache_key = 'sentry:%s:%s' % (kwargs.get('class_name') or '', checksum)
        #     added = cache.add(cache_key, 1, app.config['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 > app.config['THRASHING_LIMIT']:
        #             return

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

        # create ID client-side so that it can be passed to application
        event_id = uuid.uuid4().hex

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

        app.client.send(type=self.get_id(), tags=tags, data=data, date=date, time_spent=time_spent, event_id=event_id)

        return event_id
Exemplo n.º 20
0
    def capture(self,
                event_type,
                tags=None,
                data=None,
                date=None,
                time_spent=None,
                event_id=None,
                extra=None,
                culprit=None,
                **kwargs):
        """
        Captures and processes an event and pipes it off to SentryClient.send.
        
        To use structured data (interfaces) with capture:
        
        >>> capture('Message', message='foo', data={
        >>>     'sentry.interfaces.Http': {
        >>>         'url': '...',
        >>>         'data': {},
        >>>         'querystring': '...',
        >>>         'method': 'POST',
        >>>     },
        >>> })
        
        The finalized ``data`` structure contains the following (some optional) builtin values:
        
        >>> {
        >>>     'culprit': 'full.module.name', # or /arbitrary/path
        >>>     # the culprit version information
        >>>     'version': ('full.module.name', 'version string'),
        >>>     # all detectable installed modules
        >>>     'modules': {
        >>>         'full.module.name': 'version string',
        >>>     },
        >>>     # arbitrary data provided by user
        >>>     'extra': {
        >>>         'key': 'value',
        >>>     }
        >>> }
        
        :param event_type: the module path to the Event class. Builtins can use shorthand class
                           notation and exclude the full module path.
        :param tags: a list of tuples (key, value) specifying additional tags for event
        :param data: the data base, useful for specifying structured data interfaces. Any key which contains a '.'
                     will be assumed to be a data interface.
        :param date: the datetime of this event
        :param time_spent: a float value representing the duration of the event
        :param event_id: a 32-length unique string identifying this event
        :param extra: a dictionary of additional standard metadata
        :param culprit: a string representing the cause of this event (generally a path to a function)
        :return: a 32-length string identifying this event
        """
        if data is None:
            data = {}
        if tags is None:
            tags = []
        if extra is None:
            extra = {}
        if date is None:
            date = datetime.datetime.now()

        if '.' not in event_type:
            # Assume it's a builtin
            event_type = 'sentry.events.%s' % event_type

        handler = self.module_cache[event_type]()

        result = handler.capture(**kwargs)

        tags = list(tags) + result.pop('tags', [])

        if not culprit:
            culprit = result.pop('culprit')

        for k, v in result.iteritems():
            if k not in data:
                data[k] = v
            else:
                data[k].update(v)

        for k, v in data.iteritems():
            if '.' not in k:
                continue

            interface = self.module_cache[k]
            data[k] = interface(**v).serialize()

        tags.append(('server', app.config['NAME']))

        versions = get_versions()

        data['modules'] = versions

        if culprit:
            data['culprit'] = culprit

            # get list of modules from right to left
            parts = culprit.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:
                data['version'] = (module, version),

        # TODO: Cache should be handled by the db backend by default (as we expect a fast access backend)
        # if app.config['THRASHING_TIMEOUT'] and app.config['THRASHING_LIMIT']:
        #     cache_key = 'sentry:%s:%s' % (kwargs.get('class_name') or '', checksum)
        #     added = cache.add(cache_key, 1, app.config['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 > app.config['THRASHING_LIMIT']:
        #             return

        # for filter_ in filters.all():
        #     kwargs = filter_(None).process(kwargs) or kwargs

        # create ID client-side so that it can be passed to application
        event_id = uuid.uuid4().hex

        # Run the data through processors

        for processor in processors.all():
            data.update(self.module_cache[processor].process(data))

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

        self.send(event_type=event_type,
                  tags=tags,
                  data=data,
                  date=date,
                  time_spent=time_spent,
                  event_id=event_id)

        return event_id
Exemplo n.º 21
0
 def _postWithKey(self, data):
     resp = self.client.post(reverse('sentry-store'), {
         'data': base64.b64encode(pickle.dumps(transform(data))),
         'key': settings.KEY,
     })
     return resp        
Exemplo n.º 22
0
    def process(self, **kwargs):
        "Processes the message before passing it on to the server"
        from sentry.utils 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()
        else:
            kwargs["data"] = {}

        if "__sentry__" not in kwargs["data"]:
            kwargs["data"]["__sentry__"] = {}

        request = kwargs.pop("request", None)
        if isinstance(request, HttpRequest):
            if not request.POST and request.body:
                post_data = request.body
            else:
                post_data = request.POST

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

            if hasattr(request, "user"):
                if request.user.is_authenticated():
                    user_info = {
                        "is_authenticated": True,
                        "id": request.user.pk,
                        "username": request.user.username,
                        "email": request.user.email,
                    }
                else:
                    user_info = {"is_authenticated": False}

                kwargs["data"]["__sentry__"]["user"] = user_info

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

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

        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 we've passed frames, lets try to fetch the culprit
        if not kwargs.get("view") and kwargs["data"]["__sentry__"].get("frames"):
            # This should be cached
            modules = get_installed_apps()
            if settings.INCLUDE_PATHS:
                modules = set(list(modules) + settings.INCLUDE_PATHS)

            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 kwargs["data"]["__sentry__"]["frames"]:
                try:
                    view = ".".join([frame["module"], frame["function"]])
                except:
                    continue
                if contains(modules, view):
                    if not (contains(settings.EXCLUDE_PATHS, view) and best_guess):
                        best_guess = view
                elif best_guess:
                    break
            if best_guess:
                view = best_guess

            if view:
                kwargs["view"] = view

        # try to fetch the current version
        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"]

        (is_thrashing, message_id) = self.check_throttle(checksum)

        if is_thrashing:
            if request and message_id:
                # 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["data"] = transform(kwargs["data"])

        if "timestamp" not in kwargs:
            kwargs["timestamp"] = now_with_tz_if_supported()

        self.send(**kwargs)

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

        # store the last message_id incase we hit thrashing limits
        self.set_last_message_id(checksum, message_id)

        return message_id
Exemplo n.º 23
0
    def test_transform_model_instance(self):
        instance = DuplicateKeyModel(foo='foo')

        result = transform(instance)
        self.assertEquals(result, '<DuplicateKeyModel: foo>')
Exemplo n.º 24
0
Arquivo: base.py Projeto: dmr/sentry
    def capture(self, event_type, tags=[], data={}, date=None, time_spent=None, event_id=None, **kwargs):
        "Captures and processes an event and pipes it off to SentryClient.send."
        if not date:
            date = datetime.datetime.now()

        if '.' not in event_type:
            # Assume it's a builtin
            event_type = 'sentry.events.%s' % event_type

        module, class_name = event_type.rsplit('.', 1)

        handler = getattr(__import__(module, {}, {}, [class_name], -1), class_name)()

        result = handler.capture(**kwargs)

        tags = list(tags) + result['tags']

        data['__event__'] = result['data']
        
        # if request:
        #     data.update(dict(
        #         s_meta=request.META,
        #         s_post=request.POST,
        #         s_get=request.GET,
        #         s_cookies=request.COOKIES,
        #     ))
        #     tags.append(('url', request.build_absolute_uri()))

        tags.append(('server', app.config['NAME']))

        versions = get_versions()

        if '__sentry__' not in data:
            data['__sentry__'] = {}

        data['__sentry__']['versions'] = versions

        # TODO: view should probably be passable via kwargs
        if data['__sentry__'].get('culprit'):
            # get list of modules from right to left
            parts = data['__sentry__']['culprit'].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:
                data['__sentry__'].update({
                    'version': version,
                    'module': module,
                })

        # TODO: Cache should be handled by the db backend by default (as we expect a fast access backend)
        # if app.config['THRASHING_TIMEOUT'] and app.config['THRASHING_LIMIT']:
        #     cache_key = 'sentry:%s:%s' % (kwargs.get('class_name') or '', checksum)
        #     added = cache.add(cache_key, 1, app.config['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 > app.config['THRASHING_LIMIT']:
        #             return

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

        # create ID client-side so that it can be passed to application
        event_id = uuid.uuid4().hex

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

        self.send(event_type=event_type, tags=tags, data=data, date=date, time_spent=time_spent, event_id=event_id)

        return event_id
Exemplo n.º 25
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 settings.INCLUDE_PATHS:
                modules = set(list(modules) + settings.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(settings.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.º 26
0
    def capture(self, event_type, tags=None, data=None, date=None, time_spent=None, event_id=None,
                extra=None, culprit=None, **kwargs):
        """
        Captures and processes an event and pipes it off to SentryClient.send.
        
        To use structured data (interfaces) with capture:
        
        >>> capture('Message', message='foo', data={
        >>>     'sentry.interfaces.Http': {
        >>>         'url': '...',
        >>>         'data': {},
        >>>         'querystring': '...',
        >>>         'method': 'POST',
        >>>     },
        >>> })
        
        The finalized ``data`` structure contains the following (some optional) builtin values:
        
        >>> {
        >>>     'culprit': 'full.module.name', # or /arbitrary/path
        >>>     # the culprit version information
        >>>     'version': ('full.module.name', 'version string'),
        >>>     # all detectable installed modules
        >>>     'modules': {
        >>>         'full.module.name': 'version string',
        >>>     },
        >>>     # arbitrary data provided by user
        >>>     'extra': {
        >>>         'key': 'value',
        >>>     }
        >>> }
        
        :param event_type: the module path to the Event class. Builtins can use shorthand class
                           notation and exclude the full module path.
        :param tags: a list of tuples (key, value) specifying additional tags for event
        :param data: the data base, useful for specifying structured data interfaces. Any key which contains a '.'
                     will be assumed to be a data interface.
        :param date: the datetime of this event
        :param time_spent: a float value representing the duration of the event
        :param event_id: a 32-length unique string identifying this event
        :param extra: a dictionary of additional standard metadata
        :param culprit: a string representing the cause of this event (generally a path to a function)
        :return: a 32-length string identifying this event
        """
        if data is None:
            data = {}
        if tags is None:
            tags = []
        if extra is None:
            extra = {}
        if date is None:
            date = datetime.datetime.now()

        if '.' not in event_type:
            # Assume it's a builtin
            event_type = 'sentry.events.%s' % event_type

        handler = self.module_cache[event_type]()

        result = handler.capture(**kwargs)

        tags = list(tags) + result.pop('tags', [])

        if not culprit:
            culprit = result.pop('culprit')

        for k, v in result.iteritems():
            if k not in data:
                data[k] = v
            else:
                data[k].update(v)

        for k, v in data.iteritems():
            if '.' not in k:
                continue

            interface = self.module_cache[k]
            data[k] = interface(**v).serialize()
        
        tags.append(('server', app.config['NAME']))

        versions = get_versions()

        data['modules'] = versions

        if culprit:
            data['culprit'] = culprit

            # get list of modules from right to left
            parts = culprit.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:
                data['version'] = (module, version),

        # TODO: Cache should be handled by the db backend by default (as we expect a fast access backend)
        # if app.config['THRASHING_TIMEOUT'] and app.config['THRASHING_LIMIT']:
        #     cache_key = 'sentry:%s:%s' % (kwargs.get('class_name') or '', checksum)
        #     added = cache.add(cache_key, 1, app.config['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 > app.config['THRASHING_LIMIT']:
        #             return

        # for filter_ in filters.all():
        #     kwargs = filter_(None).process(kwargs) or kwargs

        # create ID client-side so that it can be passed to application
        event_id = uuid.uuid4().hex

        # Run the data through processors

        for processor in processors.all():
            data.update(self.module_cache[processor].process(data))

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

        self.send(event_type=event_type, tags=tags, data=data, date=date, time_spent=time_spent, event_id=event_id)

        return event_id
Exemplo n.º 27
0
    def capture(self, event_type, tags=[], data={}, date=None, time_spent=None, event_id=None,
                extra={}, culprit=None, http={}, **kwargs):
        "Captures and processes an event and pipes it off to SentryClient.send."
        # TODO: http should be some kind of pluggable interface so others can be added
        if not date:
            date = datetime.datetime.now()

        if '.' not in event_type:
            # Assume it's a builtin
            event_type = 'sentry.events.%s' % event_type

        handler = self.module_cache[event_type]()

        result = handler.capture(**kwargs)

        tags = list(tags) + result['tags']

        data['extra'] = extra
        data['event'] = result['data']
        
        if not culprit:
            culprit = result.get('culprit')
        
        for k, v in kwargs.iteritems():
            if k.startswith('interface:'):
                interface_name = k.split('interface:', 1)[1]
                if '.' not in interface_name:
                    # Assume it's a builtin
                    interface_name = 'sentry.interfaces.%s' % interface_name

                interface = self.module_cache[interface_name]
                data[k] = interface(**v).serialize()
        
        tags.append(('server', app.config['NAME']))

        versions = get_versions()

        data['modules'] = versions

        if culprit:
            data['culprit'] = culprit

            # get list of modules from right to left
            parts = culprit.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:
                data['version'] = (module, version),

        # TODO: Cache should be handled by the db backend by default (as we expect a fast access backend)
        # if app.config['THRASHING_TIMEOUT'] and app.config['THRASHING_LIMIT']:
        #     cache_key = 'sentry:%s:%s' % (kwargs.get('class_name') or '', checksum)
        #     added = cache.add(cache_key, 1, app.config['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 > app.config['THRASHING_LIMIT']:
        #             return

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

        # create ID client-side so that it can be passed to application
        event_id = uuid.uuid4().hex

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

        self.send(event_type=event_type, tags=tags, data=data, date=date, time_spent=time_spent, event_id=event_id)

        return event_id
Exemplo n.º 28
0
    def process(self, **kwargs):
        "Processes the message before passing it on to the server"
        from sentry.utils 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()
        else:
            kwargs['data'] = {}

        if '__sentry__' not in kwargs['data']:
            kwargs['data']['__sentry__'] = {}

        request = kwargs.pop('request', None)
        if isinstance(request, HttpRequest):
            try:
                post_data = not request.POST and request.raw_post_data or request.POST
            except:
                post_data = request.POST

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

            if hasattr(request, 'user'):
                if request.user.is_authenticated():
                    user_info = {
                        'is_authenticated': True,
                        'id': request.user.pk,
                        'username': request.user.username,
                        'email': request.user.email,
                    }
                else:
                    user_info = {
                        'is_authenticated': False,
                    }

                kwargs['data']['__sentry__']['user'] = user_info

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

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

        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 we've passed frames, lets try to fetch the culprit
        if not kwargs.get('view') and kwargs['data']['__sentry__'].get('frames'):
            # This should be cached
            modules = get_installed_apps()
            if settings.INCLUDE_PATHS:
                modules = set(list(modules) + settings.INCLUDE_PATHS)

            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 kwargs['data']['__sentry__']['frames']:
                try:
                    view = '.'.join([frame['module'], frame['function']])
                except:
                    continue
                if contains(modules, view):
                    if not (contains(settings.EXCLUDE_PATHS, view) and best_guess):
                        best_guess = view
                elif best_guess:
                    break
            if best_guess:
                view = best_guess

            if view:
                kwargs['view'] = view

        # try to fetch the current version
        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']

        (is_thrashing, message_id) = self.check_throttle(checksum)

        if is_thrashing:
            if request and message_id:
                # attach the sentry object to the request
                request.sentry = {
                    'id': '%s$%s' % (message_id, checksum),
                    '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['data'] = transform(kwargs['data'])

        if 'timestamp' not in kwargs:
            kwargs['timestamp'] = datetime.datetime.now()

        self.send(**kwargs)

        if request:
            # attach the sentry object to the request
            request.sentry = {
                'id': '%s$%s' % (message_id, checksum),
                'thrashed': False,
            }

        # store the last message_id incase we hit thrashing limits
        self.set_last_message_id(checksum, message_id)

        return message_id
Exemplo n.º 29
0
    def process(self, **kwargs):
        "Processes the message before passing it on to the server"
        from sentry.utils 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()
        else:
            kwargs['data'] = {}

        if '__sentry__' not in kwargs['data']:
            kwargs['data']['__sentry__'] = {}

        request = kwargs.pop('request', None)
        if isinstance(request, HttpRequest):
            try:
                post_data = not request.POST and request.raw_post_data or request.POST
            except:
                post_data = request.POST

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

            if hasattr(request, 'user'):
                if request.user.is_authenticated():
                    user_info = {
                        'is_authenticated': True,
                        'id': request.user.pk,
                        'username': request.user.username,
                        'email': request.user.email,
                    }
                else:
                    user_info = {
                        'is_authenticated': False,
                    }

                kwargs['data']['__sentry__']['user'] = user_info

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

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

        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 we've passed frames, lets try to fetch the culprit
        if not kwargs.get('view') and kwargs['data']['__sentry__'].get(
                'frames'):
            # This should be cached
            modules = get_installed_apps()
            if settings.INCLUDE_PATHS:
                modules = set(list(modules) + settings.INCLUDE_PATHS)

            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 kwargs['data']['__sentry__']['frames']:
                try:
                    view = '.'.join([frame['module'], frame['function']])
                except:
                    continue
                if contains(modules, view):
                    if not (contains(settings.EXCLUDE_PATHS, view)
                            and best_guess):
                        best_guess = view
                elif best_guess:
                    break
            if best_guess:
                view = best_guess

            if view:
                kwargs['view'] = view

        # try to fetch the current version
        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']

        (is_thrashing, message_id) = self.check_throttle(checksum)

        if is_thrashing:
            if request and message_id:
                # attach the sentry object to the request
                request.sentry = {
                    'id': '%s$%s' % (message_id, checksum),
                    '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['data'] = transform(kwargs['data'])

        if 'timestamp' not in kwargs:
            kwargs['timestamp'] = datetime.datetime.now()

        self.send(**kwargs)

        if request:
            # attach the sentry object to the request
            request.sentry = {
                'id': '%s$%s' % (message_id, checksum),
                'thrashed': False,
            }

        # store the last message_id incase we hit thrashing limits
        self.set_last_message_id(checksum, message_id)

        return message_id
Exemplo n.º 30
0
 def get_prep_value(self, value):
     if value is None:
         return
     return base64.b64encode(pickle.dumps(transform(value)).encode("zlib"))
Exemplo n.º 31
0
    def test_bad_string(self):
        x = 'The following character causes problems: \xd4'

        result = transform(x)
        self.assertEquals(result, '(Error decoding value)')
Exemplo n.º 32
0
    def process(self, **kwargs):
        "Processes the message before passing it on to the server"
        from sentry.utils 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,
            ))

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

        kwargs.setdefault('level', logging.ERROR)
        kwargs.setdefault('server_name', settings.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']

        (is_thrashing, message_id) = self.check_throttle(checksum)

        if is_thrashing:
            if request and message_id:
                # 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['data'] = transform(kwargs['data'])

        if 'timestamp' not in kwargs:
            kwargs['timestamp'] = datetime.datetime.now()

        self.send(**kwargs)
        
        if request:
            # attach the sentry object to the request
            request.sentry = {
                'id': message_id,
                'trashed': False,
            }
        
        # store the last message_id incase we hit thrashing limits
        self.set_last_message_id(checksum, message_id)
        
        return message_id
Exemplo n.º 33
0
 def test_model_instance(self):
     instance = DuplicateKeyModel(foo='foo')
     
     result = transform(instance)
     self.assertEquals(result, '<DuplicateKeyModel: foo>')