tuttle 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/app/controllers/tuttle/active_model_serializers_controller.rb +26 -0
- data/app/controllers/tuttle/active_support_controller.rb +26 -0
- data/app/controllers/tuttle/cancancan_controller.rb +1 -0
- data/app/controllers/tuttle/gems_controller.rb +4 -0
- data/app/controllers/tuttle/home_controller.rb +1 -3
- data/app/controllers/tuttle/performance_tuning_controller.rb +14 -0
- data/app/controllers/tuttle/rails_controller.rb +20 -18
- data/app/controllers/tuttle/request_controller.rb +16 -0
- data/app/controllers/tuttle/ruby_controller.rb +2 -0
- data/app/helpers/tuttle/application_helper.rb +8 -0
- data/app/views/layouts/tuttle/application.html.erb +22 -7
- data/app/views/tuttle/active_model_serializers/index.html.erb +86 -0
- data/app/views/tuttle/active_model_serializers/index9.html.erb +68 -0
- data/app/views/tuttle/active_support/dependencies.html.erb +72 -0
- data/app/views/tuttle/active_support/index.html.erb +69 -0
- data/app/views/tuttle/{rails → active_support}/inflectors.html.erb +0 -0
- data/app/views/tuttle/active_support/time_zones.html.erb +24 -0
- data/app/views/tuttle/cancancan/rule_tester.html.erb +1 -20
- data/app/views/tuttle/devise/index.html.erb +62 -9
- data/app/views/tuttle/gems/get_process_mem.html.erb +92 -0
- data/app/views/tuttle/gems/other.html.erb +102 -0
- data/app/views/tuttle/home/index.html.erb +1 -1
- data/app/views/tuttle/performance_tuning/index.html.erb +79 -0
- data/app/views/tuttle/rails/assets.html.erb +38 -43
- data/app/views/tuttle/rails/database.html.erb +2 -2
- data/app/views/tuttle/rails/engines.html.erb +40 -0
- data/app/views/tuttle/rails/generators.html.erb +74 -0
- data/app/views/tuttle/rails/index.html.erb +62 -86
- data/app/views/tuttle/rails/models.html.erb +16 -1
- data/app/views/tuttle/rails/schema_cache.html.erb +3 -1
- data/app/views/tuttle/request/index.html.erb +37 -0
- data/app/views/tuttle/ruby/index.html.erb +65 -0
- data/config/routes.rb +19 -3
- data/lib/tuttle.rb +6 -1
- data/lib/tuttle/engine.rb +23 -61
- data/lib/tuttle/instrumenter.rb +38 -0
- data/lib/tuttle/middleware/request_profiler.rb +80 -0
- data/lib/tuttle/ruby_prof/fast_call_stack_printer.rb +164 -0
- data/lib/tuttle/version.rb +1 -1
- metadata +21 -21
- data/app/assets/images/tuttle/favicon.ico +0 -0
- data/app/assets/javascripts/tuttle/application.js +0 -12
- data/app/assets/stylesheets/tuttle/application.css +0 -71
@@ -46,7 +46,22 @@ No models were found in this application
|
|
46
46
|
Stored attributes = <%= model.stored_attributes %><br/>
|
47
47
|
Save callbacks = <%= model.send('_save_callbacks').count %><br/>
|
48
48
|
Associations = <%= model.reflect_on_all_associations.count %><br/>
|
49
|
-
Reflections = <%= model.reflections.keys.to_s %><br/>
|
49
|
+
Reflections = <%= model.reflections.keys.sort!.to_s %><br/>
|
50
|
+
Validators:<br/>
|
51
|
+
<table class="table table-compact">
|
52
|
+
<tr>
|
53
|
+
<th>Kind</th>
|
54
|
+
<th>Attributes</th>
|
55
|
+
<th>Options</th>
|
56
|
+
</tr>
|
57
|
+
<% model.validators.each do |validator| %>
|
58
|
+
<tr>
|
59
|
+
<td><%= validator.kind %></td>
|
60
|
+
<td><%= validator.attributes if validator.respond_to?(:attributes) %></td>
|
61
|
+
<td><%= validator.options %></td>
|
62
|
+
</tr>
|
63
|
+
<% end %>
|
64
|
+
</table>
|
50
65
|
|
51
66
|
<% next if model.abstract_class? || ! model.table_exists? %>
|
52
67
|
<% if model.respond_to?(:find_by_statement_cache) %>
|
@@ -42,7 +42,9 @@
|
|
42
42
|
<p>Note: The schema cache is only loaded once on application startup. During development, with code reloading, it is likely to be reset.</p>
|
43
43
|
<% end %>
|
44
44
|
|
45
|
-
|
45
|
+
<%- # Rails 5.x switched to @data_sources from @tables for instance variable %>
|
46
|
+
<% cached_tablenames = @connection_schema_cache.instance_variable_defined?(:@data_sources) && instance_variable_get(:@data_sources) ||
|
47
|
+
@connection_schema_cache.instance_variable_get(:@tables) || [] %>
|
46
48
|
<% cached_columns = @connection_schema_cache.instance_variable_get(:@columns) %>
|
47
49
|
<% cached_columns_hash = @connection_schema_cache.instance_variable_get(:@columns_hash) %>
|
48
50
|
<% cached_primary_keys = @connection_schema_cache.instance_variable_get(:@primary_keys) %>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<h1>Request Info</h1>
|
2
|
+
|
3
|
+
<h2>Session Variables</h2>
|
4
|
+
<% # TODO:
|
5
|
+
# show session store configuration (class and options)
|
6
|
+
# total session size
|
7
|
+
# session variable actions - unset, set(string), new(key, string)
|
8
|
+
# Cookie header string size, cookie count
|
9
|
+
# cookie actions (client and/or server) - clear, update, new(with paths, secure, etc.)
|
10
|
+
# Do secure cookies get accessed differently?
|
11
|
+
%>
|
12
|
+
<table class="table table-condensed">
|
13
|
+
<tr>
|
14
|
+
<th>Key</th>
|
15
|
+
<th>Value</th>
|
16
|
+
</tr>
|
17
|
+
<% @session_hash.each do |key, value| %>
|
18
|
+
<tr>
|
19
|
+
<td><%= key %></td>
|
20
|
+
<td><%= value %></td>
|
21
|
+
</tr>
|
22
|
+
<% end %>
|
23
|
+
</table>
|
24
|
+
|
25
|
+
<h2>Cookies</h2>
|
26
|
+
<table class="table table-condensed">
|
27
|
+
<tr>
|
28
|
+
<th>Key</th>
|
29
|
+
<th>Value</th>
|
30
|
+
</tr>
|
31
|
+
<% @cookies_hash.each do |key, value| %>
|
32
|
+
<tr>
|
33
|
+
<td><%= key %></td>
|
34
|
+
<td><%= value %></td>
|
35
|
+
</tr>
|
36
|
+
<% end %>
|
37
|
+
</table>
|
@@ -3,8 +3,12 @@
|
|
3
3
|
<ul class="nav nav-tabs" role="tablist">
|
4
4
|
<li class="active"><a href="#ruby" role="tab" data-toggle="tab">Ruby</a></li>
|
5
5
|
<li><a href="#environment" role="tab" data-toggle="tab">Environment</a></li>
|
6
|
+
<li><a href="#rbconfig" role="tab" data-toggle="tab">Ruby Config</a></li>
|
6
7
|
<li><a href="#bundler" role="tab" data-toggle="tab">Bundler</a></li>
|
7
8
|
<li><a href="#gc" role="tab" data-toggle="tab">Garbage Collection</a></li>
|
9
|
+
<li><a href="#load_path" role="tab" data-toggle="tab">Load Path</a></li>
|
10
|
+
<li><a href="#loaded_features" role="tab" data-toggle="tab">Loaded Features</a></li>
|
11
|
+
|
8
12
|
</ul>
|
9
13
|
|
10
14
|
<div class="tab-content">
|
@@ -19,6 +23,45 @@
|
|
19
23
|
<dt>RUBY_DESCRIPTION</dt><dd><%= RUBY_DESCRIPTION %></dd>
|
20
24
|
<dt>RUBY_COPYRIGHT</dt><dd><%= RUBY_COPYRIGHT %></dd>
|
21
25
|
</dl>
|
26
|
+
<h3>RUBYOPT</h3>
|
27
|
+
<p>The RUBYOPT environment variable can be set pass command line options to Ruby.</p>
|
28
|
+
<pre><%= ENV.fetch('RUBYOPT') { 'Not set'} %></pre>
|
29
|
+
|
30
|
+
<h3>RubyVM::DEFAULT_PARAMS</h3>
|
31
|
+
<p>The Ruby VM default parameters are the default values for this version of Ruby. They are not configurable.</p>
|
32
|
+
<table class="table table-condensed" style="width: auto;">
|
33
|
+
<tr>
|
34
|
+
<th>Setting</th>
|
35
|
+
<th>Value</th>
|
36
|
+
</tr>
|
37
|
+
<% RubyVM::DEFAULT_PARAMS.each do |k, v| %>
|
38
|
+
<tr>
|
39
|
+
<td><%= k.inspect %></td>
|
40
|
+
<td><%= v %></td>
|
41
|
+
</tr>
|
42
|
+
<% end %>
|
43
|
+
</table>
|
44
|
+
|
45
|
+
<h3>RubyVM::OPTS</h3>
|
46
|
+
<p>The RubyVM OPTS are build-time settings specified when Ruby is compiled.</p>
|
47
|
+
<pre><%= RubyVM::OPTS.inspect %></pre>
|
48
|
+
</div>
|
49
|
+
|
50
|
+
<div class="tab-pane" id="rbconfig">
|
51
|
+
<h3>RbConfig</h3>
|
52
|
+
<p>The RbConfig records the compile-time values of... </p>
|
53
|
+
<table class="table table-condensed" style="width: auto;">
|
54
|
+
<tr>
|
55
|
+
<th>Setting</th>
|
56
|
+
<th>Value</th>
|
57
|
+
</tr>
|
58
|
+
<% RbConfig::CONFIG.each do |k, v| %>
|
59
|
+
<tr>
|
60
|
+
<td><%= k %></td>
|
61
|
+
<td><code><%= v %></code></td>
|
62
|
+
</tr>
|
63
|
+
<% end %>
|
64
|
+
</table>
|
22
65
|
</div>
|
23
66
|
|
24
67
|
<div class="tab-pane" id="environment">
|
@@ -58,4 +101,26 @@
|
|
58
101
|
</dl>
|
59
102
|
</div>
|
60
103
|
|
104
|
+
<div class="tab-pane" id="load_path">
|
105
|
+
<p>
|
106
|
+
The the <code>$LOAD_PATH</code> (<%= $LOAD_PATH.size %> entries) lists
|
107
|
+
the directories that will be searched when code is loaded with
|
108
|
+
<code>require</code> or <code>load</code>.
|
109
|
+
</p>
|
110
|
+
<ul>
|
111
|
+
<%- $LOAD_PATH.each do |dir_name| %>
|
112
|
+
<li><%= dir_name %></li>
|
113
|
+
<%- end %>
|
114
|
+
</ul>
|
115
|
+
</div>
|
116
|
+
|
117
|
+
<div class="tab-pane" id="loaded_features">
|
118
|
+
<p>The following <b><%= $LOADED_FEATURES.size %></b> files have been loaded via <code>require</code> at some point.</p>
|
119
|
+
<ul>
|
120
|
+
<%- $LOADED_FEATURES.each do |filename| %>
|
121
|
+
<li><%= filename %></li>
|
122
|
+
<%- end %>
|
123
|
+
</ul>
|
124
|
+
</div>
|
125
|
+
|
61
126
|
</div>
|
data/config/routes.rb
CHANGED
@@ -4,17 +4,33 @@ Tuttle::Engine.routes.draw do
|
|
4
4
|
|
5
5
|
namespace :rails do
|
6
6
|
get '', :action => :index
|
7
|
-
get :controllers, :models, :database, :schema_cache, :helpers, :assets,
|
7
|
+
get :controllers, :models, :database, :schema_cache, :helpers, :assets,
|
8
|
+
:routes, :instrumentation, :cache, :generators, :engines
|
8
9
|
end
|
9
10
|
|
10
11
|
namespace :ruby do
|
11
12
|
get '', :action => :index
|
12
|
-
get :
|
13
|
+
get :miscellaneous, :tuning
|
13
14
|
end
|
14
15
|
|
15
16
|
namespace :gems do
|
16
17
|
get '', :action => :index
|
17
|
-
get :http_clients, :json, :other
|
18
|
+
get :get_process_mem, :http_clients, :json, :other
|
19
|
+
end
|
20
|
+
|
21
|
+
namespace :active_support do
|
22
|
+
get '', :action => :index
|
23
|
+
get :dependencies, :inflectors, :time_zones
|
24
|
+
end
|
25
|
+
|
26
|
+
get '/performance_tuning' => 'performance_tuning#index'
|
27
|
+
|
28
|
+
get '/request' => 'request#index'
|
29
|
+
|
30
|
+
if defined?(ActiveModelSerializers)
|
31
|
+
get '/active_model_serializers' => 'active_model_serializers#index' # 0.10.x?
|
32
|
+
elsif defined?(ActiveModel::Serializer)
|
33
|
+
get '/active_model_serializers' => 'active_model_serializers#index' # 0.9.x?
|
18
34
|
end
|
19
35
|
|
20
36
|
if defined?(Paperclip)
|
data/lib/tuttle.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
require 'tuttle/engine'
|
2
1
|
require 'tuttle/version'
|
2
|
+
require 'tuttle/engine' if defined?(Rails)
|
3
|
+
|
4
|
+
# TODO: clean this up so that mattr_accessor is not needed
|
5
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
3
6
|
|
4
7
|
module Tuttle
|
5
8
|
|
@@ -10,6 +13,8 @@ module Tuttle
|
|
10
13
|
@@automount_engine = @@enabled = nil
|
11
14
|
@@track_notifications = false
|
12
15
|
|
16
|
+
autoload :Instrumenter, 'tuttle/instrumenter'
|
17
|
+
|
13
18
|
def self.setup
|
14
19
|
yield self
|
15
20
|
end
|
data/lib/tuttle/engine.rb
CHANGED
@@ -1,88 +1,50 @@
|
|
1
|
+
require 'rails/engine'
|
2
|
+
|
1
3
|
module Tuttle
|
2
4
|
class Engine < ::Rails::Engine
|
3
5
|
isolate_namespace Tuttle
|
4
|
-
engine_name :tuttle
|
5
6
|
|
6
|
-
|
7
|
+
mattr_accessor :reload_needed, :session_start, :session_id
|
7
8
|
|
8
|
-
|
9
|
-
attr_accessor :events, :event_counts, :cache_events
|
10
|
-
attr_accessor :session_start, :session_id
|
9
|
+
mattr_reader :logger
|
11
10
|
|
12
|
-
|
11
|
+
config.tuttle = ActiveSupport::OrderedOptions.new
|
13
12
|
|
14
|
-
|
15
|
-
|
13
|
+
config.before_configuration do
|
14
|
+
Tuttle::Engine.session_start = Time.now
|
15
|
+
Tuttle::Engine.session_id = SecureRandom.uuid
|
16
16
|
end
|
17
17
|
|
18
|
-
initializer
|
19
|
-
app.config.tuttle.each do |k,v|
|
18
|
+
initializer 'tuttle' do |app|
|
19
|
+
app.config.tuttle.each do |k, v|
|
20
20
|
Tuttle.send("#{k}=", v)
|
21
21
|
end
|
22
|
-
# Tuttle will be automatically enabled in development if not configured explicitly
|
23
|
-
Tuttle.enabled= Rails.env.development? if Tuttle.enabled==nil
|
24
|
-
Tuttle.automount_engine= true if Tuttle.automount_engine==nil
|
25
|
-
end
|
26
|
-
|
27
|
-
initializer :tuttle_startup do
|
28
|
-
next unless Tuttle.enabled
|
29
22
|
|
30
|
-
Tuttle
|
31
|
-
Tuttle
|
32
|
-
@logger = ::Logger.new("#{Rails.root}/log/tuttle.log")
|
33
|
-
@logger.info('Tuttle engine started')
|
34
|
-
end
|
23
|
+
# Tuttle will be enabled automatically in development if not configured explicitly
|
24
|
+
Tuttle.enabled = Rails.env.development? if Tuttle.enabled.nil?
|
35
25
|
|
36
|
-
initializer :tuttle_track_reloads, group: :all do
|
37
26
|
next unless Tuttle.enabled
|
38
27
|
|
39
|
-
|
40
|
-
|
41
|
-
Tuttle::Engine.reload_needed = true
|
42
|
-
end
|
43
|
-
end
|
28
|
+
@@logger = ::Logger.new("#{Rails.root}/log/tuttle.log")
|
29
|
+
Tuttle::Engine.logger.info('Tuttle engine started')
|
44
30
|
|
45
|
-
|
46
|
-
Tuttle::Engine.events = []
|
47
|
-
Tuttle::Engine.event_counts = Hash.new(0)
|
48
|
-
Tuttle::Engine.cache_events = []
|
49
|
-
next unless Tuttle.enabled && Tuttle.track_notifications
|
31
|
+
Tuttle.automount_engine = true if Tuttle.automount_engine == nil
|
50
32
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
Tuttle::Engine.events << event
|
56
|
-
Tuttle::Engine.event_counts[event.name] += 1
|
33
|
+
if Tuttle.automount_engine
|
34
|
+
Rails.application.routes.prepend do
|
35
|
+
Tuttle::Engine.logger.info('Auto-mounting /tuttle routes')
|
36
|
+
mount Tuttle::Engine, at: "tuttle"
|
57
37
|
end
|
58
38
|
end
|
59
39
|
|
60
|
-
|
61
|
-
|
62
|
-
ActiveSupport::Notifications.subscribe('cache_read.active_support') do |*args|
|
63
|
-
cache_call_location = caller_locations.detect { |cl| cl.path.start_with?("#{Rails.root}/app".freeze) }
|
64
|
-
event = ActiveSupport::Notifications::Event.new(*args)
|
65
|
-
|
66
|
-
Tuttle::Engine.logger.info("Cache Read called: #{cache_call_location.path} on line #{cache_call_location.lineno} :: #{event.payload.inspect}")
|
67
|
-
|
68
|
-
event.payload.merge!({:call_location_path => cache_call_location.path, :call_location_lineno => cache_call_location.lineno })
|
69
|
-
Tuttle::Engine.cache_events << event
|
70
|
-
end
|
71
|
-
ActiveSupport::Notifications.subscribe('cache_generate.active_support') do |*args|
|
72
|
-
Tuttle::Engine.logger.info('Cache Generate called')
|
40
|
+
if Tuttle.track_notifications
|
41
|
+
Tuttle::Instrumenter.initialize_tuttle_instrumenter
|
73
42
|
end
|
74
43
|
|
75
44
|
end
|
76
45
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
if Tuttle.automount_engine
|
81
|
-
Rails.application.routes.prepend do
|
82
|
-
Tuttle::Engine.logger.info('Auto-mounting /tuttle routes')
|
83
|
-
mount Tuttle::Engine, at: "tuttle"
|
84
|
-
end
|
85
|
-
end
|
46
|
+
config.to_prepare do
|
47
|
+
Tuttle::Engine.reload_needed = true
|
86
48
|
end
|
87
49
|
|
88
50
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Tuttle
|
2
|
+
class Instrumenter
|
3
|
+
|
4
|
+
mattr_accessor :events, :event_counts, :cache_events
|
5
|
+
@@events = []
|
6
|
+
@@event_counts = Hash.new(0)
|
7
|
+
@@cache_events = []
|
8
|
+
|
9
|
+
def self.initialize_tuttle_instrumenter
|
10
|
+
# For now, only instrument non-production mode
|
11
|
+
unless Rails.env.production?
|
12
|
+
ActiveSupport::Notifications.subscribe(/.*/) do |*args|
|
13
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
14
|
+
Tuttle::Instrumenter.events << event
|
15
|
+
Tuttle::Instrumenter.event_counts[event.name] += 1
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Note: For Rails < 4.2 instrumentation is not enabled by default. Hitting the cache inspector page will enable it for that session.
|
20
|
+
Tuttle::Engine.logger.info('Initializing cache_read subscriber')
|
21
|
+
ActiveSupport::Notifications.subscribe('cache_read.active_support') do |*args|
|
22
|
+
cache_call_location = caller_locations.detect { |cl| cl.path.start_with?("#{Rails.root}/app".freeze) }
|
23
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
24
|
+
|
25
|
+
Tuttle::Engine.logger.info("Cache Read called: #{cache_call_location.path} on line #{cache_call_location.lineno} :: #{event.payload.inspect}")
|
26
|
+
|
27
|
+
event.payload.merge!({:call_location_path => cache_call_location.path, :call_location_lineno => cache_call_location.lineno })
|
28
|
+
Tuttle::Instrumenter.cache_events << event
|
29
|
+
end
|
30
|
+
|
31
|
+
ActiveSupport::Notifications.subscribe('cache_generate.active_support') do |*args|
|
32
|
+
Tuttle::Engine.logger.info('Cache Generate called')
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Tuttle
|
4
|
+
module Middleware
|
5
|
+
class RequestProfiler
|
6
|
+
|
7
|
+
def initialize(app)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
query_string = env['QUERY_STRING']
|
13
|
+
|
14
|
+
tuttle_profiler_action = /tuttle\-profiler=([\w\-]*)/.match(query_string) { $1.to_sym }
|
15
|
+
|
16
|
+
case tuttle_profiler_action
|
17
|
+
when :'memory_profiler', :'memory'
|
18
|
+
profile_memory(env, query_string)
|
19
|
+
when :'ruby-prof', :'cpu'
|
20
|
+
profile_cpu(env, query_string)
|
21
|
+
else
|
22
|
+
@app.call(env)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def profile_memory(env, query_string)
|
30
|
+
require 'memory_profiler'
|
31
|
+
|
32
|
+
query_params = Rack::Utils.parse_nested_query(query_string)
|
33
|
+
options = {
|
34
|
+
:ignore_files => query_params['memory_profiler_ignore_files'],
|
35
|
+
:allow_files => query_params['memory_profiler_allow_files'],
|
36
|
+
}
|
37
|
+
options[:top]= Integer(query_params['memory_profiler_top']) if query_params.key?('memory_profiler_top')
|
38
|
+
|
39
|
+
report = MemoryProfiler.report(options) do
|
40
|
+
_,_,body = @app.call(env)
|
41
|
+
body.close if body.respond_to? :close
|
42
|
+
end
|
43
|
+
|
44
|
+
result = StringIO.new
|
45
|
+
report.pretty_print(result)
|
46
|
+
|
47
|
+
[200, { 'Content-Type' => 'text/plain' }, ["Report from Tuttle::Middeware::RequestProfiler\n", result.string]]
|
48
|
+
end
|
49
|
+
|
50
|
+
def profile_cpu(env, query_string)
|
51
|
+
require 'ruby-prof'
|
52
|
+
|
53
|
+
data = ::RubyProf::Profile.profile do
|
54
|
+
_, _, body = @app.call(env)
|
55
|
+
body.close if body.respond_to? :close
|
56
|
+
end
|
57
|
+
|
58
|
+
result = StringIO.new
|
59
|
+
rubyprof_printer = /ruby\-prof_printer=([\w]*)/.match(query_string) { $1.to_sym }
|
60
|
+
content_type = 'text/html'
|
61
|
+
|
62
|
+
case rubyprof_printer
|
63
|
+
when :flat
|
64
|
+
::RubyProf::FlatPrinter.new(data).print(result)
|
65
|
+
content_type = 'text/plain'
|
66
|
+
when :graph
|
67
|
+
::RubyProf::GraphHtmlPrinter.new(data).print(result)
|
68
|
+
when :fast_stack
|
69
|
+
require 'tuttle/ruby_prof/fast_call_stack_printer'
|
70
|
+
::Tuttle::RubyProf::FastCallStackPrinter.new(data).print(result, { :application => env['REQUEST_URI']})
|
71
|
+
else
|
72
|
+
::RubyProf::CallStackPrinter.new(data).print(result)
|
73
|
+
end
|
74
|
+
|
75
|
+
[200, { 'Content-Type' => content_type }, [result.string]]
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|