def transform(value, stack=None, context=None): # TODO: make this extendable if context is None: context = {} if stack is None: stack = [] objid = id(value) if objid in context: return '<...>' context[objid] = 1 transform_rec = lambda o: transform(o, stack + [value], context) if any(value is s for s in stack): ret = 'cycle' elif isinstance(value, (tuple, list, set, frozenset)): try: ret = type(value)(transform_rec(o) for o in value) except Exception: # We may be dealing with a namedtuple class value_type(list): __name__ = type(value).__name__ ret = value_type(transform_rec(o) for o in value) elif isinstance(value, uuid.UUID): ret = repr(value) elif isinstance(value, dict): ret = dict((to_unicode(k), transform_rec(v)) for k, v in six.iteritems(value)) elif isinstance(value, six.text_type): ret = to_unicode(value) elif isinstance(value, six.binary_type): ret = to_string(value) elif not isinstance(value, six.class_types) and \ _has_opbeat_metadata(value): ret = transform_rec(value.__opbeat__()) # elif isinstance(value, Promise): # # EPIC HACK # # handles lazy model instances (which are proxy values that dont easily give you the actual function) # pre = value.__class__.__name__[1:] # value = getattr(value, '%s__func' % pre)(*getattr(value, '%s__args' % pre), **getattr(value, '%s__kw' % pre)) # return transform(value) elif isinstance(value, bool): ret = bool(value) elif isinstance(value, float): ret = float(value) elif isinstance(value, int): ret = int(value) elif six.PY2 and isinstance(value, long): ret = long(value) elif value is not None: try: ret = transform(repr(value)) except: # It's common case that a model's __unicode__ definition may try to query the database # which if it was not cleaned up correctly, would hit a transaction aborted exception ret = u'<BadRepr: %s>' % type(value) else: ret = None del context[objid] return ret
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: 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.startswith('logging') and not module_name.startswith('logging'): started = True else: last_mod = module_name continue frames.append((frame, lineno)) stack = frames extra = getattr(record, 'data', {}) # Add in all of the data from the record that we aren't already capturing for k in record.__dict__.keys(): if k in ('stack', 'name', 'args', 'msg', 'levelno', 'exc_text', 'exc_info', 'data', 'created', 'levelname', 'msecs', 'relativeCreated'): continue if k.startswith('_'): continue extra[k] = record.__dict__[k] date = datetime.datetime.utcfromtimestamp(record.created) # 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): handler = self.client.get_handler('opbeat.events.Exception') data.update(handler.capture(exc_info=record.exc_info)) # data['checksum'] = handler.get_hash(data) data['level'] = record.levelno data['logger'] = record.name return self.client.capture('Message', param_message={'message':record.msg,'params':record.args}, stack=stack, data=data, extra=extra, date=date, **kwargs)
def transform(value, stack=None, context=None): # TODO: make this extendable if context is None: context = {} if stack is None: stack = [] objid = id(value) if objid in context: return '<...>' context[objid] = 1 transform_rec = lambda o: transform(o, stack + [value], context) if any(value is s for s in stack): ret = 'cycle' elif isinstance(value, (tuple, list, set, frozenset)): try: ret = type(value)(transform_rec(o) for o in value) except Exception: # We may be dealing with a namedtuple class value_type(list): __name__ = type(value).__name__ ret = value_type(transform_rec(o) for o in value) elif isinstance(value, uuid.UUID): ret = repr(value) elif isinstance(value, dict): ret = dict( (to_unicode(k), transform_rec(v)) for k, v in six.iteritems(value)) elif isinstance(value, six.text_type): ret = to_unicode(value) elif isinstance(value, six.binary_type): ret = to_string(value) elif not isinstance(value, six.class_types) and \ _has_opbeat_metadata(value): ret = transform_rec(value.__opbeat__()) elif isinstance(value, bool): ret = bool(value) elif isinstance(value, float): ret = float(value) elif isinstance(value, int): ret = int(value) elif six.PY2 and isinstance(value, long): ret = long(value) elif value is not None: try: ret = transform(repr(value)) except: # It's common case that a model's __unicode__ definition may try to query the database # which if it was not cleaned up correctly, would hit a transaction aborted exception ret = u'<BadRepr: %s>' % type(value) else: ret = None del context[objid] return ret
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 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 _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: 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.startswith( 'logging' ) and not module_name.startswith('logging'): started = True else: last_mod = module_name continue frames.append((frame, lineno)) stack = frames extra = getattr(record, 'data', {}) # Add in all of the data from the record that we aren't already capturing for k in record.__dict__.keys(): if k in ('stack', 'name', 'args', 'msg', 'levelno', 'exc_text', 'exc_info', 'data', 'created', 'levelname', 'msecs', 'relativeCreated'): continue if k.startswith('_'): continue extra[k] = record.__dict__[k] date = datetime.datetime.utcfromtimestamp(record.created) # 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): handler = self.client.get_handler('opbeat.events.Exception') data.update(handler.capture(exc_info=record.exc_info)) # data['checksum'] = handler.get_hash(data) data['level'] = record.levelno data['logger'] = record.name return self.client.capture('Message', param_message={ 'message': record.msg, 'params': record.args }, stack=stack, data=data, extra=extra, date=date, **kwargs)
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 build_msg_for_logging(self, event_type, data=None, date=None, extra=None, stack=None, **kwargs): """ Captures, processes and serializes an event into a dict object """ # 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 self.build_msg(data=data) # if '.' not in event_type: # Assume it's a builtin event_type = 'opbeat.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 'stacktrace' not in data: if stack is True: frames = iter_stack_frames() else: frames = stack data.update({ 'stacktrace': { 'frames': varmap(lambda k, v: shorten(v, string_length=self.string_max_length, list_length=self.list_max_length), get_stack_info(frames)) }, }) if 'stacktrace' in data and not culprit: culprit = get_culprit( data['stacktrace']['frames'], self.include_paths, self.exclude_paths ) if not data.get('level'): data['level'] = 'error' if isinstance( data['level'], six.integer_types): data['level'] = logging.getLevelName(data['level']).lower() data.setdefault('extra', {}) # Shorten lists/strings for k, v in six.iteritems(extra): data['extra'][k] = shorten(v, string_length=self.string_max_length, list_length=self.list_max_length) if culprit: data['culprit'] = culprit # Run the data through processors for processor in self.get_processors(): data.update(processor.process(data)) # Make sure all data is coerced data = transform(data) if 'message' not in data: data['message'] = handler.to_string(data) # Make sure certain values are not too long for v in defaults.MAX_LENGTH_VALUES: if v in data: data[v] = shorten(data[v], string_length=defaults.MAX_LENGTH_VALUES[v] ) data.update({ 'timestamp': date, # 'time_spent': time_spent, 'client_supplied_id': event_id, }) return data
def build_msg_for_logging(self, event_type, data=None, date=None, extra=None, stack=None, **kwargs): """ Captures, processes and serializes an event into a dict object """ # 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 self.build_msg(data=data) # if '.' not in event_type: # Assume it's a builtin event_type = 'opbeat.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 'stacktrace' not in data: if stack is True: frames = iter_stack_frames() else: frames = stack data.update({ 'stacktrace': { 'frames': varmap( lambda k, v: shorten(v, string_length=self. string_max_length, list_length=self.list_max_length), stacks.get_stack_info(frames)) }, }) if 'stacktrace' in data and not culprit: culprit = get_culprit(data['stacktrace']['frames'], self.include_paths, self.exclude_paths) if not data.get('level'): data['level'] = 'error' if isinstance(data['level'], six.integer_types): data['level'] = logging.getLevelName(data['level']).lower() data.setdefault('extra', {}) # Shorten lists/strings for k, v in six.iteritems(extra): data['extra'][k] = shorten(v, string_length=self.string_max_length, list_length=self.list_max_length) if culprit: data['culprit'] = culprit # Run the data through processors for processor in self.get_processors(): data.update(processor.process(data)) # Make sure all data is coerced data = transform(data) if 'message' not in data: data['message'] = handler.to_string(data) # Make sure certain values are not too long for v in defaults.MAX_LENGTH_VALUES: if v in data: data[v] = shorten(data[v], string_length=defaults.MAX_LENGTH_VALUES[v]) data.update({ 'timestamp': date, # 'time_spent': time_spent, 'client_supplied_id': event_id, }) return data