diff options
author | Armin Ronacher <armin.ronacher@active-4.com> | 2015-11-19 19:57:09 +0100 |
---|---|---|
committer | Armin Ronacher <armin.ronacher@active-4.com> | 2015-11-19 19:57:09 +0100 |
commit | be2a78f16577589e74f147bf44fffec64500539b (patch) | |
tree | c4815feb1c6a23ac0d777242f0823c66f726def0 | |
parent | bbc7e1523c3723c5fe479494e03abb0e0400ecf1 (diff) | |
download | raven-feature/better-stripping.tar.gz |
Implemented more intelligent frame strippingfeature/better-stripping
-rw-r--r-- | raven/base.py | 8 | ||||
-rw-r--r-- | raven/events.py | 1 | ||||
-rw-r--r-- | raven/utils/stacks.py | 58 |
3 files changed, 51 insertions, 16 deletions
diff --git a/raven/base.py b/raven/base.py index f258aa2..68810e5 100644 --- a/raven/base.py +++ b/raven/base.py @@ -29,7 +29,8 @@ from raven.exceptions import APIError, RateLimited from raven.utils import six, json, get_versions, get_auth_header, merge_dicts from raven.utils.encoding import to_unicode from raven.utils.serializer import transform -from raven.utils.stacks import get_stack_info, iter_stack_frames, get_culprit +from raven.utils.stacks import get_stack_info, iter_stack_frames, \ + get_culprit, slim_frame_data from raven.transport.registry import TransportRegistry, default_transports __all__ = ('Client',) @@ -322,11 +323,13 @@ class Client(object): frames, transformer=self.transform, capture_locals=self.capture_locals, + frame_allowance=None, ) data.update({ 'stacktrace': stack_info, }) + in_app_info = False if self.include_paths: for frame in self._iter_frames(data): if frame.get('in_app') is not None: @@ -336,6 +339,7 @@ class Client(object): if not path: continue + in_app_info = True if path.startswith('raven.'): frame['in_app'] = False else: @@ -344,6 +348,8 @@ class Client(object): not any(path.startswith(x) for x in self.exclude_paths) ) + slim_frame_data(self._iter_frames(data), in_app_info=in_app_info) + if not culprit: if 'stacktrace' in data: culprit = get_culprit(data['stacktrace']['frames']) diff --git a/raven/events.py b/raven/events.py index e3dc25d..03c8715 100644 --- a/raven/events.py +++ b/raven/events.py @@ -63,6 +63,7 @@ class Exception(BaseEvent): iter_traceback_frames(exc_traceback), transformer=self.transform, capture_locals=self.client.capture_locals, + frame_allowance=None, ) exc_module = getattr(exc_type, '__module__', None) diff --git a/raven/utils/stacks.py b/raven/utils/stacks.py index 62791ff..2a70c5e 100644 --- a/raven/utils/stacks.py +++ b/raven/utils/stacks.py @@ -187,25 +187,52 @@ def get_frame_locals(frame, transformer=transform, max_var_size=4096): return f_vars -def slim_frame_data(frames, frame_allowance=25): +def slim_frame_data(frames, frame_allowance=25, in_app_info=False): """ Removes various excess metadata from middle frames which go beyond ``frame_allowance``. Returns ``frames``. """ - frames_len = len(frames) - - if frames_len <= frame_allowance: - return frames - + def _strip(frames): + for frame in frames: + frame.pop('vars', None) + frame.pop('pre_context', None) + frame.pop('post_context', None) + + # We have frames marked as in app, so collect everything not in app + # and strip those. + if in_app_info: + in_app_frames = [] + framework_frames = [] + + for frame in frames: + if frame.get('in_app'): + in_app_frames.append(frame) + else: + framework_frames.append(frame) + + # Fewer frames than our limit, just do nothing + if len(in_app_frames) + len(framework_frames) < frame_allowance: + return + + # App frames alone area already over limit. + if len(in_app_frames) > frame_allowance: + _strip(in_app_frames[:-frame_allowance]) + _strip(framework_frames) + return + + _strip(framework_frames[:-frame_allowance - len(in_app_frames)]) + return + + # If we don't know what's in the app, we just throw away the data in + # the first few frames. half_max = int(frame_allowance / 2) + if not in_app_info: + frames = list(frames) + for n in range(half_max, len(frames) - half_max): + _strip(frames[n]) - for n in range(half_max, frames_len - half_max): - # remove heavy components - frames[n].pop('vars', None) - frames[n].pop('pre_context', None) - frames[n].pop('post_context', None) return frames @@ -288,8 +315,9 @@ def get_stack_info(frames, transformer=transform, capture_locals=True, }) result.append(frame_result) - stackinfo = { - 'frames': slim_frame_data(result, frame_allowance=frame_allowance), - } + if frame_allowance is not None: + result = slim_frame_data(result, frame_allowance=frame_allowance) - return stackinfo + return { + 'frames': result + } |