class RubyProf::CallStackPrinter
prints a HTML visualization of the call tree
Public Instance Methods
application()
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 162 def application @options[:application] || $PROGRAM_NAME end
arguments()
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 166 def arguments ARGV.join(' ') end
base64_image()
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 208 def base64_image file = open_asset('call_stack_printer.png') Base64.encode64(file).gsub(/\n/, '') end
color(p)
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 149 def color(p) case i = p.to_i when 0..5 "01" when 5..10 "05" when 100 "9" else "#{i/10}" end end
dump(ci)
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 145 def dump(ci) $stderr.printf "%s/%d t:%f s:%f w:%f \n", ci, ci.object_id, ci.total_time, ci.self_time, ci.wait_time end
expansion()
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 178 def expansion @options[:expansion] || 10.0 end
graph_link(call_info)
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 126 def graph_link(call_info) total_calls = call_info.target.call_infos.inject(0){|t, ci| t += ci.called} href = "#{@graph_html}##{method_href(call_info.target)}" totals = @graph_html ? "<a href='#{href}'>#{total_calls}</a>" : total_calls.to_s "[#{call_info.called} calls, #{totals} total]" end
link(call_info)
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 112 def link(call_info) method = call_info.target file = File.expand_path(method.source_file) if file =~ /\/ruby_runtime$/ h(name(call_info)) else if RUBY_PLATFORM =~ /darwin/ "<a href=\"txmt://open?url=file://#{file}&line=#{method.line}\">#{h(name(call_info))}</a>" else "<a href=\"file://#{file}##{method.line}\">#{h(name(call_info))}</a>" end end end
method_href(method)
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 133 def method_href(method) h(method.full_name.gsub(/[><#\.\?=:]/,"_") + "_" + @current_thread_id.to_s) end
name(call_info)
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 107 def name(call_info) method = call_info.target method.full_name end
open_asset(file)
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 198 def open_asset(file) path = File.join(File.expand_path('../../assets', __FILE__), file) File.open(path, 'rb').read end
print(output = STDOUT, options = {})
click to toggle source
Specify print options.
options - Hash table
:min_percent - Number 0 to 100 that specifes the minimum %self (the methods self time divided by the overall total time) that a method must take for it to be printed out in the report. Default value is 0. :print_file - True or false. Specifies if a method's source file should be printed. Default value if false. :threshold - a float from 0 to 100 that sets the threshold of results displayed. Default value is 1.0 :title - a String to overide the default "ruby-prof call tree" title of the report. :expansion - a float from 0 to 100 that sets the threshold of results that are expanded, if the percent_total exceeds it. Default value is 10.0 :application - a String to overide the name of the application, as it appears on the report.
# File lib/ruby-prof/printers/call_stack_printer.rb, line 38 def print(output = STDOUT, options = {}) @output = output setup_options(options) if @graph_html = options.delete(:graph) @graph_html = "file://" + @graph_html if @graph_html[0]=="/" end print_header @overall_threads_time = @result.threads.inject(0) do |val, thread| val += thread.total_time end @result.threads.each do |thread| @current_thread_id = thread.fiber_id @overall_time = thread.total_time thread_info = "Thread: #{thread.id}" thread_info << ", Fiber: #{thread.fiber_id}" unless thread.id == thread.fiber_id thread_info << " (#{"%4.2f%%" % ((@overall_time/@overall_threads_time)*100)} ~ #{@overall_time})" @output.print "<div class=\"thread\">#{thread_info}</div>" @output.print "<ul name=\"thread\">" thread.methods.each do |m| # $stderr.print m.dump next unless m.root? m.call_infos.each do |ci| next unless ci.root? print_stack ci, thread.total_time end end @output.print "</ul>" end print_footer end
print_commands()
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 227 def print_commands @output.puts <<-"end_commands" <div id=\"commands\"> <span style=\"font-size: 11pt; font-weight: bold;\">Threshold:</span> <input value=\"#{h threshold}\" size=\"3\" id=\"threshold\" type=\"text\"> <input value=\"Apply\" onclick=\"setThreshold();\" type=\"submit\"> <input value=\"Expand All\" onclick=\"expandAll(event);\" type=\"submit\"> <input value=\"Collapse All\" onclick=\"collapseAll(event);\" type=\"submit\"> <input value=\"Show Help\" onclick=\"toggleHelp(this);\" type=\"submit\"> </div> end_commands end
print_css()
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 203 def print_css html = open_asset('call_stack_printer.css.html') @output.puts html.gsub('%s', base64_image) end
print_header()
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 182 def print_header @output.puts "<html><head>" @output.puts '<meta http-equiv="content-type" content="text/html; charset=utf-8">' @output.puts "<title>#{h title}</title>" print_css print_java_script @output.puts '</head><body><div style="display: inline-block;">' print_title_bar print_commands print_help end
print_help()
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 240 def print_help @output.puts <<-'end_help' <div style="display: none;" id="help"> • Enter a decimal value <i>d</i> into the threshold field and click "Apply" to hide all nodes marked with time values lower than <i>d</i>.<br> • Click on "Expand All" for full tree expansion.<br> • Click on "Collapse All" to show only top level nodes.<br> • Use a, s, d, w as in Quake or Urban Terror to navigate the tree.<br> • Use f and b to navigate the tree in preorder forward and backwards.<br> • Use x to toggle visibility of a subtree.<br> • Use * to expand/collapse a whole subtree.<br> • Use h to navigate to thread root.<br> • Use n and p to navigate between threads.<br> • Click on background to move focus to a subtree.<br> </div> end_help end
print_java_script()
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 213 def print_java_script html = open_asset('call_stack_printer.js.html') @output.puts html end
print_stack(call_info, parent_time)
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 74 def print_stack(call_info, parent_time) total_time = call_info.total_time percent_parent = (total_time/parent_time)*100 percent_total = (total_time/@overall_time)*100 return unless percent_total > min_percent color = self.color(percent_total) kids = call_info.children visible = percent_total >= threshold expanded = percent_total >= expansion display = visible ? "block" : "none" @output.print "<li class=\"color#{color}\" style=\"display:#{display}\">" if kids.empty? @output.print "<a href=\"#\" class=\"toggle empty\" ></a>" else visible_children = kids.any?{|ci| (ci.total_time/@overall_time)*100 >= threshold} image = visible_children ? (expanded ? "minus" : "plus") : "empty" @output.print "<a href=\"#\" class=\"toggle #{image}\" ></a>" end @output.printf "<span> %4.2f%% (%4.2f%%) %s %s</span>\n", percent_total, percent_parent, link(call_info), graph_link(call_info) unless kids.empty? if expanded @output.print "<ul>" else @output.print '<ul style="display:none">' end kids.sort_by{|c| -c.total_time}.each do |callinfo| print_stack callinfo, total_time end @output.print "</ul>" end @output.print "</li>" end
print_title_bar()
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 218 def print_title_bar @output.puts <<-"end_title_bar" <div id="titlebar"> Call tree for application <b>#{h application} #{h arguments}</b><br/> Generated on #{Time.now} with options #{h @options.inspect}<br/> </div> end_title_bar end
sum(a)
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 141 def sum(a) a.inject(0.0){|s,t| s+=t} end
threshold()
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 174 def threshold @options[:threshold] || 1.0 end
title()
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 170 def title @title ||= @options.delete(:title) || "ruby-prof call tree" end
total_time(call_infos)
click to toggle source
# File lib/ruby-prof/printers/call_stack_printer.rb, line 137 def total_time(call_infos) sum(call_infos.map{|ci| ci.total_time}) end