def test_library_frames(elasticapm_client): include = elasticapm_client.include_paths_re exclude = elasticapm_client.exclude_paths_re frame1 = Mock(f_globals={'__name__': 'a.b.c'}) frame2 = Mock(f_globals={'__name__': 'a.b.c.d'}) frame3 = Mock(f_globals={'__name__': 'c.d'}) info1 = stacks.get_frame_info(frame1, 1, False, False, include_paths_re=include, exclude_paths_re=exclude) info2 = stacks.get_frame_info(frame2, 1, False, False, include_paths_re=include, exclude_paths_re=exclude) info3 = stacks.get_frame_info(frame3, 1, False, False, include_paths_re=include, exclude_paths_re=exclude) assert not info1['library_frame'] assert not info2['library_frame'] assert info3['library_frame']
def iterate_with_template_sources(frames, with_source_context=True, with_locals=True, include_paths_re=None, exclude_paths_re=None): template = None for frame, lineno in frames: f_code = getattr(frame, 'f_code', None) if f_code: function = frame.f_code.co_name if function == 'render': renderer = getattr(frame, 'f_locals', {}).get('self') if renderer and isinstance(renderer, Node): if getattr(renderer, "token", None) is not None: if hasattr(renderer, "source"): # up to Django 1.8 yield { 'lineno': renderer.token.lineno, 'filename': renderer.source[0].name } else: template = {'lineno': renderer.token.lineno} # Django 1.9 doesn't have the origin on the Node instance, # so we have to get it a bit further down the stack from the # Template instance elif renderer and isinstance(renderer, Template): if template and getattr(renderer, 'origin', None): template['filename'] = renderer.origin.name yield template template = None yield get_frame_info(frame, lineno, with_source_context, with_locals, include_paths_re, exclude_paths_re)
def test_library_frames(elasticapm_client): include = elasticapm_client.include_paths_re exclude = elasticapm_client.exclude_paths_re frame1 = Mock(f_code=Mock(co_filename="/a/b/c/d.py")) frame2 = Mock(f_code=Mock(co_filename="/a/b/c/d/e.py")) frame3 = Mock(f_code=Mock(co_filename="/c/d/e.py")) frame4 = Mock(f_code=Mock(co_filename="/c/e.py")) info1 = stacks.get_frame_info(frame1, 1, False, False, include_paths_re=include, exclude_paths_re=exclude) info2 = stacks.get_frame_info(frame2, 1, False, False, include_paths_re=include, exclude_paths_re=exclude) info3 = stacks.get_frame_info(frame3, 1, False, False, include_paths_re=include, exclude_paths_re=exclude) info4 = stacks.get_frame_info(frame4, 1, False, False, include_paths_re=include, exclude_paths_re=exclude) assert not info1["library_frame"] assert not info2["library_frame"] assert not info3["library_frame"] assert info4["library_frame"]
def test_get_frame_info(): frame = get_me_a_test_frame() frame_info = stacks.get_frame_info( frame, frame.f_lineno, library_frame_context_lines=5, in_app_frame_context_lines=5, with_locals=True ) assert frame_info["function"] == "get_me_a_test_frame" assert frame_info["filename"] == os.path.join("tests", "utils", "stacks", "__init__.py") assert frame_info["module"] == "tests.utils.stacks" assert frame_info["lineno"] == 6 assert frame_info["context_line"] == " return inspect.currentframe()" assert frame_info["vars"] == {"a_local_var": 42}
def test_get_frame_info(): frame = get_me_a_test_frame() frame_info = stacks.get_frame_info(frame, frame.f_lineno, with_locals=True, with_source_context=True) assert frame_info['function'] == 'get_me_a_test_frame' assert frame_info['filename'] == 'tests/utils/stacks/__init__.py' assert frame_info['module'] == 'tests.utils.stacks' assert frame_info['lineno'] == 6 assert frame_info['context_line'] == ' return inspect.currentframe()' assert frame_info['vars'] == {'a_local_var': 42}
def iterate_with_template_sources( frames, with_locals=True, library_frame_context_lines=None, in_app_frame_context_lines=None, include_paths_re=None, exclude_paths_re=None, locals_processor_func=None, ): template = None for f in frames: try: frame, lineno = f except ValueError: # TODO how can we possibly get anything besides a (frame, lineno) tuple here??? logging.getLogger("elasticapm").error( "Malformed list of frames. Frames may be missing in Kibana.") break f_code = getattr(frame, "f_code", None) if f_code: function_name = frame.f_code.co_name if function_name == "render": renderer = getattr(frame, "f_locals", {}).get("self") if renderer and isinstance(renderer, Node): if getattr(renderer, "token", None) is not None: if hasattr(renderer, "source"): # up to Django 1.8 yield { "lineno": renderer.token.lineno, "filename": renderer.source[0].name } else: template = {"lineno": renderer.token.lineno} # Django 1.9 doesn't have the origin on the Node instance, # so we have to get it a bit further down the stack from the # Template instance elif renderer and isinstance(renderer, Template): if template and getattr(renderer, "origin", None): template["filename"] = renderer.origin.name yield template template = None yield get_frame_info( frame, lineno, library_frame_context_lines=library_frame_context_lines, in_app_frame_context_lines=in_app_frame_context_lines, with_locals=with_locals, include_paths_re=include_paths_re, exclude_paths_re=exclude_paths_re, locals_processor_func=locals_processor_func, )
def test_get_frame_info(): frame = get_me_a_test_frame() frame_info = stacks.get_frame_info( frame, frame.f_lineno, library_frame_context_lines=5, in_app_frame_context_lines=5, with_locals=True, ) assert frame_info['function'] == 'get_me_a_test_frame' assert frame_info['filename'] == os.path.join('tests', 'utils', 'stacks', '__init__.py') assert frame_info['module'] == 'tests.utils.stacks' assert frame_info['lineno'] == 6 assert frame_info['context_line'] == ' return inspect.currentframe()' assert frame_info['vars'] == {'a_local_var': 42}
def iterate_with_template_sources( frames, with_locals=True, library_frame_context_lines=None, in_app_frame_context_lines=None, include_paths_re=None, exclude_paths_re=None, locals_processor_func=None, ): template = None for frame, lineno in frames: f_code = getattr(frame, "f_code", None) if f_code: function_name = frame.f_code.co_name if function_name == "render": renderer = getattr(frame, "f_locals", {}).get("self") if renderer and isinstance(renderer, Node): if getattr(renderer, "token", None) is not None: if hasattr(renderer, "source"): # up to Django 1.8 yield { "lineno": renderer.token.lineno, "filename": renderer.source[0].name } else: template = {"lineno": renderer.token.lineno} # Django 1.9 doesn't have the origin on the Node instance, # so we have to get it a bit further down the stack from the # Template instance elif renderer and isinstance(renderer, Template): if template and getattr(renderer, "origin", None): template["filename"] = renderer.origin.name yield template template = None yield get_frame_info( frame, lineno, library_frame_context_lines=library_frame_context_lines, in_app_frame_context_lines=in_app_frame_context_lines, with_locals=with_locals, include_paths_re=include_paths_re, exclude_paths_re=exclude_paths_re, locals_processor_func=locals_processor_func, )
def bench_iter_stack_frames(): for frame, lineno in iter_stack_frames(): info = get_frame_info(frame, lineno)