def test_over_max(self): values = [] for n in xrange(5): values.append({'filename': 'frame %d' % n}) value = {'frames': values} trim_frames(value, max_frames=4) assert len(value['frames']) == 4 for value, num in itertools.izip(values[:2], xrange(2)): assert value['filename'] == 'frame %d' % num for value, num in itertools.izip(values[2:], xrange(3, 5)): assert value['filename'] == 'frame %d' % num
def normalize_event_data(self, data): # TODO(dcramer): store http.env.REMOTE_ADDR as user.ip # First we pull out our top-level (non-data attr) kwargs if not isinstance(data.get('level'), (basestring, int)): data['level'] = logging.ERROR elif data['level'] not in LOG_LEVELS: data['level'] = logging.ERROR if not data.get('logger'): data['logger'] = DEFAULT_LOGGER_NAME else: data['logger'] = trim(data['logger'], 64) if data.get('platform'): data['platform'] = trim(data['platform'], 64) timestamp = data.get('timestamp') if not timestamp: timestamp = timezone.now() # We must convert date to local time so Django doesn't mess it up # based on TIME_ZONE if settings.TIME_ZONE: if not timezone.is_aware(timestamp): timestamp = timestamp.replace(tzinfo=timezone.utc) elif timezone.is_aware(timestamp): timestamp = timestamp.replace(tzinfo=None) data['timestamp'] = timestamp if not data.get('event_id'): data['event_id'] = uuid.uuid4().hex data.setdefault('message', None) data.setdefault('culprit', None) data.setdefault('time_spent', None) data.setdefault('server_name', None) data.setdefault('site', None) data.setdefault('checksum', None) data.setdefault('platform', None) data.setdefault('extra', {}) tags = data.get('tags') if not tags: tags = [] # full support for dict syntax elif isinstance(tags, dict): tags = tags.items() # prevent [tag, tag, tag] (invalid) syntax elif not all(len(t) == 2 for t in tags): tags = [] else: tags = list(tags) data['tags'] = tags if not isinstance(data['extra'], dict): # throw it away data['extra'] = {} trim_dict( data['extra'], max_size=settings.SENTRY_MAX_EXTRA_VARIABLE_SIZE) # TODO: each interface should describe its own normalization logic if 'sentry.interfaces.Exception' in data: if 'values' not in data['sentry.interfaces.Exception']: data['sentry.interfaces.Exception'] = { 'values': [data['sentry.interfaces.Exception']] } # convert stacktrace + exception into expanded exception if 'sentry.interfaces.Stacktrace' in data: data['sentry.interfaces.Exception']['values'][0]['stacktrace'] = data.pop('sentry.interfaces.Stacktrace') for exc_data in data['sentry.interfaces.Exception']['values']: for key in ('type', 'module', 'value'): value = exc_data.get(key) if value: exc_data[key] = trim(value) if exc_data.get('stacktrace'): trim_frames(exc_data['stacktrace']) for frame in exc_data['stacktrace']['frames']: stack_vars = frame.get('vars', {}) trim_dict(stack_vars) for key, value in frame.iteritems(): if key not in ('vars', 'data'): frame[key] = trim(value) if 'sentry.interfaces.Stacktrace' in data: trim_frames(data['sentry.interfaces.Stacktrace']) for frame in data['sentry.interfaces.Stacktrace']['frames']: stack_vars = frame.get('vars', {}) trim_dict(stack_vars) for key, value in frame.iteritems(): if key not in ('vars', 'data'): frame[key] = trim(value) if 'sentry.interfaces.Message' in data: msg_data = data['sentry.interfaces.Message'] trim(msg_data['message'], 1024) if msg_data.get('params'): msg_data['params'] = trim(msg_data['params']) if 'sentry.interfaces.Http' in data: http_data = data['sentry.interfaces.Http'] for key in ('cookies', 'querystring', 'headers', 'env', 'url'): value = http_data.get(key) if not value: continue if type(value) == dict: trim_dict(value) else: http_data[key] = trim(value) value = http_data.get('data') if value: http_data['data'] = trim(value, 2048) # default the culprit to the url if not data['culprit']: data['culprit'] = strip(http_data.get('url')) if data['culprit']: data['culprit'] = trim(strip(data['culprit']), MAX_CULPRIT_LENGTH) if data['message']: data['message'] = strip(data['message']) return data
def normalize_event_data(self, data): # TODO(dcramer): store http.env.REMOTE_ADDR as user.ip # First we pull out our top-level (non-data attr) kwargs if not data.get('level') or data['level'] not in LOG_LEVELS: data['level'] = logging.ERROR if not data.get('logger'): data['logger'] = DEFAULT_LOGGER_NAME else: data['logger'] = trim(data['logger'], 64) timestamp = data.get('timestamp') if not timestamp: timestamp = timezone.now() # We must convert date to local time so Django doesn't mess it up # based on TIME_ZONE if settings.TIME_ZONE: if not timezone.is_aware(timestamp): timestamp = timestamp.replace(tzinfo=timezone.utc) elif timezone.is_aware(timestamp): timestamp = timestamp.replace(tzinfo=None) data['timestamp'] = timestamp if not data.get('event_id'): data['event_id'] = uuid.uuid4().hex data.setdefault('message', None) data.setdefault('culprit', None) data.setdefault('time_spent', None) data.setdefault('server_name', None) data.setdefault('site', None) data.setdefault('checksum', None) data.setdefault('platform', None) data.setdefault('extra', {}) tags = data.get('tags') if not tags: tags = [] # full support for dict syntax elif isinstance(tags, dict): tags = tags.items() # prevent [tag, tag, tag] (invalid) syntax elif not all(len(t) == 2 for t in tags): tags = [] else: tags = list(tags) data['tags'] = tags data['message'] = strip(data['message']) data['culprit'] = strip(data['culprit']) if not isinstance(data['extra'], dict): # throw it away data['extra'] = {} trim_dict(data['extra'], max_size=MAX_EXTRA_VARIABLE_SIZE) if 'sentry.interfaces.Exception' in data: if 'values' not in data['sentry.interfaces.Exception']: data['sentry.interfaces.Exception'] = { 'values': [data['sentry.interfaces.Exception']] } # convert stacktrace + exception into expanded exception if 'sentry.interfaces.Stacktrace' in data: data['sentry.interfaces.Exception']['values'][0][ 'stacktrace'] = data.pop('sentry.interfaces.Stacktrace') for exc_data in data['sentry.interfaces.Exception']['values']: for key in ('type', 'module', 'value'): value = exc_data.get(key) if value: exc_data[key] = trim(value) if exc_data.get('stacktrace'): trim_frames(exc_data['stacktrace']) for frame in exc_data['stacktrace']['frames']: stack_vars = frame.get('vars', {}) trim_dict(stack_vars) if 'sentry.interfaces.Stacktrace' in data: trim_frames(data['sentry.interfaces.Stacktrace']) for frame in data['sentry.interfaces.Stacktrace']['frames']: stack_vars = frame.get('vars', {}) trim_dict(stack_vars) if 'sentry.interfaces.Message' in data: msg_data = data['sentry.interfaces.Message'] trim(msg_data['message'], 1024) if msg_data.get('params'): msg_data['params'] = trim(msg_data['params']) if 'sentry.interfaces.Http' in data: http_data = data['sentry.interfaces.Http'] for key in ('cookies', 'querystring', 'headers', 'env', 'url'): value = http_data.get(key) if not value: continue if type(value) == dict: trim_dict(value) else: http_data[key] = trim(value) value = http_data.get('data') if value: http_data['data'] = trim(value, 2048) # default the culprit to the url if not data['culprit']: data['culprit'] = trim(strip(http_data.get('url')), MAX_CULPRIT_LENGTH) return data
def test_under_max(self): value = {'frames': [{'filename': 'foo'}]} trim_frames(value) assert len(value['frames']) == 1 assert value.get('frames_omitted') is None