rack-mini-profiler 0.1.10 → 0.1.15.pre
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.
- data/CHANGELOG +25 -0
- data/README.md +27 -1
- data/lib/html/includes.css +1 -1
- data/lib/html/includes.js +16 -9
- data/lib/html/includes.less +1 -1
- data/lib/html/includes.tmpl +1 -1
- data/lib/mini_profiler/client_settings.rb +65 -0
- data/lib/mini_profiler/client_timer_struct.rb +0 -0
- data/lib/mini_profiler/config.rb +1 -1
- data/lib/mini_profiler/context.rb +0 -0
- data/lib/mini_profiler/page_timer_struct.rb +0 -0
- data/lib/mini_profiler/profiler.rb +44 -60
- data/lib/mini_profiler/profiling_methods.rb +1 -2
- data/lib/mini_profiler/request_timer_struct.rb +0 -0
- data/lib/mini_profiler/sql_timer_struct.rb +11 -1
- data/lib/mini_profiler/storage/abstract_store.rb +0 -0
- data/lib/mini_profiler/storage/file_store.rb +0 -0
- data/lib/mini_profiler/storage/memory_store.rb +0 -1
- data/lib/mini_profiler/storage/redis_store.rb +0 -0
- data/lib/mini_profiler/timer_struct.rb +3 -6
- data/lib/mini_profiler_rails/railtie.rb +1 -1
- data/lib/patches/sql_patches.rb +46 -0
- data/lib/rack-mini-profiler.rb +0 -0
- data/rack-mini-profiler.gemspec +1 -1
- metadata +7 -9
data/CHANGELOG
CHANGED
|
@@ -44,3 +44,28 @@
|
|
|
44
44
|
* Added option to disable profiler for the current session (pp=disable / pp=enable)
|
|
45
45
|
* yajl compatability contributed by Sven Riedel
|
|
46
46
|
|
|
47
|
+
10-August-2012 - Sam
|
|
48
|
+
|
|
49
|
+
* Added basic prepared statement profiling for postgres
|
|
50
|
+
|
|
51
|
+
20-August-2012 - Sam
|
|
52
|
+
|
|
53
|
+
* 1.12.pre
|
|
54
|
+
* Cap X-MiniProfiler-Ids at 10, otherwise the header can get killed
|
|
55
|
+
|
|
56
|
+
3-September-2012 - Sam
|
|
57
|
+
|
|
58
|
+
* 1.13.pre
|
|
59
|
+
* pg gem prepared statements were not being logged correctly
|
|
60
|
+
* added setting config.backtrace_ignores = [] - an array of regexes that match on caller lines that get ignored
|
|
61
|
+
* added setting config.backtrace_includes = [] - an array of regexes that get included in the trace by default
|
|
62
|
+
* cleaned up the way client settings are stored
|
|
63
|
+
* made pp=full-backtrace "sticky"
|
|
64
|
+
* added pp=normal-backtrace to clear the "sticky" state
|
|
65
|
+
* change "pp=sample" to work with "caller" no need for stack trace gem
|
|
66
|
+
|
|
67
|
+
4-September-2012 - Sam
|
|
68
|
+
|
|
69
|
+
* 1.15.pre
|
|
70
|
+
* fixed annoying bug where client settings were not sticking
|
|
71
|
+
* fixed long standing issue with Rack::ConditionalGet stopping MiniProfiler from working properly
|
data/README.md
CHANGED
|
@@ -87,7 +87,33 @@ In a Rails app, this can be done conveniently in an initializer such as config/i
|
|
|
87
87
|
|
|
88
88
|
## Rails 2.X support
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
To get MiniProfiler working with Rails 2.3.X you need to do the initialization manually as well as monkey patch away an incompatibility between activesupport and json_pure.
|
|
91
|
+
|
|
92
|
+
Add the following code to your environment.rb (or just in a specific environment such as development.rb) for initialization and configuration of MiniProfiler.
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
# configure and initialize MiniProfiler
|
|
96
|
+
require 'rack-mini-profiler'
|
|
97
|
+
c = ::Rack::MiniProfiler.config
|
|
98
|
+
c.pre_authorize_cb = lambda { |env|
|
|
99
|
+
Rails.env.development? || Rails.env.production?
|
|
100
|
+
}
|
|
101
|
+
tmp = Rails.root.to_s + "/tmp/miniprofiler"
|
|
102
|
+
FileUtils.mkdir_p(tmp) unless File.exists?(tmp)
|
|
103
|
+
c.storage_options = {:path => tmp}
|
|
104
|
+
c.storage = ::Rack::MiniProfiler::FileStore
|
|
105
|
+
config.middleware.use(::Rack::MiniProfiler)
|
|
106
|
+
::Rack::MiniProfiler.profile_method(ActionController::Base, :process) {|action| "Executing action: #{action}"}
|
|
107
|
+
::Rack::MiniProfiler.profile_method(ActionView::Template, :render) {|x,y| "Rendering: #{@virtual_path}"}
|
|
108
|
+
|
|
109
|
+
# monkey patch away an activesupport and json_pure incompatability
|
|
110
|
+
# http://pivotallabs.com/users/alex/blog/articles/1332-monkey-patch-of-the-day-activesupport-vs-json-pure-vs-ruby-1-8
|
|
111
|
+
if JSON.const_defined?(:Pure)
|
|
112
|
+
class JSON::Pure::Generator::State
|
|
113
|
+
include ActiveSupport::CoreExtensions::Hash::Except
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
```
|
|
91
117
|
|
|
92
118
|
## Available Options
|
|
93
119
|
|
data/lib/html/includes.css
CHANGED
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
.profiler-results .profiler-popup .profiler-timings th,.profiler-results .profiler-popup .profiler-timings td{padding-left:6px;padding-right:6px;}
|
|
59
59
|
.profiler-results .profiler-popup .profiler-timings th{font-size:95%;padding-bottom:3px;}
|
|
60
60
|
.profiler-results .profiler-popup .profiler-timings .profiler-label{max-width:275px;}
|
|
61
|
-
.profiler-results .profiler-queries{display:none;z-index:2147483643;position:absolute;overflow-y:auto;overflow-x:
|
|
61
|
+
.profiler-results .profiler-queries{display:none;z-index:2147483643;position:absolute;overflow-y:auto;overflow-x:auto;background-color:#fff;}.profiler-results .profiler-queries th{font-size:17px;}
|
|
62
62
|
.profiler-results.profiler-min .profiler-result{display:none;}
|
|
63
63
|
.profiler-results.profiler-min .profiler-controls span{display:none;}
|
|
64
64
|
.profiler-results.profiler-min .profiler-controls .profiler-min-max{border-right:none;padding:0px;margin:0px;}
|
data/lib/html/includes.js
CHANGED
|
@@ -5,7 +5,8 @@ var MiniProfiler = (function ($) {
|
|
|
5
5
|
container,
|
|
6
6
|
controls,
|
|
7
7
|
fetchedIds = [],
|
|
8
|
-
fetchingIds = []
|
|
8
|
+
fetchingIds = [], // so we never pull down a profiler twice
|
|
9
|
+
ajaxStartTime
|
|
9
10
|
;
|
|
10
11
|
|
|
11
12
|
var hasLocalStorage = function () {
|
|
@@ -73,15 +74,15 @@ var MiniProfiler = (function ($) {
|
|
|
73
74
|
clientPerformance = null;
|
|
74
75
|
clientProbes = null;
|
|
75
76
|
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
clientProbes =
|
|
80
|
-
for (j = 0; j < clientProbes.length; j++) {
|
|
81
|
-
clientProbes[j].d = clientProbes[j].d.getTime();
|
|
82
|
-
}
|
|
83
|
-
mPt.t = [];
|
|
77
|
+
if (window.mPt) {
|
|
78
|
+
clientProbes = mPt.results();
|
|
79
|
+
for (j = 0; j < clientProbes.length; j++) {
|
|
80
|
+
clientProbes[j].d = clientProbes[j].d.getTime();
|
|
84
81
|
}
|
|
82
|
+
mPt.flush();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (id == options.currentId) {
|
|
85
86
|
|
|
86
87
|
clientPerformance = getClientPerformance();
|
|
87
88
|
|
|
@@ -113,6 +114,9 @@ var MiniProfiler = (function ($) {
|
|
|
113
114
|
|
|
114
115
|
}
|
|
115
116
|
}
|
|
117
|
+
} else if (ajaxStartTime != null && clientProbes && clientProbes.length > 0) {
|
|
118
|
+
clientPerformance = { timing: { navigationStart: ajaxStartTime.getTime() } };
|
|
119
|
+
ajaxStartTime = null;
|
|
116
120
|
}
|
|
117
121
|
|
|
118
122
|
if ($.inArray(id, fetchedIds) < 0 && $.inArray(id, fetchingIds) < 0) {
|
|
@@ -449,6 +453,9 @@ var MiniProfiler = (function ($) {
|
|
|
449
453
|
jQuery(document).ajaxComplete(jQueryAjaxComplete);
|
|
450
454
|
}
|
|
451
455
|
|
|
456
|
+
if (jQuery(document).ajaxStart)
|
|
457
|
+
jQuery(document).ajaxStart(function () { ajaxStartTime = new Date(); });
|
|
458
|
+
|
|
452
459
|
// fetch results after ASP Ajax calls
|
|
453
460
|
if (typeof (Sys) != 'undefined' && typeof (Sys.WebForms) != 'undefined' && typeof (Sys.WebForms.PageRequestManager) != 'undefined') {
|
|
454
461
|
// Get the instance of PageRequestManager.
|
data/lib/html/includes.less
CHANGED
data/lib/html/includes.tmpl
CHANGED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Rack
|
|
2
|
+
class MiniProfiler
|
|
3
|
+
class ClientSettings
|
|
4
|
+
|
|
5
|
+
COOKIE_NAME = "__profilin"
|
|
6
|
+
|
|
7
|
+
BACKTRACE_DEFAULT = nil
|
|
8
|
+
BACKTRACE_FULL = 1
|
|
9
|
+
BACKTRACE_NONE = 2
|
|
10
|
+
|
|
11
|
+
attr_accessor :disable_profiling
|
|
12
|
+
attr_accessor :backtrace_level
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def initialize(env)
|
|
16
|
+
request = ::Rack::Request.new(env)
|
|
17
|
+
@cookie = request.cookies[COOKIE_NAME]
|
|
18
|
+
if @cookie
|
|
19
|
+
@cookie.split(",").map{|pair| pair.split("=")}.each do |k,v|
|
|
20
|
+
@orig_disable_profiling = @disable_profiling = (v=='t') if k == "dp"
|
|
21
|
+
@backtrace_level = v.to_i if k == "bt"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
@backtrace_level = nil if !@backtrace_level.nil? && (@backtrace_level == 0 || @backtrace_level > BACKTRACE_NONE)
|
|
26
|
+
@orig_backtrace_level = @backtrace_level
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def write!(headers)
|
|
31
|
+
if @orig_disable_profiling != @disable_profiling || @orig_backtrace_level != @backtrace_level || @cookie.nil?
|
|
32
|
+
settings = {"p" => "t" }
|
|
33
|
+
settings["dp"] = "t" if @disable_profiling
|
|
34
|
+
settings["bt"] = @backtrace_level if @backtrace_level
|
|
35
|
+
settings_string = settings.map{|k,v| "#{k}=#{v}"}.join(",")
|
|
36
|
+
Rack::Utils.set_cookie_header!(headers, COOKIE_NAME, :value => settings_string, :path => '/')
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def discard_cookie!(headers)
|
|
41
|
+
Rack::Utils.delete_cookie_header!(headers, COOKIE_NAME, :path => '/')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def has_cookie?
|
|
45
|
+
!@cookie.nil?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def disable_profiling?
|
|
49
|
+
@disable_profiling
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def backtrace_full?
|
|
53
|
+
@backtrace_level == BACKTRACE_FULL
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def backtrace_default?
|
|
57
|
+
@backtrace_level == BACKTRACE_DEFAULT
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def backtrace_none?
|
|
61
|
+
@backtrace_level == BACKTRACE_NONE
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
File without changes
|
data/lib/mini_profiler/config.rb
CHANGED
|
@@ -13,7 +13,7 @@ module Rack
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
attr_accessor :auto_inject, :base_url_path, :pre_authorize_cb, :position,
|
|
16
|
-
:backtrace_remove, :
|
|
16
|
+
:backtrace_remove, :backtrace_includes, :backtrace_ignores, :skip_schema_queries,
|
|
17
17
|
:storage, :user_provider, :storage_instance, :storage_options, :skip_paths, :authorization_mode, :use_existing_jquery
|
|
18
18
|
|
|
19
19
|
def self.default
|
|
File without changes
|
|
File without changes
|
|
@@ -13,12 +13,13 @@ require 'mini_profiler/storage/file_store'
|
|
|
13
13
|
require 'mini_profiler/config'
|
|
14
14
|
require 'mini_profiler/profiling_methods'
|
|
15
15
|
require 'mini_profiler/context'
|
|
16
|
+
require 'mini_profiler/client_settings'
|
|
16
17
|
|
|
17
18
|
module Rack
|
|
18
19
|
|
|
19
20
|
class MiniProfiler
|
|
20
21
|
|
|
21
|
-
VERSION = '
|
|
22
|
+
VERSION = '106'.freeze
|
|
22
23
|
|
|
23
24
|
class << self
|
|
24
25
|
|
|
@@ -56,35 +57,6 @@ module Rack
|
|
|
56
57
|
self.current.discard = true if current
|
|
57
58
|
end
|
|
58
59
|
|
|
59
|
-
# user has the mini profiler cookie, only used when config.authorization_mode == :whitelist
|
|
60
|
-
def has_profiling_cookie?(env)
|
|
61
|
-
env['HTTP_COOKIE'] && env['HTTP_COOKIE'].include?("__profilin=stylin")
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# remove the mini profiler cookie, only used when config.authorization_mode == :whitelist
|
|
65
|
-
def remove_profiling_cookie(headers)
|
|
66
|
-
Rack::Utils.set_cookie_header!(headers, '__profilin', :value => 'notstylin', :path => '/')
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def set_profiling_cookie(headers)
|
|
70
|
-
Rack::Utils.set_cookie_header!(headers, '__profilin', :value => 'stylin', :path => '/')
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# user has the mini profiler cookie, only used when config.authorization_mode == :whitelist
|
|
74
|
-
def has_disable_profiling_cookie?(env)
|
|
75
|
-
env['HTTP_COOKIE'] && env['HTTP_COOKIE'].include?("__profilin_disable=stylin")
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# remove the mini profiler cookie, only used when config.authorization_mode == :whitelist
|
|
79
|
-
def remove_disable_profiling_cookie(headers)
|
|
80
|
-
#something is odd with delete_cookie_header
|
|
81
|
-
Rack::Utils.set_cookie_header!(headers, '__profilin_disable', :value => 'notstylin', :path => '/')
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def set_disable_profiling_cookie(headers)
|
|
85
|
-
Rack::Utils.set_cookie_header!(headers, '__profilin_disable', :value => 'stylin', :path => '/')
|
|
86
|
-
end
|
|
87
|
-
|
|
88
60
|
def create_current(env={}, options={})
|
|
89
61
|
# profiling the request
|
|
90
62
|
self.current = Context.new
|
|
@@ -195,6 +167,8 @@ module Rack
|
|
|
195
167
|
|
|
196
168
|
|
|
197
169
|
def call(env)
|
|
170
|
+
client_settings = ClientSettings.new(env)
|
|
171
|
+
|
|
198
172
|
status = headers = body = nil
|
|
199
173
|
query_string = env['QUERY_STRING']
|
|
200
174
|
path = env['PATH_INFO']
|
|
@@ -203,12 +177,12 @@ module Rack
|
|
|
203
177
|
(@config.skip_paths && @config.skip_paths.any?{ |p| path[0,p.length] == p}) ||
|
|
204
178
|
query_string =~ /pp=skip/
|
|
205
179
|
|
|
206
|
-
has_profiling_cookie =
|
|
180
|
+
has_profiling_cookie = client_settings.has_cookie?
|
|
207
181
|
|
|
208
182
|
if skip_it || (@config.authorization_mode == :whitelist && !has_profiling_cookie)
|
|
209
183
|
status,headers,body = @app.call(env)
|
|
210
184
|
if !skip_it && @config.authorization_mode == :whitelist && !has_profiling_cookie && MiniProfiler.request_authorized?
|
|
211
|
-
|
|
185
|
+
client_settings.write!(headers)
|
|
212
186
|
end
|
|
213
187
|
return [status,headers,body]
|
|
214
188
|
end
|
|
@@ -216,7 +190,7 @@ module Rack
|
|
|
216
190
|
# handle all /mini-profiler requests here
|
|
217
191
|
return serve_html(env) if path.start_with? @config.base_url_path
|
|
218
192
|
|
|
219
|
-
has_disable_cookie =
|
|
193
|
+
has_disable_cookie = client_settings.disable_profiling?
|
|
220
194
|
# manual session disable / enable
|
|
221
195
|
if query_string =~ /pp=disable/ || has_disable_cookie
|
|
222
196
|
skip_it = true
|
|
@@ -228,16 +202,23 @@ module Rack
|
|
|
228
202
|
|
|
229
203
|
if skip_it
|
|
230
204
|
status,headers,body = @app.call(env)
|
|
231
|
-
|
|
205
|
+
client_settings.disable_profiling = true
|
|
206
|
+
client_settings.write!(headers)
|
|
232
207
|
return [status,headers,body]
|
|
233
208
|
end
|
|
234
209
|
|
|
235
210
|
MiniProfiler.create_current(env, @config)
|
|
236
211
|
MiniProfiler.deauthorize_request if @config.authorization_mode == :whitelist
|
|
237
|
-
if query_string =~ /pp=
|
|
212
|
+
if query_string =~ /pp=normal-backtrace/
|
|
213
|
+
client_settings.backtrace_level = ClientSettings::BACKTRACE_DEFAULT
|
|
214
|
+
elsif query_string =~ /pp=no-backtrace/
|
|
238
215
|
current.skip_backtrace = true
|
|
239
|
-
|
|
216
|
+
client_settings.backtrace_level = ClientSettings::BACKTRACE_NONE
|
|
217
|
+
elsif query_string =~ /pp=full-backtrace/ || client_settings.backtrace_full?
|
|
240
218
|
current.full_backtrace = true
|
|
219
|
+
client_settings.backtrace_level = ClientSettings::BACKTRACE_FULL
|
|
220
|
+
elsif client_settings.backtrace_none?
|
|
221
|
+
current.skip_backtrace = true
|
|
241
222
|
end
|
|
242
223
|
|
|
243
224
|
done_sampling = false
|
|
@@ -249,17 +230,11 @@ module Rack
|
|
|
249
230
|
t = Thread.current
|
|
250
231
|
Thread.new {
|
|
251
232
|
begin
|
|
252
|
-
require 'stacktrace' rescue nil
|
|
253
|
-
if !t.respond_to? :stacktrace
|
|
254
|
-
missing_stacktrace = true
|
|
255
|
-
quit_sampler = true
|
|
256
|
-
return
|
|
257
|
-
end
|
|
258
233
|
i = 10000 # for sanity never grab more than 10k samples
|
|
259
234
|
while i > 0
|
|
260
235
|
break if done_sampling
|
|
261
236
|
i -= 1
|
|
262
|
-
backtraces << t.
|
|
237
|
+
backtraces << t.backtrace
|
|
263
238
|
sleep 0.001
|
|
264
239
|
end
|
|
265
240
|
ensure
|
|
@@ -271,10 +246,14 @@ module Rack
|
|
|
271
246
|
status, headers, body = nil
|
|
272
247
|
start = Time.now
|
|
273
248
|
begin
|
|
249
|
+
|
|
250
|
+
# Strip all the caching headers so we don't get 304s back
|
|
251
|
+
# This solves a very annoying bug where rack mini profiler never shows up
|
|
252
|
+
env['HTTP_IF_MODIFIED_SINCE'] = nil
|
|
253
|
+
env['HTTP_IF_NONE_MATCH'] = nil
|
|
254
|
+
|
|
274
255
|
status,headers,body = @app.call(env)
|
|
275
|
-
|
|
276
|
-
MiniProfiler.remove_disable_profiling_cookie(headers)
|
|
277
|
-
end
|
|
256
|
+
client_settings.write!(headers)
|
|
278
257
|
ensure
|
|
279
258
|
if backtraces
|
|
280
259
|
done_sampling = true
|
|
@@ -284,7 +263,7 @@ module Rack
|
|
|
284
263
|
|
|
285
264
|
skip_it = current.discard
|
|
286
265
|
if (config.authorization_mode == :whitelist && !MiniProfiler.request_authorized?)
|
|
287
|
-
|
|
266
|
+
client_settings.discard_cookie!(headers)
|
|
288
267
|
skip_it = true
|
|
289
268
|
end
|
|
290
269
|
|
|
@@ -298,7 +277,7 @@ module Rack
|
|
|
298
277
|
|
|
299
278
|
if query_string =~ /pp=help/
|
|
300
279
|
body.close if body.respond_to? :close
|
|
301
|
-
return help
|
|
280
|
+
return help(nil, client_settings)
|
|
302
281
|
end
|
|
303
282
|
|
|
304
283
|
page_struct = current.page_struct
|
|
@@ -306,7 +285,7 @@ module Rack
|
|
|
306
285
|
|
|
307
286
|
if backtraces
|
|
308
287
|
body.close if body.respond_to? :close
|
|
309
|
-
return help(:stacktrace) if missing_stacktrace
|
|
288
|
+
return help(:stacktrace, client_settings) if missing_stacktrace
|
|
310
289
|
return analyze(backtraces, page_struct)
|
|
311
290
|
end
|
|
312
291
|
|
|
@@ -317,6 +296,8 @@ module Rack
|
|
|
317
296
|
|
|
318
297
|
# inject headers, script
|
|
319
298
|
if status == 200
|
|
299
|
+
|
|
300
|
+
client_settings.write!(headers)
|
|
320
301
|
|
|
321
302
|
# mini profiler is meddling with stuff, we can not cache cause we will get incorrect data
|
|
322
303
|
# Rack::ETag has already inserted some nonesense in the chain
|
|
@@ -346,6 +327,7 @@ module Rack
|
|
|
346
327
|
end
|
|
347
328
|
end
|
|
348
329
|
|
|
330
|
+
client_settings.write!(headers)
|
|
349
331
|
[status, headers, body]
|
|
350
332
|
ensure
|
|
351
333
|
# Make sure this always happens
|
|
@@ -373,16 +355,17 @@ module Rack
|
|
|
373
355
|
[200, headers, [body]]
|
|
374
356
|
end
|
|
375
357
|
|
|
376
|
-
def help(category = nil)
|
|
358
|
+
def help(category = nil, client_settings)
|
|
377
359
|
headers = {'Content-Type' => 'text/plain'}
|
|
378
360
|
body = "Append the following to your query string:
|
|
379
361
|
|
|
380
362
|
pp=help : display this screen
|
|
381
363
|
pp=env : display the rack environment
|
|
382
364
|
pp=skip : skip mini profiler for this request
|
|
383
|
-
pp=no-backtrace : don't collect stack traces from all the SQL executed
|
|
384
|
-
pp=
|
|
385
|
-
pp=
|
|
365
|
+
pp=no-backtrace #{"(*) " if client_settings.backtrace_none?}: don't collect stack traces from all the SQL executed (sticky, use pp=normal-backtrace to enable)
|
|
366
|
+
pp=normal-backtrace #{"(*) " if client_settings.backtrace_default?}: collect stack traces from all the SQL executed and filter normally
|
|
367
|
+
pp=full-backtrace #{"(*) " if client_settings.backtrace_full?}: enable full backtraces for SQL executed (use pp=normal-backtrace to disable)
|
|
368
|
+
pp=sample : sample stack traces and return a report isolating heavy usage (experimental)
|
|
386
369
|
pp=disable : disable profiling for this session
|
|
387
370
|
pp=enable : enable profiling for this session (if previously disabled)
|
|
388
371
|
"
|
|
@@ -390,6 +373,7 @@ module Rack
|
|
|
390
373
|
body = "pp=stacktrace requires the stacktrace gem - add gem 'stacktrace' to your Gemfile"
|
|
391
374
|
end
|
|
392
375
|
|
|
376
|
+
client_settings.write!(headers)
|
|
393
377
|
[200, headers, [body]]
|
|
394
378
|
end
|
|
395
379
|
|
|
@@ -403,13 +387,12 @@ module Rack
|
|
|
403
387
|
fulldump << "\n\n"
|
|
404
388
|
distinct = {}
|
|
405
389
|
trace.each do |frame|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
seen[
|
|
410
|
-
seen[name] += 1
|
|
390
|
+
unless distinct[frame]
|
|
391
|
+
distinct[frame] = true
|
|
392
|
+
seen[frame] ||= 0
|
|
393
|
+
seen[frame] += 1
|
|
411
394
|
end
|
|
412
|
-
fulldump <<
|
|
395
|
+
fulldump << frame << "\n"
|
|
413
396
|
end
|
|
414
397
|
end
|
|
415
398
|
|
|
@@ -427,7 +410,8 @@ module Rack
|
|
|
427
410
|
end
|
|
428
411
|
|
|
429
412
|
def ids_json(env)
|
|
430
|
-
ids
|
|
413
|
+
# cap at 10 ids, otherwise there is a chance you can blow the header
|
|
414
|
+
ids = [current.page_struct["Id"]] + (@storage.get_unviewed_ids(user(env)) || [])[0..8]
|
|
431
415
|
::JSON.generate(ids.uniq)
|
|
432
416
|
end
|
|
433
417
|
|
|
@@ -9,7 +9,7 @@ module Rack
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
# perform a profiling step on given block
|
|
12
|
-
def step(name)
|
|
12
|
+
def step(name, opts = nil)
|
|
13
13
|
if current
|
|
14
14
|
parent_timer = current.current_timer
|
|
15
15
|
result = nil
|
|
@@ -20,7 +20,6 @@ module Rack
|
|
|
20
20
|
current_timer.record_time
|
|
21
21
|
current.current_timer = parent_timer
|
|
22
22
|
end
|
|
23
|
-
result
|
|
24
23
|
else
|
|
25
24
|
yield if block_given?
|
|
26
25
|
end
|
|
File without changes
|
|
@@ -14,7 +14,17 @@ module Rack
|
|
|
14
14
|
# Clean up the stack trace if there are options to do so
|
|
15
15
|
Kernel.caller.each do |ln|
|
|
16
16
|
ln.gsub!(Rack::MiniProfiler.config.backtrace_remove, '') if Rack::MiniProfiler.config.backtrace_remove and !full_backtrace
|
|
17
|
-
if
|
|
17
|
+
if full_backtrace or
|
|
18
|
+
(
|
|
19
|
+
(
|
|
20
|
+
Rack::MiniProfiler.config.backtrace_includes.nil? or
|
|
21
|
+
Rack::MiniProfiler.config.backtrace_includes.all?{|regex| ln =~ regex}
|
|
22
|
+
) and
|
|
23
|
+
(
|
|
24
|
+
Rack::MiniProfiler.config.backtrace_ignores.nil? or
|
|
25
|
+
Rack::MiniProfiler.config.backtrace_ignores.all?{|regex| !(ln =~ regex)}
|
|
26
|
+
)
|
|
27
|
+
)
|
|
18
28
|
stack_trace << ln << "\n"
|
|
19
29
|
end
|
|
20
30
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -22,12 +22,9 @@ module Rack
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def to_json(*a)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
else
|
|
29
|
-
::JSON.generate(@attributes, a[0])
|
|
30
|
-
end
|
|
25
|
+
# this does could take in an option hash, but the only interesting there is max_nesting.
|
|
26
|
+
# if this becomes an option we could increase
|
|
27
|
+
::JSON.generate( @attributes, :max_nesting => 100 )
|
|
31
28
|
end
|
|
32
29
|
|
|
33
30
|
end
|
|
@@ -31,7 +31,7 @@ module MiniProfilerRails
|
|
|
31
31
|
|
|
32
32
|
# Quiet the SQL stack traces
|
|
33
33
|
c.backtrace_remove = Rails.root.to_s + "/"
|
|
34
|
-
c.
|
|
34
|
+
c.backtrace_includes = [/^\/?(app|config|lib|test)/]
|
|
35
35
|
c.skip_schema_queries = Rails.env != 'production'
|
|
36
36
|
|
|
37
37
|
# Install the Middleware
|
data/lib/patches/sql_patches.rb
CHANGED
|
@@ -91,6 +91,24 @@ if SqlPatches.class_exists? "PG::Result"
|
|
|
91
91
|
class PG::Connection
|
|
92
92
|
alias_method :exec_without_profiling, :exec
|
|
93
93
|
alias_method :async_exec_without_profiling, :async_exec
|
|
94
|
+
alias_method :exec_prepared_without_profiling, :exec_prepared
|
|
95
|
+
alias_method :send_query_prepared_without_profiling, :send_query_prepared
|
|
96
|
+
alias_method :prepare_without_profiling, :prepare
|
|
97
|
+
|
|
98
|
+
def prepare(*args,&blk)
|
|
99
|
+
# we have no choice but to do this here,
|
|
100
|
+
# if we do the check for profiling first, our cache may miss critical stuff
|
|
101
|
+
|
|
102
|
+
@prepare_map ||= {}
|
|
103
|
+
@prepare_map[args[0]] = args[1]
|
|
104
|
+
# dont leak more than 10k ever
|
|
105
|
+
@prepare_map = {} if @prepare_map.length > 1000
|
|
106
|
+
|
|
107
|
+
current = ::Rack::MiniProfiler.current
|
|
108
|
+
return prepare_without_profiling(*args,&blk) unless current
|
|
109
|
+
|
|
110
|
+
prepare_without_profiling(*args,&blk)
|
|
111
|
+
end
|
|
94
112
|
|
|
95
113
|
def exec(*args,&blk)
|
|
96
114
|
current = ::Rack::MiniProfiler.current
|
|
@@ -104,6 +122,34 @@ if SqlPatches.class_exists? "PG::Result"
|
|
|
104
122
|
result
|
|
105
123
|
end
|
|
106
124
|
|
|
125
|
+
def exec_prepared(*args,&blk)
|
|
126
|
+
current = ::Rack::MiniProfiler.current
|
|
127
|
+
return exec_prepared_without_profiling(*args,&blk) unless current
|
|
128
|
+
|
|
129
|
+
start = Time.now
|
|
130
|
+
result = exec_prepared_without_profiling(*args,&blk)
|
|
131
|
+
elapsed_time = ((Time.now - start).to_f * 1000).round(1)
|
|
132
|
+
mapped = args[0]
|
|
133
|
+
mapped = @prepare_map[mapped] || args[0] if @prepare_map
|
|
134
|
+
result.instance_variable_set("@miniprofiler_sql_id", ::Rack::MiniProfiler.record_sql(mapped, elapsed_time))
|
|
135
|
+
|
|
136
|
+
result
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def send_query_prepared(*args,&blk)
|
|
140
|
+
current = ::Rack::MiniProfiler.current
|
|
141
|
+
return send_query_prepared_without_profiling(*args,&blk) unless current
|
|
142
|
+
|
|
143
|
+
start = Time.now
|
|
144
|
+
result = send_query_prepared_without_profiling(*args,&blk)
|
|
145
|
+
elapsed_time = ((Time.now - start).to_f * 1000).round(1)
|
|
146
|
+
mapped = args[0]
|
|
147
|
+
mapped = @prepare_map[mapped] || args[0] if @prepare_map
|
|
148
|
+
result.instance_variable_set("@miniprofiler_sql_id", ::Rack::MiniProfiler.record_sql(mapped, elapsed_time))
|
|
149
|
+
|
|
150
|
+
result
|
|
151
|
+
end
|
|
152
|
+
|
|
107
153
|
def async_exec(*args,&blk)
|
|
108
154
|
current = ::Rack::MiniProfiler.current
|
|
109
155
|
return exec_without_profiling(*args,&blk) unless current
|
data/lib/rack-mini-profiler.rb
CHANGED
|
File without changes
|
data/rack-mini-profiler.gemspec
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = "rack-mini-profiler"
|
|
3
|
-
s.version = "0.1.
|
|
3
|
+
s.version = "0.1.15.pre"
|
|
4
4
|
s.summary = "Profiles loading speed for rack applications."
|
|
5
5
|
s.authors = ["Aleks Totic","Sam Saffron", "Robin Ward"]
|
|
6
6
|
s.description = "Page loading speed displayed on every page. Optimize while you develop, performance is a feature."
|
metadata
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rack-mini-profiler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.1.15.pre
|
|
5
|
+
prerelease: 7
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Aleks Totic
|
|
@@ -11,7 +11,7 @@ authors:
|
|
|
11
11
|
autorequire:
|
|
12
12
|
bindir: bin
|
|
13
13
|
cert_chain: []
|
|
14
|
-
date: 2012-
|
|
14
|
+
date: 2012-09-04 00:00:00.000000000 Z
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
17
17
|
name: rack
|
|
@@ -91,6 +91,7 @@ files:
|
|
|
91
91
|
- lib/mini_profiler/request_timer_struct.rb
|
|
92
92
|
- lib/mini_profiler/timer_struct.rb
|
|
93
93
|
- lib/mini_profiler/page_timer_struct.rb
|
|
94
|
+
- lib/mini_profiler/client_settings.rb
|
|
94
95
|
- lib/mini_profiler/context.rb
|
|
95
96
|
- lib/mini_profiler/config.rb
|
|
96
97
|
- lib/mini_profiler/profiling_methods.rb
|
|
@@ -130,16 +131,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
130
131
|
version: '0'
|
|
131
132
|
segments:
|
|
132
133
|
- 0
|
|
133
|
-
hash:
|
|
134
|
+
hash: 439688077
|
|
134
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
136
|
none: false
|
|
136
137
|
requirements:
|
|
137
|
-
- - ! '
|
|
138
|
+
- - ! '>'
|
|
138
139
|
- !ruby/object:Gem::Version
|
|
139
|
-
version:
|
|
140
|
-
segments:
|
|
141
|
-
- 0
|
|
142
|
-
hash: -296105007
|
|
140
|
+
version: 1.3.1
|
|
143
141
|
requirements: []
|
|
144
142
|
rubyforge_project:
|
|
145
143
|
rubygems_version: 1.8.24
|