Beispiel #1
0
 def merge(self, data):
     d = self.data
     for key, value in six.iteritems(data):
         if key in ('tags', 'extra'):
             d.setdefault(key, {})
             for t_key, t_value in six.iteritems(value):
                 d[key][t_key] = t_value
         else:
             d[key] = value
Beispiel #2
0
 def serialize(self, value, **kwargs):
     list_max_length = kwargs.get('list_max_length') or float('inf')
     return dict(
         (self.make_key(self.recurse(k, **kwargs)), self.recurse(v, **kwargs))
         for n, (k, v)
         in itertools.takewhile(lambda x: x[0] < list_max_length, enumerate(six.iteritems(value)))
     )
Beispiel #3
0
def merge_dicts(*dicts):
    out = {}
    for d in dicts:
        if not d:
            continue

        for k, v in six.iteritems(d):
            out[k] = v
    return out
Beispiel #4
0
def get_headers(environ):
    """
    Returns only proper HTTP headers.
    """
    for key, value in six.iteritems(environ):
        key = str(key)
        if key.startswith('HTTP_') and key not in \
           ('HTTP_CONTENT_TYPE', 'HTTP_CONTENT_LENGTH'):
            yield key[5:].replace('_', '-').title(), value
        elif key in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
            yield key.replace('_', '-').title(), value
Beispiel #5
0
def varmap(func, var, context=None, name=None):
    """
    Executes ``func(key_name, value)`` on all values
    recurisively discovering dict and list scoped
    values.
    """
    if context is None:
        context = {}
    objid = id(var)
    if objid in context:
        return func(name, '<...>')
    context[objid] = 1
    if isinstance(var, dict):
        ret = dict((k, varmap(func, v, context, k)) for k, v in six.iteritems(var))
    elif isinstance(var, (list, tuple)):
        ret = [varmap(func, f, context, name) for f in var]
    else:
        ret = func(name, var)
    del context[objid]
    return ret
Beispiel #6
0
def get_frame_locals(frame, transformer=transform, max_var_size=4096):
    f_locals = getattr(frame, 'f_locals', None)
    if not f_locals:
        return None

    if not isinstance(f_locals, dict):
        # XXX: Genshi (and maybe others) have broken implementations of
        # f_locals that are not actually dictionaries
        try:
            f_locals = to_dict(f_locals)
        except Exception:
            return None

    f_vars = {}
    f_size = 0
    for k, v in six.iteritems(f_locals):
        v = transformer(v)
        v_size = len(repr(v))
        if v_size + f_size < 4096:
            f_vars[k] = v
            f_size += v_size
    return f_vars
Beispiel #7
0
    def build_msg(self, event_type, data=None, date=None,
                  time_spent=None, extra=None, stack=None, public_key=None,
                  tags=None, **kwargs):
        """
        Captures, processes and serializes an event into a dict object

        The result of ``build_msg`` should be a standardized dict, with
        all default values available.
        """

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

        data = merge_dicts(self.context.data, data)

        data.setdefault('tags', {})
        data.setdefault('extra', {})

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

        handler = self.get_handler(event_type)
        result = handler.capture(**kwargs)

        # data (explicit) culprit takes over auto event detection
        culprit = result.pop('culprit', None)
        if data.get('culprit'):
            culprit = data['culprit']

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

        # auto_log_stacks only applies to events that are not exceptions
        # due to confusion about which stack is which and the automatic
        # application of stacktrace to exception objects by Sentry
        if stack is None and 'exception' not in data:
            stack = self.auto_log_stacks

        if stack and 'stacktrace' not in data:
            if stack is True:
                frames = iter_stack_frames()

            else:
                frames = stack

            stack_info = get_stack_info(
                frames,
                transformer=self.transform,
                capture_locals=self.capture_locals,
            )
            data.update({
                'stacktrace': stack_info,
            })

        if 'stacktrace' in data and self.include_paths:
            for frame in data['stacktrace']['frames']:
                if frame.get('in_app') is not None:
                    continue

                path = frame.get('module')
                if not path:
                    continue

                if path.startswith('raven.'):
                    frame['in_app'] = False
                else:
                    frame['in_app'] = (
                        any(path.startswith(x) for x in self.include_paths) and
                        not any(path.startswith(x) for x in self.exclude_paths)
                    )

        if not culprit:
            if 'stacktrace' in data:
                culprit = get_culprit(data['stacktrace']['frames'])
            elif 'exception' in data:
                stacktrace = data['exception']['values'][0].get('stacktrace')
                if stacktrace:
                    culprit = get_culprit(stacktrace['frames'])

        if not data.get('level'):
            data['level'] = kwargs.get('level') or logging.ERROR

        if not data.get('server_name'):
            data['server_name'] = self.name

        if not data.get('modules'):
            data['modules'] = self.get_module_versions()

        if self.release is not None:
            data['release'] = self.release

        data['tags'] = merge_dicts(self.tags, data['tags'], tags)
        data['extra'] = merge_dicts(self.extra, data['extra'], extra)

        # Legacy support for site attribute
        site = data.pop('site', None) or self.site
        if site:
            data['tags'].setdefault('site', site)

        if culprit:
            data['culprit'] = culprit

        # Run the data through processors
        for processor in self.get_processors():
            data.update(processor.process(data))

        if 'message' not in data:
            data['message'] = kwargs.get('message', handler.to_string(data))

        # tags should only be key=>u'value'
        for key, value in six.iteritems(data['tags']):
            data['tags'][key] = to_unicode(value)

        # extra data can be any arbitrary value
        for k, v in six.iteritems(data['extra']):
            data['extra'][k] = self.transform(v)

        # It's important date is added **after** we serialize
        data.setdefault('project', self.remote.project)
        data.setdefault('timestamp', date or datetime.utcnow())
        data.setdefault('time_spent', time_spent)
        data.setdefault('event_id', event_id)
        data.setdefault('platform', PLATFORM_NAME)

        return data
