rack-mini-profiler 0.1.11.pre → 0.1.16
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.
Potentially problematic release.
This version of rack-mini-profiler might be problematic. Click here for more details.
- data/CHANGELOG +29 -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 +2 -2
- 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 +64 -62
- data/lib/mini_profiler/profiling_methods.rb +17 -6
- 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 -1
- data/lib/mini_profiler/storage/memory_store.rb +1 -2
- data/lib/mini_profiler/storage/redis_store.rb +0 -0
- data/lib/mini_profiler_rails/railtie.rb +1 -1
- data/lib/patches/sql_patches.rb +7 -6
- data/lib/rack-mini-profiler.rb +0 -0
- data/rack-mini-profiler.gemspec +1 -1
- metadata +10 -6
data/CHANGELOG
CHANGED
@@ -47,3 +47,32 @@
|
|
47
47
|
10-August-2012 - Sam
|
48
48
|
|
49
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
|
72
|
+
|
73
|
+
5-September-2012 - Sam
|
74
|
+
|
75
|
+
* 1.16
|
76
|
+
* fixed long standing problem specs (issue with memory store)
|
77
|
+
* fixed issue where profiler would be dumped when you got a 404 in production (and any time rails is bypassed)
|
78
|
+
* implemented stacktrace 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
@@ -138,7 +138,7 @@
|
|
138
138
|
</td>
|
139
139
|
|
140
140
|
{{if HasSqlTimings}}
|
141
|
-
<td class="profiler-duration {{if HasDuplicateSqlTimings}}profiler-warning{{/if}}" title="{{if HasDuplicateSqlTimings}}duplicate queries detected - {{/if}}${ExecutedReaders} reader, ${ExecutedScalars} scalar, ${ExecutedNonQueries} non-query statements executed">
|
141
|
+
<td class="profiler-duration {{if HasDuplicateSqlTimings}}profiler-warning{{/if}}" title="{{if HasDuplicateSqlTimings}}duplicate queries detected - {{/if}}{{if ExecutedReaders > 0 || ExecutedScalars > 0 || ExecutedNonQueries > 0}}${ExecutedReaders} reader, ${ExecutedScalars} scalar, ${ExecutedNonQueries} non-query statements executed{{/if}}">
|
142
142
|
<a class="profiler-queries-show">
|
143
143
|
{{if HasDuplicateSqlTimings}}<span class="profiler-nuclear">!</span>{{/if}}
|
144
144
|
${SqlTimings.length} <span class="profiler-unit">sql</span>
|
@@ -192,4 +192,4 @@
|
|
192
192
|
</td>
|
193
193
|
</tr>
|
194
194
|
|
195
|
-
</script>
|
195
|
+
</script>
|
@@ -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 = '107'.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,9 @@ module Rack
|
|
195
167
|
|
196
168
|
|
197
169
|
def call(env)
|
170
|
+
|
171
|
+
client_settings = ClientSettings.new(env)
|
172
|
+
|
198
173
|
status = headers = body = nil
|
199
174
|
query_string = env['QUERY_STRING']
|
200
175
|
path = env['PATH_INFO']
|
@@ -203,12 +178,12 @@ module Rack
|
|
203
178
|
(@config.skip_paths && @config.skip_paths.any?{ |p| path[0,p.length] == p}) ||
|
204
179
|
query_string =~ /pp=skip/
|
205
180
|
|
206
|
-
has_profiling_cookie =
|
181
|
+
has_profiling_cookie = client_settings.has_cookie?
|
207
182
|
|
208
183
|
if skip_it || (@config.authorization_mode == :whitelist && !has_profiling_cookie)
|
209
184
|
status,headers,body = @app.call(env)
|
210
185
|
if !skip_it && @config.authorization_mode == :whitelist && !has_profiling_cookie && MiniProfiler.request_authorized?
|
211
|
-
|
186
|
+
client_settings.write!(headers)
|
212
187
|
end
|
213
188
|
return [status,headers,body]
|
214
189
|
end
|
@@ -216,7 +191,7 @@ module Rack
|
|
216
191
|
# handle all /mini-profiler requests here
|
217
192
|
return serve_html(env) if path.start_with? @config.base_url_path
|
218
193
|
|
219
|
-
has_disable_cookie =
|
194
|
+
has_disable_cookie = client_settings.disable_profiling?
|
220
195
|
# manual session disable / enable
|
221
196
|
if query_string =~ /pp=disable/ || has_disable_cookie
|
222
197
|
skip_it = true
|
@@ -228,38 +203,52 @@ module Rack
|
|
228
203
|
|
229
204
|
if skip_it
|
230
205
|
status,headers,body = @app.call(env)
|
231
|
-
|
206
|
+
client_settings.disable_profiling = true
|
207
|
+
client_settings.write!(headers)
|
232
208
|
return [status,headers,body]
|
233
209
|
end
|
234
210
|
|
235
211
|
MiniProfiler.create_current(env, @config)
|
236
212
|
MiniProfiler.deauthorize_request if @config.authorization_mode == :whitelist
|
237
|
-
if query_string =~ /pp=
|
213
|
+
if query_string =~ /pp=normal-backtrace/
|
214
|
+
client_settings.backtrace_level = ClientSettings::BACKTRACE_DEFAULT
|
215
|
+
elsif query_string =~ /pp=no-backtrace/
|
238
216
|
current.skip_backtrace = true
|
239
|
-
|
217
|
+
client_settings.backtrace_level = ClientSettings::BACKTRACE_NONE
|
218
|
+
elsif query_string =~ /pp=full-backtrace/ || client_settings.backtrace_full?
|
240
219
|
current.full_backtrace = true
|
220
|
+
client_settings.backtrace_level = ClientSettings::BACKTRACE_FULL
|
221
|
+
elsif client_settings.backtrace_none?
|
222
|
+
current.skip_backtrace = true
|
241
223
|
end
|
242
224
|
|
243
225
|
done_sampling = false
|
244
226
|
quit_sampler = false
|
245
227
|
backtraces = nil
|
246
|
-
|
228
|
+
stacktrace_installed = true
|
247
229
|
if query_string =~ /pp=sample/
|
230
|
+
skip_frames = 0
|
248
231
|
backtraces = []
|
249
232
|
t = Thread.current
|
233
|
+
|
234
|
+
begin
|
235
|
+
require 'stacktrace'
|
236
|
+
skip_frames = stacktrace.length
|
237
|
+
rescue
|
238
|
+
stacktrace_installed = false
|
239
|
+
end
|
240
|
+
|
250
241
|
Thread.new {
|
251
242
|
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
243
|
i = 10000 # for sanity never grab more than 10k samples
|
259
244
|
while i > 0
|
260
245
|
break if done_sampling
|
261
246
|
i -= 1
|
262
|
-
|
247
|
+
if stacktrace_installed
|
248
|
+
backtraces << t.stacktrace(0,-(1+skip_frames), StackFrame::Flags::METHOD | StackFrame::Flags::KLASS)
|
249
|
+
else
|
250
|
+
backtraces << t.backtrace
|
251
|
+
end
|
263
252
|
sleep 0.001
|
264
253
|
end
|
265
254
|
ensure
|
@@ -271,10 +260,14 @@ module Rack
|
|
271
260
|
status, headers, body = nil
|
272
261
|
start = Time.now
|
273
262
|
begin
|
263
|
+
|
264
|
+
# Strip all the caching headers so we don't get 304s back
|
265
|
+
# This solves a very annoying bug where rack mini profiler never shows up
|
266
|
+
env['HTTP_IF_MODIFIED_SINCE'] = nil
|
267
|
+
env['HTTP_IF_NONE_MATCH'] = nil
|
268
|
+
|
274
269
|
status,headers,body = @app.call(env)
|
275
|
-
|
276
|
-
MiniProfiler.remove_disable_profiling_cookie(headers)
|
277
|
-
end
|
270
|
+
client_settings.write!(headers)
|
278
271
|
ensure
|
279
272
|
if backtraces
|
280
273
|
done_sampling = true
|
@@ -284,10 +277,14 @@ module Rack
|
|
284
277
|
|
285
278
|
skip_it = current.discard
|
286
279
|
if (config.authorization_mode == :whitelist && !MiniProfiler.request_authorized?)
|
287
|
-
|
280
|
+
# this is non-obvious, don't kill the profiling cookie on errors or short requests
|
281
|
+
# this ensures that stuff that never reaches the rails stack does not kill profiling
|
282
|
+
if status == 200 && ((Time.now - start) > 0.1)
|
283
|
+
client_settings.discard_cookie!(headers)
|
284
|
+
end
|
288
285
|
skip_it = true
|
289
286
|
end
|
290
|
-
|
287
|
+
|
291
288
|
return [status,headers,body] if skip_it
|
292
289
|
|
293
290
|
# we must do this here, otherwise current[:discard] is not being properly treated
|
@@ -298,7 +295,7 @@ module Rack
|
|
298
295
|
|
299
296
|
if query_string =~ /pp=help/
|
300
297
|
body.close if body.respond_to? :close
|
301
|
-
return help
|
298
|
+
return help(nil, client_settings)
|
302
299
|
end
|
303
300
|
|
304
301
|
page_struct = current.page_struct
|
@@ -306,7 +303,6 @@ module Rack
|
|
306
303
|
|
307
304
|
if backtraces
|
308
305
|
body.close if body.respond_to? :close
|
309
|
-
return help(:stacktrace) if missing_stacktrace
|
310
306
|
return analyze(backtraces, page_struct)
|
311
307
|
end
|
312
308
|
|
@@ -317,6 +313,8 @@ module Rack
|
|
317
313
|
|
318
314
|
# inject headers, script
|
319
315
|
if status == 200
|
316
|
+
|
317
|
+
client_settings.write!(headers)
|
320
318
|
|
321
319
|
# mini profiler is meddling with stuff, we can not cache cause we will get incorrect data
|
322
320
|
# Rack::ETag has already inserted some nonesense in the chain
|
@@ -346,6 +344,7 @@ module Rack
|
|
346
344
|
end
|
347
345
|
end
|
348
346
|
|
347
|
+
client_settings.write!(headers)
|
349
348
|
[status, headers, body]
|
350
349
|
ensure
|
351
350
|
# Make sure this always happens
|
@@ -373,16 +372,17 @@ module Rack
|
|
373
372
|
[200, headers, [body]]
|
374
373
|
end
|
375
374
|
|
376
|
-
def help(category = nil)
|
375
|
+
def help(category = nil, client_settings)
|
377
376
|
headers = {'Content-Type' => 'text/plain'}
|
378
377
|
body = "Append the following to your query string:
|
379
378
|
|
380
379
|
pp=help : display this screen
|
381
380
|
pp=env : display the rack environment
|
382
381
|
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=
|
382
|
+
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)
|
383
|
+
pp=normal-backtrace #{"(*) " if client_settings.backtrace_default?}: collect stack traces from all the SQL executed and filter normally
|
384
|
+
pp=full-backtrace #{"(*) " if client_settings.backtrace_full?}: enable full backtraces for SQL executed (use pp=normal-backtrace to disable)
|
385
|
+
pp=sample : sample stack traces and return a report isolating heavy usage (experimental works best with the stacktrace gem)
|
386
386
|
pp=disable : disable profiling for this session
|
387
387
|
pp=enable : enable profiling for this session (if previously disabled)
|
388
388
|
"
|
@@ -390,6 +390,7 @@ module Rack
|
|
390
390
|
body = "pp=stacktrace requires the stacktrace gem - add gem 'stacktrace' to your Gemfile"
|
391
391
|
end
|
392
392
|
|
393
|
+
client_settings.write!(headers)
|
393
394
|
[200, headers, [body]]
|
394
395
|
end
|
395
396
|
|
@@ -403,13 +404,13 @@ module Rack
|
|
403
404
|
fulldump << "\n\n"
|
404
405
|
distinct = {}
|
405
406
|
trace.each do |frame|
|
406
|
-
|
407
|
-
unless distinct[
|
408
|
-
distinct[
|
409
|
-
seen[
|
410
|
-
seen[
|
407
|
+
frame = "#{frame.klass}::#{frame.method}" unless String === frame
|
408
|
+
unless distinct[frame]
|
409
|
+
distinct[frame] = true
|
410
|
+
seen[frame] ||= 0
|
411
|
+
seen[frame] += 1
|
411
412
|
end
|
412
|
-
fulldump <<
|
413
|
+
fulldump << frame << "\n"
|
413
414
|
end
|
414
415
|
end
|
415
416
|
|
@@ -427,7 +428,8 @@ module Rack
|
|
427
428
|
end
|
428
429
|
|
429
430
|
def ids_json(env)
|
430
|
-
ids
|
431
|
+
# cap at 10 ids, otherwise there is a chance you can blow the header
|
432
|
+
ids = [current.page_struct["Id"]] + (@storage.get_unviewed_ids(user(env)) || [])[0..8]
|
431
433
|
::JSON.generate(ids.uniq)
|
432
434
|
end
|
433
435
|
|
@@ -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,15 +20,17 @@ 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
|
27
26
|
end
|
28
27
|
|
29
28
|
def unprofile_method(klass, method)
|
30
|
-
|
31
|
-
|
29
|
+
|
30
|
+
clean = clean_method_name(method)
|
31
|
+
|
32
|
+
with_profiling = ("#{clean}_with_mini_profiler").intern
|
33
|
+
without_profiling = ("#{clean}_without_mini_profiler").intern
|
32
34
|
|
33
35
|
if klass.send :method_defined?, with_profiling
|
34
36
|
klass.send :alias_method, method, without_profiling
|
@@ -39,8 +41,10 @@ module Rack
|
|
39
41
|
|
40
42
|
def profile_method(klass, method, &blk)
|
41
43
|
default_name = klass.to_s + " " + method.to_s
|
42
|
-
|
43
|
-
|
44
|
+
clean = clean_method_name(method)
|
45
|
+
|
46
|
+
with_profiling = ("#{clean}_with_mini_profiler").intern
|
47
|
+
without_profiling = ("#{clean}_without_mini_profiler").intern
|
44
48
|
|
45
49
|
if klass.send :method_defined?, with_profiling
|
46
50
|
return # dont double profile
|
@@ -68,6 +72,13 @@ module Rack
|
|
68
72
|
end
|
69
73
|
klass.send :alias_method, method, with_profiling
|
70
74
|
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def clean_method_name(method)
|
79
|
+
method.to_s.gsub(/[\?\!]/, "")
|
80
|
+
end
|
81
|
+
|
71
82
|
end
|
72
83
|
end
|
73
84
|
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
|
@@ -55,10 +55,9 @@ module Rack
|
|
55
55
|
def cleanup_cache
|
56
56
|
expire_older_than = ((Time.now.to_f - MiniProfiler::MemoryStore::EXPIRE_TIMER_CACHE) * 1000).to_i
|
57
57
|
@timer_struct_lock.synchronize {
|
58
|
-
@timer_struct_cache.delete_if { |k, v| v['
|
58
|
+
@timer_struct_cache.delete_if { |k, v| v['Started'] < expire_older_than }
|
59
59
|
}
|
60
60
|
end
|
61
|
-
|
62
61
|
end
|
63
62
|
end
|
64
63
|
end
|
File without changes
|
@@ -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
@@ -96,17 +96,18 @@ if SqlPatches.class_exists? "PG::Result"
|
|
96
96
|
alias_method :prepare_without_profiling, :prepare
|
97
97
|
|
98
98
|
def prepare(*args,&blk)
|
99
|
-
|
100
|
-
|
101
|
-
|
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
102
|
@prepare_map ||= {}
|
103
103
|
@prepare_map[args[0]] = args[1]
|
104
|
-
|
105
104
|
# dont leak more than 10k ever
|
106
|
-
@prepare_map = {} if @prepare_map.length >
|
105
|
+
@prepare_map = {} if @prepare_map.length > 1000
|
107
106
|
|
108
|
-
|
107
|
+
current = ::Rack::MiniProfiler.current
|
108
|
+
return prepare_without_profiling(*args,&blk) unless current
|
109
109
|
|
110
|
+
prepare_without_profiling(*args,&blk)
|
110
111
|
end
|
111
112
|
|
112
113
|
def exec(*args,&blk)
|
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.16"
|
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.16
|
5
|
+
prerelease:
|
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-05 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,13 +131,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
131
|
version: '0'
|
131
132
|
segments:
|
132
133
|
- 0
|
133
|
-
hash:
|
134
|
+
hash: 1044164429
|
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
|
+
version: '0'
|
141
|
+
segments:
|
142
|
+
- 0
|
143
|
+
hash: 1044164429
|
140
144
|
requirements: []
|
141
145
|
rubyforge_project:
|
142
146
|
rubygems_version: 1.8.24
|