-
Notifications
You must be signed in to change notification settings - Fork 5
/
action_profiler.rb
52 lines (43 loc) · 1.61 KB
/
action_profiler.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
require 'ruby-prof'
require 'set'
module ActionController
module ActionProfiler
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
# Add an around_filter :action_profiler to ApplicationController. Examples:
#
# action_profiler :if => lambda { |c| c.request.subdomains.first == 'live' }
#
# PROFILER_IPS = ['127.0.0.1']
# action_profiler :if => lambda { |c| PROFILER_IPS.include?(c.request.remote_ip) }
def action_profiler(options = {})
around_filter :action_profiler, options
end
end
protected
MODES = %w(process_time wall_time cpu_time allocations memory gc_runs gc_time).to_set
def action_profiler(&block)
if !RubyProf.running? && mode = params[:profile]
if MODES.include?(mode)
RubyProf.measure_mode = RubyProf.const_get(mode.upcase)
end
result = RubyProf.profile(&block)
if response.body.is_a?(String)
min_percent = (params[:profile_percent] || 0.01).to_f
output = StringIO.new
RubyProf::CallTreePrinter.new(result).print(output, :min_percent => min_percent)
response.body.replace(output.string)
response.status = 200
response.location = nil
response.headers['Content-Length'] = response.body.size
response.headers['Content-Type'] = 'application/octet-stream'
response.headers['Content-Disposition'] = %(attachment; filename="#{File.basename(request.path)}.#{mode}.tree")
end
else
yield
end
end
end
end