Beispiel #8
0
    def build_msg(self,
                  event_type,
                  data=None,
                  date=None,
                  time_spent=None,
                  extra=None,
                  stack=None,
                  public_key=None,
                  tags=None,
                  **kwargs):
        """
        Captures, processes and serializes an event into a dict object

        The result of ``build_msg`` should be a standardized dict, with
        all default values available.
        """

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

        data = merge_dicts(self.context.data, data)

        data.setdefault('tags', {})
        data.setdefault('extra', {})

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

        handler = self.get_handler(event_type)
        result = handler.capture(**kwargs)

        # data (explicit) culprit takes over auto event detection
        culprit = result.pop('culprit', None)
        if data.get('culprit'):
            culprit = data['culprit']

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

        # auto_log_stacks only applies to events that are not exceptions
        # due to confusion about which stack is which and the automatic
        # application of stacktrace to exception objects by Sentry
        if stack is None and 'exception' not in data:
            stack = self.auto_log_stacks

        if stack and 'stacktrace' not in data:
            if stack is True:
                frames = iter_stack_frames()

            else:
                frames = stack

            stack_info = get_stack_info(
                frames,
                transformer=self.transform,
                capture_locals=self.capture_locals,
            )
            data.update({
                'stacktrace': stack_info,
            })

        if 'stacktrace' in data and self.include_paths:
            for frame in data['stacktrace']['frames']:
                if frame.get('in_app') is not None:
                    continue

                path = frame.get('module')
                if not path:
                    continue

                if path.startswith('raven.'):
                    frame['in_app'] = False
                else:
                    frame['in_app'] = (any(
                        path.startswith(x)
                        for x in self.include_paths) and not any(
                            path.startswith(x) for x in self.exclude_paths))

        if not culprit:
            if 'stacktrace' in data:
                culprit = get_culprit(data['stacktrace']['frames'])
            elif 'exception' in data:
                stacktrace = data['exception']['values'][0].get('stacktrace')
                if stacktrace:
                    culprit = get_culprit(stacktrace['frames'])

        if not data.get('level'):
            data['level'] = kwargs.get('level') or logging.ERROR

        if not data.get('server_name'):
            data['server_name'] = self.name

        if not data.get('modules'):
            data['modules'] = self.get_module_versions()

        if self.release is not None:
            data['release'] = self.release

        data['tags'] = merge_dicts(self.tags, data['tags'], tags)
        data['extra'] = merge_dicts(self.extra, data['extra'], extra)

        # Legacy support for site attribute
        site = data.pop('site', None) or self.site
        if site:
            data['tags'].setdefault('site', site)

        if culprit:
            data['culprit'] = culprit

        # Run the data through processors
        for processor in self.get_processors():
            data.update(processor.process(data))

        if 'message' not in data:
            data['message'] = kwargs.get('message', handler.to_string(data))

        # tags should only be key=>u'value'
        for key, value in six.iteritems(data['tags']):
            data['tags'][key] = to_unicode(value)

        # extra data can be any arbitrary value
        for k, v in six.iteritems(data['extra']):
            data['extra'][k] = self.transform(v)

        # It's important date is added **after** we serialize
        data.setdefault('project', self.project)
        data.setdefault('timestamp', date or datetime.utcnow())
        data.setdefault('time_spent', time_spent)
        data.setdefault('event_id', event_id)
        data.setdefault('platform', PLATFORM_NAME)

        return data
