Skip to content

Instantly share code, notes, and snippets.

@jagthedrummer
Created February 15, 2017 19:41
Show Gist options
  • Save jagthedrummer/34184b49277dc2fb379421a8a797ccaf to your computer and use it in GitHub Desktop.
Save jagthedrummer/34184b49277dc2fb379421a8a797ccaf to your computer and use it in GitHub Desktop.
Trace and graph execution path for a method
# Quick and dirty code to drop into a Rails controller to trace execution through code paths and graph it.
# Changing the conditional on line 10 allows you to tweak which classes/directories you see int he graph.
# The trace_calls method could also be used outside a controller like: trace_calls{ do_some_method }
around_action :trace_calls
def trace_calls
g = GraphViz.new( :G, :type => :digraph )
nodes = []
trace = TracePoint.new(:call,:return) do |tp|
if tp.path =~ /clickfunnels\/userpages/ #|| tp.path =~ /clickfunnels\/app/ #|| tp.path =~ /clickfunnels\/lib/
method_name = "#{tp.defined_class}##{tp.method_id}"
puts "nodes = #{nodes.length}"
if tp.event == :call
new_node = g.add_nodes(method_name)
puts "call #{method_name}"
old_node = nodes.last
if new_node.present? && old_node.present?
g.add_edges(old_node[:node], new_node)
end
nodes << { method_name: method_name, node: new_node }
elsif tp.event == :return
puts "return #{method_name}"
old_node = nodes.last
prev_node = nodes[-2]
if old_node[:method_name] == method_name
nodes.pop
end
end
end
end
trace.enable
yield
trace.disable
g.output( :png => "hello_world.png" )
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment