ruby-prof 1.1.0-x64-mingw32 → 1.4.2-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES +48 -1
- data/Rakefile +2 -14
- data/bin/ruby-prof +100 -152
- data/ext/ruby_prof/extconf.rb +8 -28
- data/ext/ruby_prof/rp_aggregate_call_tree.c +59 -0
- data/ext/ruby_prof/rp_aggregate_call_tree.h +13 -0
- data/ext/ruby_prof/rp_allocation.c +67 -59
- data/ext/ruby_prof/rp_allocation.h +3 -3
- data/ext/ruby_prof/rp_call_tree.c +369 -0
- data/ext/ruby_prof/rp_call_tree.h +43 -0
- data/ext/ruby_prof/rp_call_trees.c +288 -0
- data/ext/ruby_prof/rp_call_trees.h +28 -0
- data/ext/ruby_prof/rp_measure_allocations.c +12 -14
- data/ext/ruby_prof/rp_measure_process_time.c +12 -14
- data/ext/ruby_prof/rp_measure_wall_time.c +17 -15
- data/ext/ruby_prof/rp_measurement.c +47 -40
- data/ext/ruby_prof/rp_measurement.h +7 -7
- data/ext/ruby_prof/rp_method.c +116 -255
- data/ext/ruby_prof/rp_method.h +31 -39
- data/ext/ruby_prof/rp_profile.c +316 -303
- data/ext/ruby_prof/rp_profile.h +1 -3
- data/ext/ruby_prof/rp_stack.c +122 -106
- data/ext/ruby_prof/rp_stack.h +17 -20
- data/ext/ruby_prof/rp_thread.c +136 -111
- data/ext/ruby_prof/rp_thread.h +12 -9
- data/ext/ruby_prof/ruby_prof.c +27 -23
- data/ext/ruby_prof/ruby_prof.h +9 -0
- data/ext/ruby_prof/vc/ruby_prof.sln +8 -0
- data/ext/ruby_prof/vc/ruby_prof.vcxproj +22 -7
- data/lib/2.7/ruby_prof.so +0 -0
- data/lib/ruby-prof.rb +5 -5
- data/lib/ruby-prof/assets/call_stack_printer.html.erb +4 -7
- data/lib/ruby-prof/assets/graph_printer.html.erb +5 -6
- data/lib/ruby-prof/{call_info.rb → call_tree.rb} +6 -6
- data/lib/ruby-prof/call_tree_visitor.rb +36 -0
- data/lib/ruby-prof/compatibility.rb +0 -10
- data/lib/ruby-prof/measurement.rb +5 -2
- data/lib/ruby-prof/method_info.rb +3 -15
- data/lib/ruby-prof/printers/abstract_printer.rb +12 -2
- data/lib/ruby-prof/printers/call_info_printer.rb +12 -10
- data/lib/ruby-prof/printers/call_stack_printer.rb +20 -22
- data/lib/ruby-prof/printers/call_tree_printer.rb +1 -1
- data/lib/ruby-prof/printers/dot_printer.rb +3 -3
- data/lib/ruby-prof/printers/flat_printer.rb +3 -2
- data/lib/ruby-prof/printers/graph_printer.rb +4 -5
- data/lib/ruby-prof/printers/multi_printer.rb +2 -2
- data/lib/ruby-prof/profile.rb +8 -4
- data/lib/ruby-prof/rack.rb +51 -127
- data/lib/ruby-prof/thread.rb +3 -18
- data/lib/ruby-prof/version.rb +1 -1
- data/ruby-prof.gemspec +7 -0
- data/test/alias_test.rb +42 -45
- data/test/basic_test.rb +0 -86
- data/test/{call_info_visitor_test.rb → call_tree_visitor_test.rb} +6 -5
- data/test/call_trees_test.rb +66 -0
- data/test/exclude_methods_test.rb +17 -12
- data/test/fiber_test.rb +95 -39
- data/test/gc_test.rb +36 -42
- data/test/inverse_call_tree_test.rb +175 -0
- data/test/line_number_test.rb +67 -70
- data/test/marshal_test.rb +7 -13
- data/test/measure_allocations_test.rb +224 -234
- data/test/measure_allocations_trace_test.rb +224 -234
- data/test/measure_memory_trace_test.rb +814 -469
- data/test/measure_process_time_test.rb +0 -64
- data/test/measure_times.rb +2 -0
- data/test/measure_wall_time_test.rb +34 -58
- data/test/pause_resume_test.rb +19 -10
- data/test/prime.rb +1 -3
- data/test/prime_script.rb +6 -0
- data/test/printer_call_stack_test.rb +0 -1
- data/test/printer_call_tree_test.rb +0 -1
- data/test/printer_flat_test.rb +61 -30
- data/test/printer_graph_html_test.rb +0 -1
- data/test/printer_graph_test.rb +3 -4
- data/test/printers_test.rb +2 -2
- data/test/printing_recursive_graph_test.rb +1 -1
- data/test/profile_test.rb +16 -0
- data/test/rack_test.rb +0 -64
- data/test/recursive_test.rb +50 -54
- data/test/start_stop_test.rb +19 -19
- data/test/test_helper.rb +6 -17
- data/test/thread_test.rb +11 -11
- data/test/unique_call_path_test.rb +25 -95
- metadata +22 -11
- data/ext/ruby_prof/rp_call_info.c +0 -271
- data/ext/ruby_prof/rp_call_info.h +0 -35
- data/lib/2.6.5/ruby_prof.so +0 -0
- data/lib/ruby-prof/call_info_visitor.rb +0 -38
- data/test/parser_timings.rb +0 -24
@@ -17,11 +17,21 @@ module RubyProf
|
|
17
17
|
@output = nil
|
18
18
|
end
|
19
19
|
|
20
|
-
# Returns the min_percent of
|
20
|
+
# Returns the min_percent of time a method must take to be included in a profiling report
|
21
21
|
def min_percent
|
22
22
|
@options[:min_percent] || 0
|
23
23
|
end
|
24
24
|
|
25
|
+
# Returns the max_percent of time a method can take to be included in a profiling report
|
26
|
+
def max_percent
|
27
|
+
@options[:max_percent] || 100
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns the method to filter methods by (when using min_percent and max_percent)
|
31
|
+
def filter_by
|
32
|
+
@options[:filter_by] || :self_time
|
33
|
+
end
|
34
|
+
|
25
35
|
# Returns the time format used to show when a profile was run
|
26
36
|
def time_format
|
27
37
|
'%A, %B %-d at %l:%M:%S %p (%Z)'
|
@@ -89,7 +99,7 @@ module RubyProf
|
|
89
99
|
end
|
90
100
|
|
91
101
|
def print_header(thread)
|
92
|
-
@output << "Measure Mode: %s\n" %
|
102
|
+
@output << "Measure Mode: %s\n" % @result.measure_mode_string
|
93
103
|
@output << "Thread ID: %d\n" % thread.id
|
94
104
|
@output << "Fiber ID: %d\n" % thread.fiber_id unless thread.id == thread.fiber_id
|
95
105
|
@output << "Total: %0.6f\n" % thread.total_time
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module RubyProf
|
4
|
-
# Prints out the call graph based on
|
4
|
+
# Prints out the call graph based on CallTree instances. This
|
5
5
|
# is mainly for debugging purposes as it provides access into
|
6
6
|
# into RubyProf's internals.
|
7
7
|
#
|
@@ -19,6 +19,7 @@ module RubyProf
|
|
19
19
|
private
|
20
20
|
|
21
21
|
def print_header(thread)
|
22
|
+
@output << "----------------------------------------------------\n"
|
22
23
|
@output << "Thread ID: #{thread.id}\n"
|
23
24
|
@output << "Fiber ID: #{thread.fiber_id}\n"
|
24
25
|
@output << "Total Time: #{thread.total_time}\n"
|
@@ -27,18 +28,18 @@ module RubyProf
|
|
27
28
|
end
|
28
29
|
|
29
30
|
def print_methods(thread)
|
30
|
-
visitor =
|
31
|
+
visitor = CallTreeVisitor.new(thread.call_tree)
|
31
32
|
|
32
|
-
visitor.visit do |
|
33
|
+
visitor.visit do |call_tree, event|
|
33
34
|
if event == :enter
|
34
|
-
@output << " " *
|
35
|
-
@output <<
|
35
|
+
@output << " " * call_tree.depth
|
36
|
+
@output << call_tree.target.full_name
|
36
37
|
@output << " ("
|
37
|
-
@output << "tt:#{sprintf("%#{TIME_WIDTH}.2f",
|
38
|
-
@output << "st:#{sprintf("%#{TIME_WIDTH}.2f",
|
39
|
-
@output << "wt:#{sprintf("%#{TIME_WIDTH}.2f",
|
40
|
-
@output << "ct:#{sprintf("%#{TIME_WIDTH}.2f",
|
41
|
-
@output << "call:#{
|
38
|
+
@output << "tt:#{sprintf("%#{TIME_WIDTH}.2f", call_tree.total_time)}, "
|
39
|
+
@output << "st:#{sprintf("%#{TIME_WIDTH}.2f", call_tree.self_time)}, "
|
40
|
+
@output << "wt:#{sprintf("%#{TIME_WIDTH}.2f", call_tree.wait_time)}, "
|
41
|
+
@output << "ct:#{sprintf("%#{TIME_WIDTH}.2f", call_tree.children_time)}, "
|
42
|
+
@output << "call:#{call_tree.called}, "
|
42
43
|
@output << ")"
|
43
44
|
@output << "\n"
|
44
45
|
end
|
@@ -46,6 +47,7 @@ module RubyProf
|
|
46
47
|
end
|
47
48
|
|
48
49
|
def print_footer(thread)
|
50
|
+
@output << "\n" << "\n"
|
49
51
|
end
|
50
52
|
end
|
51
53
|
end
|
@@ -4,6 +4,7 @@ require 'erb'
|
|
4
4
|
require 'fileutils'
|
5
5
|
require 'base64'
|
6
6
|
require 'set'
|
7
|
+
require 'stringio'
|
7
8
|
|
8
9
|
module RubyProf
|
9
10
|
# Prints a HTML visualization of the call tree.
|
@@ -46,7 +47,6 @@ module RubyProf
|
|
46
47
|
def print(output = STDOUT, options = {})
|
47
48
|
setup_options(options)
|
48
49
|
output << @erb.result(binding)
|
49
|
-
a = 1
|
50
50
|
end
|
51
51
|
|
52
52
|
# :enddoc:
|
@@ -55,50 +55,49 @@ module RubyProf
|
|
55
55
|
@erb = ERB.new(self.template)
|
56
56
|
end
|
57
57
|
|
58
|
-
def print_stack(output, visited,
|
59
|
-
total_time =
|
58
|
+
def print_stack(output, visited, call_tree, parent_time)
|
59
|
+
total_time = call_tree.total_time
|
60
60
|
percent_parent = (total_time/parent_time)*100
|
61
61
|
percent_total = (total_time/@overall_time)*100
|
62
62
|
return unless percent_total > min_percent
|
63
63
|
color = self.color(percent_total)
|
64
|
-
kids = call_info.target.callees
|
65
64
|
visible = percent_total >= threshold
|
66
65
|
expanded = percent_total >= expansion
|
67
66
|
display = visible ? "block" : "none"
|
68
67
|
|
69
68
|
output << "<li class=\"color#{color}\" style=\"display:#{display}\">" << "\n"
|
70
69
|
|
71
|
-
if visited.include?(
|
70
|
+
if visited.include?(call_tree)
|
72
71
|
output << "<a href=\"#\" class=\"toggle empty\" ></a>" << "\n"
|
73
|
-
output << "<span>%s %s</span>" % [link(
|
72
|
+
output << "<span>%s %s</span>" % [link(call_tree.target, true), graph_link(call_tree)] << "\n"
|
74
73
|
else
|
75
|
-
visited <<
|
74
|
+
visited << call_tree
|
76
75
|
|
77
|
-
if
|
76
|
+
if call_tree.children.empty?
|
78
77
|
output << "<a href=\"#\" class=\"toggle empty\" ></a>" << "\n"
|
79
78
|
else
|
80
|
-
visible_children =
|
79
|
+
visible_children = call_tree.children.any?{|ci| (ci.total_time/@overall_time)*100 >= threshold}
|
81
80
|
image = visible_children ? (expanded ? "minus" : "plus") : "empty"
|
82
81
|
output << "<a href=\"#\" class=\"toggle #{image}\" ></a>" << "\n"
|
83
82
|
end
|
84
83
|
output << "<span>%4.2f%% (%4.2f%%) %s %s</span>" % [percent_total, percent_parent,
|
85
|
-
link(
|
84
|
+
link(call_tree.target, false), graph_link(call_tree)] << "\n"
|
86
85
|
|
87
|
-
unless
|
86
|
+
unless call_tree.children.empty?
|
88
87
|
output << (expanded ? '<ul>' : '<ul style="display:none">') << "\n"
|
89
|
-
|
90
|
-
print_stack(output, visited,
|
88
|
+
call_tree.children.sort_by{|c| -c.total_time}.each do |child_call_tree|
|
89
|
+
print_stack(output, visited, child_call_tree, total_time)
|
91
90
|
end
|
92
91
|
output << '</ul>' << "\n"
|
93
92
|
end
|
94
93
|
|
95
|
-
visited.delete(
|
94
|
+
visited.delete(call_tree)
|
96
95
|
end
|
97
96
|
output << '</li>' << "\n"
|
98
97
|
end
|
99
98
|
|
100
|
-
def name(
|
101
|
-
method =
|
99
|
+
def name(call_tree)
|
100
|
+
method = call_tree.target
|
102
101
|
method.full_name
|
103
102
|
end
|
104
103
|
|
@@ -112,19 +111,18 @@ module RubyProf
|
|
112
111
|
end
|
113
112
|
end
|
114
113
|
|
115
|
-
def graph_link(
|
116
|
-
total_calls =
|
117
|
-
href = "#{method_href(call_info.target)}"
|
114
|
+
def graph_link(call_tree)
|
115
|
+
total_calls = call_tree.target.called
|
118
116
|
totals = total_calls.to_s
|
119
|
-
"[#{
|
117
|
+
"[#{call_tree.called} calls, #{totals} total]"
|
120
118
|
end
|
121
119
|
|
122
120
|
def method_href(method)
|
123
121
|
h(method.full_name.gsub(/[><#\.\?=:]/,"_"))
|
124
122
|
end
|
125
123
|
|
126
|
-
def total_time(
|
127
|
-
sum(
|
124
|
+
def total_time(call_trees)
|
125
|
+
sum(call_trees.map{|ci| ci.total_time})
|
128
126
|
end
|
129
127
|
|
130
128
|
def sum(a)
|
@@ -137,7 +137,7 @@ module RubyProf
|
|
137
137
|
output << "#{method.line} #{convert(method.self_time)}\n"
|
138
138
|
|
139
139
|
# Now print out all the children methods
|
140
|
-
method.callees.each do |callee|
|
140
|
+
method.call_trees.callees.each do |callee|
|
141
141
|
output << "cfl=#{file(callee.target)}\n"
|
142
142
|
output << "cfn=#{self.calltree_name(callee.target)}\n"
|
143
143
|
output << "calls=#{callee.called} #{callee.line}\n"
|
@@ -114,12 +114,12 @@ module RubyProf
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def print_edges(total_time, method)
|
117
|
-
method.callers.sort_by(&:total_time).reverse.each do |
|
118
|
-
target_percentage = (
|
117
|
+
method.call_trees.callers.sort_by(&:total_time).reverse.each do |call_tree|
|
118
|
+
target_percentage = (call_tree.target.total_time / total_time) * 100.0
|
119
119
|
next if target_percentage < min_percent
|
120
120
|
|
121
121
|
# Get children method
|
122
|
-
puts "#{dot_id(method)} -> #{dot_id(
|
122
|
+
puts "#{dot_id(method)} -> #{dot_id(call_tree.target)} [label=\"#{call_tree.called}/#{call_tree.target.called}\" fontsize=10 fontcolor=#{EDGE_COLOR}];"
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
@@ -29,8 +29,9 @@ module RubyProf
|
|
29
29
|
|
30
30
|
sum = 0
|
31
31
|
methods.each do |method|
|
32
|
-
|
33
|
-
next if
|
32
|
+
percent = (method.send(filter_by) / total_time) * 100
|
33
|
+
next if percent < min_percent
|
34
|
+
next if percent > max_percent
|
34
35
|
|
35
36
|
sum += method.self_time
|
36
37
|
#self_time_called = method.called > 0 ? method.self_time/method.called : 0
|
@@ -25,7 +25,7 @@ module RubyProf
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def print_header(thread)
|
28
|
-
@output << "Measure Mode: %s\n" %
|
28
|
+
@output << "Measure Mode: %s\n" % @result.measure_mode_string
|
29
29
|
@output << "Thread ID: #{thread.id}\n"
|
30
30
|
@output << "Fiber ID: #{thread.fiber_id}\n"
|
31
31
|
@output << "Total Time: #{thread.total_time}\n"
|
@@ -78,8 +78,7 @@ module RubyProf
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def print_parents(thread, method)
|
81
|
-
|
82
|
-
method.callers.sort_by(&:total_time).each do |caller|
|
81
|
+
method.call_trees.callers.sort_by(&:total_time).each do |caller|
|
83
82
|
@output << " " * 2 * PERCENTAGE_WIDTH
|
84
83
|
@output << sprintf("%#{TIME_WIDTH}.3f", caller.total_time)
|
85
84
|
@output << sprintf("%#{TIME_WIDTH}.3f", caller.self_time)
|
@@ -88,13 +87,13 @@ module RubyProf
|
|
88
87
|
|
89
88
|
call_called = "#{caller.called}/#{method.called}"
|
90
89
|
@output << sprintf("%#{CALL_WIDTH}s", call_called)
|
91
|
-
@output << sprintf(" %s", caller.parent.full_name)
|
90
|
+
@output << sprintf(" %s", caller.parent.target.full_name)
|
92
91
|
@output << "\n"
|
93
92
|
end
|
94
93
|
end
|
95
94
|
|
96
95
|
def print_children(method)
|
97
|
-
method.callees.sort_by(&:total_time).reverse.each do |child|
|
96
|
+
method.call_trees.callees.sort_by(&:total_time).reverse.each do |child|
|
98
97
|
# Get children method
|
99
98
|
|
100
99
|
@output << " " * 2 * PERCENTAGE_WIDTH
|
@@ -12,7 +12,7 @@ module RubyProf
|
|
12
12
|
@graph_html_printer = GraphHtmlPrinter.new(result) if printers.include?(:graph_html)
|
13
13
|
|
14
14
|
@tree_printer = CallTreePrinter.new(result) if printers.include?(:tree)
|
15
|
-
@call_info_printer = CallInfoPrinter.new(result) if printers.include?(:
|
15
|
+
@call_info_printer = CallInfoPrinter.new(result) if printers.include?(:call_tree)
|
16
16
|
|
17
17
|
@stack_printer = CallStackPrinter.new(result) if printers.include?(:stack)
|
18
18
|
@dot_printer = DotPrinter.new(result) if printers.include?(:dot)
|
@@ -58,7 +58,7 @@ module RubyProf
|
|
58
58
|
|
59
59
|
# the name of the callinfo profile file
|
60
60
|
def call_info_report
|
61
|
-
"#{@directory}/#{@profile}.
|
61
|
+
"#{@directory}/#{@profile}.call_tree.txt"
|
62
62
|
end
|
63
63
|
|
64
64
|
# the name of the callgrind profile file
|
data/lib/ruby-prof/profile.rb
CHANGED
@@ -7,10 +7,14 @@ module RubyProf
|
|
7
7
|
# :nodoc:
|
8
8
|
def measure_mode_string
|
9
9
|
case self.measure_mode
|
10
|
-
when WALL_TIME
|
11
|
-
|
12
|
-
when
|
13
|
-
|
10
|
+
when WALL_TIME
|
11
|
+
"wall_time"
|
12
|
+
when PROCESS_TIME
|
13
|
+
"process_time"
|
14
|
+
when ALLOCATIONS
|
15
|
+
"allocations"
|
16
|
+
when MEMORY
|
17
|
+
"memory"
|
14
18
|
end
|
15
19
|
end
|
16
20
|
|
data/lib/ruby-prof/rack.rb
CHANGED
@@ -5,43 +5,37 @@ module Rack
|
|
5
5
|
class RubyProf
|
6
6
|
def initialize(app, options = {})
|
7
7
|
@app = app
|
8
|
+
@options = options
|
9
|
+
@options[:min_percent] ||= 1
|
8
10
|
|
9
|
-
options[:
|
11
|
+
@tmpdir = options[:path] || Dir.tmpdir
|
12
|
+
FileUtils.mkdir_p(@tmpdir)
|
10
13
|
|
11
|
-
options[:
|
12
|
-
|
14
|
+
@printer_klasses = @options[:printers] || {::RubyProf::FlatPrinter => 'flat.txt',
|
15
|
+
::RubyProf::GraphPrinter => 'graph.txt',
|
16
|
+
::RubyProf::GraphHtmlPrinter => 'graph.html',
|
17
|
+
::RubyProf::CallStackPrinter => 'call_stack.html'}
|
13
18
|
|
14
19
|
@skip_paths = options[:skip_paths] || [%r{^/assets}, %r{\.(css|js|png|jpeg|jpg|gif)$}]
|
15
20
|
@only_paths = options[:only_paths]
|
16
|
-
|
17
|
-
@max_requests = options[:max_requests]
|
18
|
-
|
19
|
-
@options = options
|
20
21
|
end
|
21
22
|
|
22
23
|
def call(env)
|
23
24
|
request = Rack::Request.new(env)
|
24
25
|
|
25
26
|
if should_profile?(request.path)
|
26
|
-
profiler.resume
|
27
27
|
begin
|
28
|
-
result =
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
result = nil
|
29
|
+
data = ::RubyProf::Profile.profile(profiling_options) do
|
30
|
+
result = @app.call(env)
|
31
|
+
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
nil
|
36
|
-
else
|
37
|
-
request.path.gsub('/', '-')[1..-1]
|
38
|
-
end
|
33
|
+
path = request.path.gsub('/', '-')
|
34
|
+
path.slice!(0)
|
39
35
|
|
40
|
-
|
41
|
-
|
36
|
+
print(data, path)
|
37
|
+
result
|
42
38
|
end
|
43
|
-
|
44
|
-
result
|
45
39
|
else
|
46
40
|
@app.call(env)
|
47
41
|
end
|
@@ -49,123 +43,53 @@ module Rack
|
|
49
43
|
|
50
44
|
private
|
51
45
|
|
52
|
-
|
53
|
-
|
54
|
-
@options = options
|
55
|
-
|
56
|
-
@profile = ::RubyProf::Profile.new(profiling_options)
|
57
|
-
@profile.start
|
58
|
-
@profile.pause
|
59
|
-
|
60
|
-
@printer_klasses = options[:printers] || default_printers
|
61
|
-
|
62
|
-
@tmpdir = options[:path]
|
63
|
-
|
64
|
-
@max_requests = options[:max_requests] || 1
|
65
|
-
@requests_count = 0
|
46
|
+
def should_profile?(path)
|
47
|
+
return false if paths_match?(path, @skip_paths)
|
66
48
|
|
67
|
-
|
68
|
-
|
69
|
-
# ongoing profile is not lost if the process shuts down before the
|
70
|
-
# max request count is reached
|
71
|
-
ObjectSpace.define_finalizer(self, proc { print! })
|
72
|
-
end
|
49
|
+
@only_paths ? paths_match?(path, @only_paths) : true
|
50
|
+
end
|
73
51
|
|
74
|
-
|
75
|
-
|
76
|
-
|
52
|
+
def paths_match?(path, paths)
|
53
|
+
paths.any? { |skip_path| skip_path =~ path }
|
54
|
+
end
|
77
55
|
|
78
|
-
|
79
|
-
|
80
|
-
|
56
|
+
def profiling_options
|
57
|
+
options = {}
|
58
|
+
options[:measure_mode] = ::RubyProf.measure_mode
|
59
|
+
options[:exclude_threads] =
|
60
|
+
if @options[:ignore_existing_threads]
|
61
|
+
Thread.list.select{|t| t != Thread.current}
|
62
|
+
else
|
63
|
+
::RubyProf.exclude_threads
|
64
|
+
end
|
65
|
+
if @options[:request_thread_only]
|
66
|
+
options[:include_threads] = [Thread.current]
|
81
67
|
end
|
82
|
-
|
83
|
-
|
84
|
-
@requests_count >= @max_requests
|
68
|
+
if @options[:merge_fibers]
|
69
|
+
options[:merge_fibers] = true
|
85
70
|
end
|
71
|
+
options
|
72
|
+
end
|
86
73
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
data = @profile.stop
|
91
|
-
|
92
|
-
prefix ||= "multi-requests-#{@requests_count}"
|
93
|
-
|
94
|
-
@printer_klasses.each do |printer_klass, base_name|
|
95
|
-
printer = printer_klass.new(data)
|
96
|
-
|
97
|
-
if base_name.respond_to?(:call)
|
98
|
-
base_name = base_name.call
|
99
|
-
end
|
74
|
+
def print(data, path)
|
75
|
+
@printer_klasses.each do |printer_klass, base_name|
|
76
|
+
printer = printer_klass.new(data)
|
100
77
|
|
101
|
-
|
102
|
-
|
103
|
-
printer.print(@options.merge(:profile => "#{prefix}-#{base_name}"))
|
104
|
-
else
|
105
|
-
file_name = ::File.join(@tmpdir, "#{prefix}-#{base_name}")
|
106
|
-
::File.open(file_name, 'wb') do |file|
|
107
|
-
printer.print(file, @options)
|
108
|
-
end
|
109
|
-
end
|
78
|
+
if base_name.respond_to?(:call)
|
79
|
+
base_name = base_name.call
|
110
80
|
end
|
111
81
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
options[:exclude_threads] =
|
121
|
-
if @options[:ignore_existing_threads]
|
122
|
-
Thread.list.select{|t| t != Thread.current}
|
123
|
-
else
|
124
|
-
::RubyProf.exclude_threads
|
82
|
+
if printer_klass == ::RubyProf::MultiPrinter
|
83
|
+
printer.print(@options.merge(:profile => "#{path}-#{base_name}"))
|
84
|
+
elsif printer_klass == ::RubyProf::CallTreePrinter
|
85
|
+
printer.print(@options.merge(:profile => "#{path}-#{base_name}"))
|
86
|
+
else
|
87
|
+
file_name = ::File.join(@tmpdir, "#{path}-#{base_name}")
|
88
|
+
::File.open(file_name, 'wb') do |file|
|
89
|
+
printer.print(file, @options)
|
125
90
|
end
|
126
|
-
if @options[:request_thread_only]
|
127
|
-
options[:include_threads] = [Thread.current]
|
128
91
|
end
|
129
|
-
options
|
130
|
-
end
|
131
|
-
|
132
|
-
def default_printers
|
133
|
-
{::RubyProf::FlatPrinter => 'flat.txt',
|
134
|
-
::RubyProf::GraphPrinter => 'graph.txt',
|
135
|
-
::RubyProf::GraphHtmlPrinter => 'graph.html',
|
136
|
-
::RubyProf::CallStackPrinter => 'call_stack.html'}
|
137
92
|
end
|
138
93
|
end
|
139
|
-
|
140
|
-
def profiler
|
141
|
-
if aggregate_requests?
|
142
|
-
@@_shared_profiler ||= RackProfiler.new(@options)
|
143
|
-
else
|
144
|
-
@_profiler ||= RackProfiler.new(@options)
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
def delete_profiler!
|
149
|
-
if aggregate_requests?
|
150
|
-
@@_shared_profiler.print! if @@_shared_profiler
|
151
|
-
@@_shared_profiler = nil
|
152
|
-
else
|
153
|
-
@_profiler = nil
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
def aggregate_requests?
|
158
|
-
!@max_requests.nil?
|
159
|
-
end
|
160
|
-
|
161
|
-
def should_profile?(path)
|
162
|
-
return false if paths_match?(path, @skip_paths)
|
163
|
-
|
164
|
-
@only_paths ? paths_match?(path, @only_paths) : true
|
165
|
-
end
|
166
|
-
|
167
|
-
def paths_match?(path, paths)
|
168
|
-
paths.any? { |skip_path| skip_path =~ path }
|
169
|
-
end
|
170
94
|
end
|
171
95
|
end
|