Beispiel #9
0
    def build_msg(self, event_type, data=None, date=None,
                  time_spent=None, extra=None, stack=None, public_key=None,
                  tags=None, **kwargs):
        """
        Captures, processes and serializes an event into a dict object

        The result of ``build_msg`` should be a standardized dict, with
        all default values available.
        """

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

        if data is None:
            data = {}
        if extra is None:
            extra = {}
        if not date:
            date = datetime.datetime.utcnow()
        if stack is None:
            stack = self.auto_log_stacks

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

        handler = self.get_handler(event_type)
        result = handler.capture(**kwargs)

        # data (explicit) culprit takes over auto event detection
        culprit = result.pop('culprit', None)
        if data.get('culprit'):
            culprit = data['culprit']

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

        if stack and 'sentry.interfaces.Stacktrace' not in data:
            if stack is True:
                frames = iter_stack_frames()

            else:
                frames = stack

            data.update({
                'sentry.interfaces.Stacktrace': {
                    'frames': get_stack_info(frames,
                        transformer=self.transform)
                },
            })

        if 'sentry.interfaces.Stacktrace' in data:
            if self.include_paths:
                for frame in data['sentry.interfaces.Stacktrace']['frames']:
                    if frame.get('in_app') is not None:
                        continue

                    path = frame.get('module')
                    if not path:
                        continue

                    if path.startswith('raven.'):
                        frame['in_app'] = False
                    else:
                        frame['in_app'] = (
                            any(path.startswith(x) for x in self.include_paths)
                            and not
                            any(path.startswith(x) for x in self.exclude_paths)
                        )

            if not culprit:
                culprit = get_culprit(data['sentry.interfaces.Stacktrace']['frames'])

        if not data.get('level'):
            data['level'] = kwargs.get('level') or logging.ERROR

        if not data.get('server_name'):
            data['server_name'] = self.name

        if not data.get('modules'):
            data['modules'] = self.get_module_versions()

        data['tags'] = tags or {}
        data.setdefault('extra', {})
        data.setdefault('level', logging.ERROR)

        # Add default extra context
        if self.extra:
            for k, v in six.iteritems(self.extra):
                data['extra'].setdefault(k, v)

        # Add default tag context
        if self.tags:
            for k, v in six.iteritems(self.tags):
                data['tags'].setdefault(k, v)

        for k, v in six.iteritems(extra):
            data['extra'][k] = v

        if culprit:
            data['culprit'] = culprit

        # Run the data through processors
        for processor in self.get_processors():
            data.update(processor.process(data))

        if 'message' not in data:
            data['message'] = handler.to_string(data)

        data.setdefault('project', self.project)

        # Legacy support for site attribute
        site = data.pop('site', None) or self.site
        if site:
            data['tags'].setdefault('site', site)

        for key, value in six.iteritems(data['tags']):
            data['tags'][key] = to_unicode(value)

        # Make sure custom data is coerced
        for k, v in six.iteritems(data['extra']):
            data['extra'][k] = self.transform(v)

        # It's important date is added **after** we serialize
        data.update({
            'timestamp': date,
            'time_spent': time_spent,
            'event_id': event_id,
            'platform': PLATFORM_NAME,
        })

        return data
Beispiel #10
0
 def __exit__(self, exc_type, exc_value, traceback):
     for k, v in six.iteritems(self._orig):
         if v is self.NotDefined:
             delattr(settings, k)
         else:
             setattr(settings, k, v)
Beispiel #11
0
 def __enter__(self):
     for k, v in six.iteritems(self.overrides):
         self._orig[k] = getattr(settings, k, self.NotDefined)
         setattr(settings, k, v)
Beispiel #12
0
 def make_record(self, msg, args=(), level=logging.INFO, extra=None, exc_info=None):
     record = logging.LogRecord('root', level, __file__, 27, msg, args, exc_info, 'make_record')
     if extra:
         for key, value in six.iteritems(extra):
             record.__dict__[key] = value
     return record
Beispiel #13
0
 def __exit__(self, exc_type, exc_value, traceback):
     for k, v in six.iteritems(self._orig):
         if v is self.NotDefined:
             delattr(settings, k)
         else:
             setattr(settings, k, v)
