Updated version of this Gist is available from https://bitbucket.org/techtonik/xtrace
Created
October 19, 2011 20:55
-
-
Save techtonik/1299647 to your computer and use it in GitHub Desktop.
Python - Get function trace in Xdebug format - https://bitbucket.org/techtonik/xtrace
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import datetime | |
import inspect | |
import os | |
import sys | |
oldfunc = None #: save old trace function if any | |
def start(): | |
global oldfunc | |
oldfunc = sys.gettrace() | |
print datetime.datetime.now().strftime('TRACE START [%Y-%m-%d %H:%M:%S]') | |
sys.settrace(function_trace_xdebug) | |
def stop(): | |
global oldfunc | |
print datetime.datetime.now().strftime('TRACE END [%Y-%m-%d %H:%M:%S]') | |
sys.settrace(oldfunc) | |
trace_cwd = os.getcwd() #: current directory is stripped from filenames | |
trace_depth = 0 | |
trace_filter = ['/usr/lib/python'] | |
# [ ] check what will happen with depth when trace started deep inside and | |
# moved out (also check for Xdebug) | |
def function_trace_xdebug(frame, event, arg): | |
'''print function trace in default xdebug human-readable format | |
http://xdebug.org/docs/execution_trace''' | |
global trace_depth | |
if event == 'call': # generated before any function call | |
def strip_cwd(filename): | |
global trace_cwd | |
if trace_cwd and filename.startswith(trace_cwd): | |
return os.path.normpath(filename.replace(trace_cwd, '.', 1)) | |
return filename | |
trace_depth += 1 | |
funcname = frame.f_code.co_name | |
filename = strip_cwd(frame.f_code.co_filename) | |
lineno = frame.f_lineno | |
param = '' | |
if funcname == '<module>': | |
funcname = '<%s>' % inspect.getmodule(frame.f_code).__name__ | |
# by analogy with PHP require() trace in Xdebug, the format is | |
# <mod.name>(module_location) file_imported_from:line | |
param = filename | |
filename = strip_cwd(frame.f_back.f_code.co_filename) | |
# skip paths mentioned in trace_filter | |
if (funcname[0] is not '<' # not module import | |
and any( [filename.startswith(x) for x in trace_filter] )): | |
pass | |
else: | |
print '%*s-> %s(%s) %s:%s' % (trace_depth*2, '', funcname, param, | |
filename, lineno) | |
return function_trace_xdebug | |
elif event == 'return': | |
trace_depth -= 1 | |
else: | |
pass #print 'TRACE: UNKNOWN %s EVENT WITH ARG %s' % (event, arg) | |
return | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
f30994 - add filename and lineno info, add module name for entries
c598d4 - strip current working directory from filenames
7590f2 - wrap actual module name in <>, provide path to module as a param, and mention the line module is imported from in final argument
36b94b - convert to a module