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
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))) )
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
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
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
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
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
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
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
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)
def __enter__(self): for k, v in six.iteritems(self.overrides): self._orig[k] = getattr(settings, k, self.NotDefined) setattr(settings, k, v)
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
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 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
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)
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
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
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
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)
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)
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