Beispiel #14
0
    def _emit(self, record, **kwargs):
        data = {}

        extra = getattr(record, "data", None)
        if not isinstance(extra, dict):
            if extra:
                extra = {"data": extra}
            else:
                extra = {}

        for k, v in six.iteritems(vars(record)):
            if k in RESERVED:
                continue
            if k.startswith("_"):
                continue
            if "." not in k and k not in ("culprit", "server_name"):
                extra[k] = v
            else:
                data[k] = v

        stack = getattr(record, "stack", None)
        if stack is True:
            stack = iter_stack_frames()

        if stack:
            stack = self._get_targetted_stack(stack, record)

        date = datetime.datetime.utcfromtimestamp(record.created)
        event_type = "raven.events.Message"
        handler_kwargs = {"params": record.args}
        try:
            handler_kwargs["message"] = six.text_type(record.msg)
        except UnicodeDecodeError:
            # Handle binary strings where it should be unicode...
            handler_kwargs["message"] = repr(record.msg)[1:-1]

        try:
            handler_kwargs["formatted"] = six.text_type(record.message)
        except UnicodeDecodeError:
            # Handle binary strings where it should be unicode...
            handler_kwargs["formatted"] = repr(record.message)[1:-1]

        # If there's no exception being processed, exc_info may be a 3-tuple of None
        # http://docs.python.org/library/sys.html#sys.exc_info
        if record.exc_info and all(record.exc_info):
            # capture the standard message first so that we ensure
            # the event is recorded as an exception, in addition to having our
            # message interface attached
            handler = self.client.get_handler(event_type)
            data.update(handler.capture(**handler_kwargs))

            event_type = "raven.events.Exception"
            handler_kwargs = {"exc_info": record.exc_info}

        # HACK: discover a culprit when we normally couldn't
        elif not (data.get("stacktrace") or data.get("culprit")) and (record.name or record.funcName):
            culprit = label_from_frame({"module": record.name, "function": record.funcName})
            if culprit:
                data["culprit"] = culprit

        data["level"] = record.levelno
        data["logger"] = record.name

        if hasattr(record, "tags"):
            kwargs["tags"] = record.tags

        kwargs.update(handler_kwargs)

        return self.client.capture(event_type, stack=stack, data=data, extra=extra, date=date, **kwargs)
Beispiel #15
0
    def build_msg(
        self,
        event_type,
        data=None,
        date=None,
        time_spent=None,
        extra=None,
        stack=None,
        public_key=None,
        tags=None,
        fingerprint=None,
        **kwargs
    ):
        """
        Captures, processes and serializes an event into a dict object

        The result of ``build_msg`` should be a standardized dict, with
        all default values available.
        """

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

        data = merge_dicts(self.context.data, data)

        data.setdefault("tags", {})
        data.setdefault("extra", {})

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

        handler = self.get_handler(event_type)
        result = handler.capture(**kwargs)

        # data (explicit) culprit takes over auto event detection
        culprit = result.pop("culprit", None)
        if data.get("culprit"):
            culprit = data["culprit"]

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

        # auto_log_stacks only applies to events that are not exceptions
        # due to confusion about which stack is which and the automatic
        # application of stacktrace to exception objects by Sentry
        if stack is None and "exception" not in data:
            stack = self.auto_log_stacks

        if stack and "stacktrace" not in data:
            if stack is True:
                frames = iter_stack_frames()

            else:
                frames = stack

            stack_info = get_stack_info(frames, transformer=self.transform, capture_locals=self.capture_locals)
            data.update({"stacktrace": stack_info})

        if self.include_paths:
            for frame in self._iter_frames(data):
                if frame.get("in_app") is not None:
                    continue

                path = frame.get("module")
                if not path:
                    continue

                if path.startswith("raven."):
                    frame["in_app"] = False
                else:
                    frame["in_app"] = any(path.startswith(x) for x in self.include_paths) and not any(
                        path.startswith(x) for x in self.exclude_paths
                    )

        if not culprit:
            if "stacktrace" in data:
                culprit = get_culprit(data["stacktrace"]["frames"])
            elif "exception" in data:
                stacktrace = data["exception"]["values"][0].get("stacktrace")
                if stacktrace:
                    culprit = get_culprit(stacktrace["frames"])

        if not data.get("level"):
            data["level"] = kwargs.get("level") or logging.ERROR

        if not data.get("server_name"):
            data["server_name"] = self.name

        if not data.get("modules"):
            data["modules"] = self.get_module_versions()

        if self.release is not None:
            data["release"] = self.release

        data["tags"] = merge_dicts(self.tags, data["tags"], tags)
        data["extra"] = merge_dicts(self.extra, data["extra"], extra)

        # Legacy support for site attribute
        site = data.pop("site", None) or self.site
        if site:
            data["tags"].setdefault("site", site)

        if culprit:
            data["culprit"] = culprit

        if fingerprint:
            data["fingerprint"] = fingerprint

        # Run the data through processors
        for processor in self.get_processors():
            data.update(processor.process(data))

        if "message" not in data:
            data["message"] = kwargs.get("message", handler.to_string(data))

        # tags should only be key=>u'value'
        for key, value in six.iteritems(data["tags"]):
            data["tags"][key] = to_unicode(value)

        # extra data can be any arbitrary value
        for k, v in six.iteritems(data["extra"]):
            data["extra"][k] = self.transform(v)

        # It's important date is added **after** we serialize
        data.setdefault("project", self.remote.project)
        data.setdefault("timestamp", date or datetime.utcnow())
        data.setdefault("time_spent", time_spent)
        data.setdefault("event_id", event_id)
        data.setdefault("platform", PLATFORM_NAME)

        return data
Beispiel #16
0
    def _emit(self, record, **kwargs):
        data = {}

        for k, v in six.iteritems(record.__dict__):
            if '.' not in k and k not in ('culprit',):
                continue
            data[k] = v

        stack = getattr(record, 'stack', None)
        if stack is True:
            stack = iter_stack_frames()

        if stack:
            # we might need to traverse this multiple times, so coerce it to a list
            stack = list(stack)
            frames = []
            started = False
            last_mod = ''
            for item in stack:
                if isinstance(item, (list, tuple)):
                    frame, lineno = item
                else:
                    frame, lineno = item, item.f_lineno

                if not started:
                    f_globals = getattr(frame, 'f_globals', {})
                    module_name = f_globals.get('__name__', '')
                    if (last_mod and last_mod.startswith('logging')) \
                        and not module_name.startswith('logging'):
                        started = True
                    else:
                        last_mod = module_name
                        continue
                frames.append((frame, lineno))

            # We must've not found a starting point
            if not frames:
                frames = stack

            stack = frames

        extra = getattr(record, 'data', None)
        if not isinstance(extra, dict):
            if extra:
                extra = {'data': extra}
            else:
                extra = {}

        # Add in all of the data from the record that we aren't already capturing
        for k in record.__dict__.keys():
            if k in RESERVED:
                continue
            if k.startswith('_'):
                continue
            extra[k] = record.__dict__[k]

        date = datetime.datetime.utcfromtimestamp(record.created)
        event_type = 'raven.events.Message'
        handler_kwargs = {'message': record.msg, 'params': record.args}

        # If there's no exception being processed, exc_info may be a 3-tuple of None
        # http://docs.python.org/library/sys.html#sys.exc_info
        if record.exc_info and all(record.exc_info):
            # capture the standard message first so that we ensure
            # the event is recorded as an exception, in addition to having our
            # message interface attached
            handler = self.client.get_handler(event_type)
            data.update(handler.capture(**handler_kwargs))
            # ensure message is propagated, otherwise the exception will overwrite it
            data['message'] = record.message

            event_type = 'raven.events.Exception'
            handler_kwargs = {'exc_info': record.exc_info}

        # HACK: discover a culprit when we normally couldn't
        elif not (data.get('sentry.interfaces.Stacktrace') or data.get('culprit')) and (record.name or record.funcName):
            culprit = label_from_frame({'module': record.name, 'function': record.funcName})
            if culprit:
                data['culprit'] = culprit

        data['level'] = record.levelno
        data['logger'] = record.name

        if hasattr(record, 'tags'):
            kwargs['tags'] = record.tags

        kwargs.update(handler_kwargs)

        return self.client.capture(event_type, stack=stack, data=data, extra=extra,
            date=date, **kwargs)
Beispiel #17
0
    def build_msg(self,
                  event_type,
                  data=None,
                  date=None,
                  time_spent=None,
                  extra=None,
                  stack=None,
                  public_key=None,
                  tags=None,
                  **kwargs):
        """
        Captures, processes and serializes an event into a dict object

        The result of ``build_msg`` should be a standardized dict, with
        all default values available.
        """

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

        if data is None:
            data = {}
        if extra is None:
            extra = {}
        if not date:
            date = datetime.datetime.utcnow()
        if stack is None:
            stack = self.auto_log_stacks

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

        handler = self.get_handler(event_type)
        result = handler.capture(**kwargs)

        # data (explicit) culprit takes over auto event detection
        culprit = result.pop('culprit', None)
        if data.get('culprit'):
            culprit = data['culprit']

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

        if stack and 'sentry.interfaces.Stacktrace' not in data:
            if stack is True:
                frames = iter_stack_frames()

            else:
                frames = stack

            data.update({
                'sentry.interfaces.Stacktrace': {
                    'frames': get_stack_info(frames,
                                             transformer=self.transform)
                },
            })

        if 'sentry.interfaces.Stacktrace' in data:
            if self.include_paths:
                for frame in data['sentry.interfaces.Stacktrace']['frames']:
                    if frame.get('in_app') is not None:
                        continue

                    path = frame.get('module')
                    if not path:
                        continue

                    if path.startswith('raven.'):
                        frame['in_app'] = False
                    else:
                        frame['in_app'] = (any(
                            path.startswith(x) for x in self.include_paths)
                                           and not any(
                                               path.startswith(x)
                                               for x in self.exclude_paths))

            if not culprit:
                culprit = get_culprit(
                    data['sentry.interfaces.Stacktrace']['frames'])

        if not data.get('level'):
            data['level'] = kwargs.get('level') or logging.ERROR

        if not data.get('server_name'):
            data['server_name'] = self.name

        if not data.get('modules'):
            data['modules'] = self.get_module_versions()

        data['tags'] = tags or {}
        data.setdefault('extra', {})
        data.setdefault('level', logging.ERROR)

        # Add default extra context
        if self.extra:
            for k, v in six.iteritems(self.extra):
                data['extra'].setdefault(k, v)

        # Add default tag context
        if self.tags:
            for k, v in six.iteritems(self.tags):
                data['tags'].setdefault(k, v)

        for k, v in six.iteritems(extra):
            data['extra'][k] = v

        if culprit:
            data['culprit'] = culprit

        # Run the data through processors
        for processor in self.get_processors():
            data.update(processor.process(data))

        if 'message' not in data:
            data['message'] = handler.to_string(data)

        data.setdefault('project', self.project)

        # Legacy support for site attribute
        site = data.pop('site', None) or self.site
        if site:
            data['tags'].setdefault('site', site)

        for key, value in six.iteritems(data['tags']):
            data['tags'][key] = to_unicode(value)

        # Make sure custom data is coerced
        for k, v in six.iteritems(data['extra']):
            data['extra'][k] = self.transform(v)

        # It's important date is added **after** we serialize
        data.update({
            'timestamp': date,
            'time_spent': time_spent,
            'event_id': event_id,
            'platform': PLATFORM_NAME,
        })

        return data
Beispiel #18
0
 def make_record(self, msg, args=(), level=logging.INFO, extra=None, exc_info=None, name='root', pathname=__file__):
     record = logging.LogRecord(name, level, pathname, 27, msg, args, exc_info, 'make_record')
     if extra:
         for key, value in six.iteritems(extra):
             record.__dict__[key] = value
     return record
Beispiel #19
0
 def __enter__(self):
     for k, v in six.iteritems(self.overrides):
         self._orig[k] = getattr(settings, k, self.NotDefined)
         setattr(settings, k, v)
Beispiel #20
0
def get_stack_info(frames, transformer=transform, capture_locals=True,
                   max_frames=50):
    """
    Given a list of frames, returns a list of stack information
    dictionary objects that are JSON-ready.

    We have to be careful here as certain implementations of the
    _Frame class do not contain the nescesary data to lookup all
    of the information we want.
    """
    __traceback_hide__ = True  # NOQA

    half_max = max_frames / 2

    top_results = []
    bottom_results = []

    total_frames = 0

    for frame_no, frame_info in enumerate(frames):
        # Old, terrible API
        if isinstance(frame_info, (list, tuple)):
            frame, lineno = frame_info

        else:
            frame = frame_info
            lineno = frame_info.f_lineno

        # Support hidden frames
        f_locals = getattr(frame, 'f_locals', {})
        if _getitem_from_frame(f_locals, '__traceback_hide__'):
            continue

        f_globals = getattr(frame, 'f_globals', {})

        f_code = getattr(frame, 'f_code', None)
        if f_code:
            abs_path = frame.f_code.co_filename
            function = frame.f_code.co_name
        else:
            abs_path = None
            function = None

        loader = _getitem_from_frame(f_globals, '__loader__')
        module_name = _getitem_from_frame(f_globals, '__name__')

        if lineno:
            lineno -= 1

        if lineno is not None and abs_path:
            pre_context, context_line, post_context = get_lines_from_file(abs_path, lineno, 5, loader, module_name)
        else:
            pre_context, context_line, post_context = None, None, None

        # Try to pull a relative file path
        # This changes /foo/site-packages/baz/bar.py into baz/bar.py
        try:
            base_filename = sys.modules[module_name.split('.', 1)[0]].__file__
            filename = abs_path.split(base_filename.rsplit('/', 2)[0], 1)[-1].lstrip("/")
        except:
            filename = abs_path

        if not filename:
            filename = abs_path

        if capture_locals and not isinstance(f_locals, dict):
            # XXX: Genshi (and maybe others) have broken implementations of
            # f_locals that are not actually dictionaries
            try:
                f_locals = to_dict(f_locals)
            except Exception:
                capture_locals = False

        frame_result = {
            'abs_path': abs_path,
            'filename': filename,
            'module': module_name or None,
            'function': function or '<unknown>',
            'lineno': lineno + 1,
        }
        if capture_locals:
            frame_result['vars'] = dict(
                (k, transformer(v))
                for k, v in six.iteritems(f_locals)
            )

        if context_line is not None:
            frame_result.update({
                'pre_context': pre_context,
                'context_line': context_line,
                'post_context': post_context,
            })

        if frame_no >= half_max:
            while len(bottom_results) > half_max - 1:
                bottom_results.pop(0)
            bottom_results.append(frame_result)
        else:
            top_results.append(frame_result)
        total_frames += 1

    stackinfo = {
        'frames': top_results + bottom_results,
    }
    if total_frames > max_frames:
        stackinfo['frames_omitted'] = (half_max + 1, total_frames - half_max + 1)

    return stackinfo
Beispiel #21
0
    def _emit(self, record, **kwargs):
        data = {}

        extra = getattr(record, 'data', None)
        if not isinstance(extra, dict):
            if extra:
                extra = {'data': extra}
            else:
                extra = {}

        for k, v in six.iteritems(vars(record)):
            if k in RESERVED:
                continue
            if k.startswith('_'):
                continue
            if '.' not in k and k not in ('culprit', 'server_name', 'fingerprint'):
                extra[k] = v
            else:
                data[k] = v

        stack = getattr(record, 'stack', None)
        if stack is True:
            stack = iter_stack_frames()

        if stack:
            stack = self._get_targetted_stack(stack, record)

        date = datetime.datetime.utcfromtimestamp(record.created)
        event_type = 'raven.events.Message'
        handler_kwargs = {
            'params': record.args,
        }
        try:
            handler_kwargs['message'] = six.text_type(record.msg)
        except UnicodeDecodeError:
            # Handle binary strings where it should be unicode...
            handler_kwargs['message'] = repr(record.msg)[1:-1]

        try:
            handler_kwargs['formatted'] = six.text_type(record.message)
        except UnicodeDecodeError:
            # Handle binary strings where it should be unicode...
            handler_kwargs['formatted'] = repr(record.message)[1:-1]

        # If there's no exception being processed, exc_info may be a 3-tuple of None
        # http://docs.python.org/library/sys.html#sys.exc_info
        if record.exc_info and all(record.exc_info):
            # capture the standard message first so that we ensure
            # the event is recorded as an exception, in addition to having our
            # message interface attached
            handler = self.client.get_handler(event_type)
            data.update(handler.capture(**handler_kwargs))

            event_type = 'raven.events.Exception'
            handler_kwargs = {'exc_info': record.exc_info}

        # HACK: discover a culprit when we normally couldn't
        elif not (data.get('stacktrace') or data.get('culprit')) and (record.name or record.funcName):
            culprit = label_from_frame({'module': record.name, 'function': record.funcName})
            if culprit:
                data['culprit'] = culprit

        data['level'] = record.levelno
        data['logger'] = record.name

        if hasattr(record, 'tags'):
            kwargs['tags'] = record.tags
        elif self.tags:
            kwargs['tags'] = self.tags

        kwargs.update(handler_kwargs)

        return self.client.capture(
            event_type, stack=stack, data=data,
            extra=extra, date=date, **kwargs)
Beispiel #22
0
    def _emit(self, record, **kwargs):
        data = {}

        extra = getattr(record, 'data', None)
        if not isinstance(extra, dict):
            if extra:
                extra = {'data': extra}
            else:
                extra = {}

        for k, v in six.iteritems(vars(record)):
            if k in RESERVED:
                continue
            if k.startswith('_'):
                continue
            if '.' not in k and k not in ('culprit', 'server_name'):
                extra[k] = v
            else:
                data[k] = v

        stack = getattr(record, 'stack', None)
        if stack is True:
            stack = iter_stack_frames()

        if stack:
            stack = self._get_targetted_stack(stack, record)

        date = datetime.datetime.utcfromtimestamp(record.created)
        event_type = 'raven.events.Message'
        handler_kwargs = {
            'params': record.args,
        }
        try:
            handler_kwargs['message'] = six.text_type(record.msg)
        except UnicodeDecodeError:
            # Handle binary strings where it should be unicode...
            handler_kwargs['message'] = repr(record.msg)[1:-1]

        try:
            handler_kwargs['formatted'] = six.text_type(record.message)
        except UnicodeDecodeError:
            # Handle binary strings where it should be unicode...
            handler_kwargs['formatted'] = repr(record.message)[1:-1]

        # If there's no exception being processed, exc_info may be a 3-tuple of None
        # http://docs.python.org/library/sys.html#sys.exc_info
        if record.exc_info and all(record.exc_info):
            # capture the standard message first so that we ensure
            # the event is recorded as an exception, in addition to having our
            # message interface attached
            handler = self.client.get_handler(event_type)
            data.update(handler.capture(**handler_kwargs))

            event_type = 'raven.events.Exception'
            handler_kwargs = {'exc_info': record.exc_info}

        # HACK: discover a culprit when we normally couldn't
        elif not (data.get('stacktrace')
                  or data.get('culprit')) and (record.name or record.funcName):
            culprit = label_from_frame({
                'module': record.name,
                'function': record.funcName
            })
            if culprit:
                data['culprit'] = culprit

        data['level'] = record.levelno
        data['logger'] = record.name

        if hasattr(record, 'tags'):
            kwargs['tags'] = record.tags

        kwargs.update(handler_kwargs)

        return self.client.capture(event_type,
                                   stack=stack,
                                   data=data,
                                   extra=extra,
                                   date=date,
                                   **kwargs)
    def __call(self, function, *args, **kwargs):
        for key, value in six.iteritems(self.defaults):
            if key not in kwargs:
                kwargs[key] = value

        return function(*args, **kwargs)
Beispiel #24
0
def get_stack_info(frames,
                   transformer=transform,
                   capture_locals=True,
                   max_frames=50):
    """
    Given a list of frames, returns a list of stack information
    dictionary objects that are JSON-ready.

    We have to be careful here as certain implementations of the
    _Frame class do not contain the necessary data to lookup all
    of the information we want.
    """
    __traceback_hide__ = True  # NOQA

    half_max = max_frames / 2

    top_results = []
    bottom_results = []

    total_frames = 0

    for frame_no, frame_info in enumerate(frames):
        # Old, terrible API
        if isinstance(frame_info, (list, tuple)):
            frame, lineno = frame_info

        else:
            frame = frame_info
            lineno = frame_info.f_lineno

        # Support hidden frames
        f_locals = getattr(frame, 'f_locals', {})
        if _getitem_from_frame(f_locals, '__traceback_hide__'):
            continue

        f_globals = getattr(frame, 'f_globals', {})

        f_code = getattr(frame, 'f_code', None)
        if f_code:
            abs_path = frame.f_code.co_filename
            function = frame.f_code.co_name
        else:
            abs_path = None
            function = None

        loader = _getitem_from_frame(f_globals, '__loader__')
        module_name = _getitem_from_frame(f_globals, '__name__')

        if lineno:
            lineno -= 1

        if lineno is not None and abs_path:
            pre_context, context_line, post_context = get_lines_from_file(
                abs_path, lineno, 5, loader, module_name)
        else:
            pre_context, context_line, post_context = None, None, None

        # Try to pull a relative file path
        # This changes /foo/site-packages/baz/bar.py into baz/bar.py
        try:
            base_filename = sys.modules[module_name.split('.', 1)[0]].__file__
            filename = abs_path.split(base_filename.rsplit('/', 2)[0],
                                      1)[-1].lstrip("/")
        except:
            filename = abs_path

        if not filename:
            filename = abs_path

        if capture_locals and not isinstance(f_locals, dict):
            # XXX: Genshi (and maybe others) have broken implementations of
            # f_locals that are not actually dictionaries
            try:
                f_locals = to_dict(f_locals)
            except Exception:
                capture_locals = False

        frame_result = {
            'abs_path': abs_path,
            'filename': filename,
            'module': module_name or None,
            'function': function or '<unknown>',
            'lineno': lineno + 1,
        }
        if capture_locals:
            frame_result['vars'] = dict(
                (k, transformer(v)) for k, v in six.iteritems(f_locals))

        if context_line is not None:
            frame_result.update({
                'pre_context': pre_context,
                'context_line': context_line,
                'post_context': post_context,
            })

        if frame_no >= half_max:
            while len(bottom_results) > half_max - 1:
                bottom_results.pop(0)
            bottom_results.append(frame_result)
        else:
            top_results.append(frame_result)
        total_frames += 1

    stackinfo = {
        'frames': top_results + bottom_results,
    }
    if total_frames > max_frames:
        stackinfo['frames_omitted'] = (half_max + 1,
                                       total_frames - half_max + 1)

    return stackinfo