rack-mini-profiler 0.1.26 → 0.1.27
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rack-mini-profiler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Ruby/CHANGELOG +6 -0
- data/Ruby/README.md +7 -0
- data/Ruby/lib/html/flamegraph.html +32 -6
- data/Ruby/lib/html/includes.js +2 -1
- data/Ruby/lib/mini_profiler/config.rb +2 -1
- data/Ruby/lib/mini_profiler/flame_graph.rb +4 -4
- data/Ruby/lib/mini_profiler/profiler.rb +13 -16
- data/Ruby/lib/mini_profiler/sql_timer_struct.rb +1 -1
- data/Ruby/lib/mini_profiler/version.rb +1 -1
- data/rack-mini-profiler.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6cc0ebab51bb03cdde11e69f1c1b2d4f204e6c04
|
4
|
+
data.tar.gz: 704a46d89f38d3a956d193a9913bc00321299453
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c084c48f8a7ca7bf9ad5a85f608e66b212b1e874c295a8c8b9a238887064e7a00c4a5e6edae2f2dfb73f958ba0972fcf7b8f74c69c920471627df6dba17b69b
|
7
|
+
data.tar.gz: 0c99b98715befd9127dc3da931682d2eded099d70b31bc74d134695d4d7e5b11a96c9a4c22b202e572f6ac2198d212dde015c218a8ad8747acb8ff4947baca7e
|
data/Ruby/CHANGELOG
CHANGED
@@ -131,5 +131,11 @@
|
|
131
131
|
* 1.26
|
132
132
|
* (minor) allow Rack::MiniProfilerRails.initialize!(Rails.application), for post config intialization
|
133
133
|
|
134
|
+
26-June-2013
|
135
|
+
* 1.27
|
136
|
+
* Disable global ajax handlers on MP requests @JP
|
137
|
+
* Add Rack::MiniProfiler.config.backtrace_threshold_ms
|
138
|
+
* jQuery 2.0 support
|
139
|
+
|
134
140
|
|
135
141
|
|
data/Ruby/README.md
CHANGED
@@ -111,8 +111,14 @@ You can set configuration options using the configuration accessor on Rack::Mini
|
|
111
111
|
```
|
112
112
|
# Have Mini Profiler show up on the right
|
113
113
|
Rack::MiniProfiler.config.position = 'right'
|
114
|
+
# Have Mini Profiler start in hidden mode - display with short cut (defaulted to 'Alt+P')
|
115
|
+
Rack::MiniProfiler.config.start_hidden = true
|
116
|
+
# Don't collect backtraces on SQL queries that take less than 5 ms to execute
|
117
|
+
# (necessary on Rubies earlier than 2.0)
|
118
|
+
Rack::MiniProfiler.config.backtrace_threshold_ms = 5
|
114
119
|
```
|
115
120
|
|
121
|
+
|
116
122
|
In a Rails app, this can be done conveniently in an initializer such as config/initializers/mini_profiler.rb.
|
117
123
|
|
118
124
|
## Rails 2.X support
|
@@ -154,6 +160,7 @@ end
|
|
154
160
|
* backtrace_filter - a regex you can use to filter out unwanted lines from the backtraces
|
155
161
|
* toggle_shortcut (default Alt+P) - a jquery.hotkeys.js-style keyboard shortcut, used to toggle the mini_profiler's visibility. See http://code.google.com/p/js-hotkeys/ for more info.
|
156
162
|
* start_hidden (default false) - Whether or not you want the mini_profiler to be visible when loading a page
|
163
|
+
* backtrace_threshold_ms (default zero) - Minimum SQL query elapsed time before a backtrace is recorded. Backtrace recording can take a couple of milliseconds on rubies earlier than 2.0, impacting performance for very small queries.
|
157
164
|
|
158
165
|
## Special query strings
|
159
166
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html>
|
3
3
|
<head>
|
4
|
-
<script src="
|
5
|
-
<script src="
|
4
|
+
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
5
|
+
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.0.8/d3.min.js"></script>
|
6
6
|
<!-- <script src="http://cdnjs.cloudflare.com/ajax/libs/sugar/1.3.8/sugar.min.js"></script> -->
|
7
7
|
<meta charset=utf-8 />
|
8
8
|
<title>Flame Graph of Page</title>
|
@@ -168,15 +168,21 @@ Array.prototype.getUnique = function() {
|
|
168
168
|
return a
|
169
169
|
}
|
170
170
|
|
171
|
-
var samplePercent = function(samples){
|
172
|
-
|
171
|
+
var samplePercent = function(samples, exclusive){
|
172
|
+
var info = " (" + samples +
|
173
173
|
" sample" + (samples == 1 ? "" : "s") + " - " +
|
174
|
-
((samples / maxX) * 100).toFixed(2) + "%)";
|
174
|
+
((samples / maxX) * 100).toFixed(2) + "%) ";
|
175
|
+
if (exclusive) {
|
176
|
+
info += " (" + exclusive +
|
177
|
+
" exclusive - " +
|
178
|
+
((exclusive / maxX) * 100).toFixed(2) + "%) ";
|
179
|
+
}
|
180
|
+
return info;
|
175
181
|
}
|
176
182
|
|
177
183
|
var mouseover = function(d) {
|
178
184
|
var i = info[d.frame];
|
179
|
-
$('.info').text( d.frame + " " + samplePercent(i.samples.length));
|
185
|
+
$('.info').text( d.frame + " " + samplePercent(i.samples.length, d.topFrame ? d.topFrame.exclusiveCount : 0));
|
180
186
|
d3.selectAll(i.nodes)
|
181
187
|
.attr('opacity',0.5);
|
182
188
|
};
|
@@ -212,6 +218,8 @@ var rainbow = function(numOfSteps, step) {
|
|
212
218
|
|
213
219
|
// assign some colors, analyze samples per gem
|
214
220
|
var gemStats = {}
|
221
|
+
var topFrames = {}
|
222
|
+
var lastFrame = {frame: 'd52e04d-df28-41ed-a215-b6ec840a8ea5', x: -1}
|
215
223
|
|
216
224
|
$.each(data, function(){
|
217
225
|
|
@@ -226,8 +234,26 @@ $.each(data, function(){
|
|
226
234
|
for(var j=0; j < this.width; j++){
|
227
235
|
stat.samples.push(this.x + j);
|
228
236
|
}
|
237
|
+
// This assumes the traversal is in order
|
238
|
+
if (lastFrame.x != this.x) {
|
239
|
+
var topFrame = topFrames[lastFrame.frame]
|
240
|
+
if (!topFrame) {
|
241
|
+
topFrames[lastFrame.frame] = topFrame = {exclusiveCount: 0}
|
242
|
+
}
|
243
|
+
topFrame.exclusiveCount += 1;
|
244
|
+
lastFrame.topFrame = topFrame;
|
245
|
+
}
|
246
|
+
lastFrame = this;
|
247
|
+
|
229
248
|
});
|
230
249
|
|
250
|
+
var topFrame = topFrames[lastFrame.frame]
|
251
|
+
if (!topFrame) {
|
252
|
+
topFrames[lastFrame.frame] = topFrame = {exclusiveCount: 0}
|
253
|
+
}
|
254
|
+
topFrame.exclusiveCount += 1;
|
255
|
+
lastFrame.topFrame = topFrame;
|
256
|
+
|
231
257
|
var totalGems = 0;
|
232
258
|
$.each(gemStats, function(){totalGems++;});
|
233
259
|
|
data/Ruby/lib/html/includes.js
CHANGED
@@ -126,6 +126,7 @@ var MiniProfiler = (function () {
|
|
126
126
|
url: options.path + 'results',
|
127
127
|
data: { id: id, clientPerformance: clientPerformance, clientProbes: clientProbes, popup: 1 },
|
128
128
|
dataType: 'json',
|
129
|
+
global: false,
|
129
130
|
type: 'POST',
|
130
131
|
success: function (json) {
|
131
132
|
fetchedIds.push(id);
|
@@ -657,7 +658,7 @@ var MiniProfiler = (function () {
|
|
657
658
|
if (typeof(jQuery) == 'function') {
|
658
659
|
var jQueryVersion = jQuery.fn.jquery.split('.');
|
659
660
|
}
|
660
|
-
if (jQueryVersion && parseInt(jQueryVersion[0]) < 2 && parseInt(jQueryVersion[1]) >= 7) {
|
661
|
+
if (jQueryVersion && (parseInt(jQueryVersion[0]) == 2) || (parseInt(jQueryVersion[0]) < 2 && parseInt(jQueryVersion[1]) >= 7)) {
|
661
662
|
MiniProfiler.jQuery = $ = jQuery;
|
662
663
|
$(deferInit);
|
663
664
|
} else {
|
@@ -15,7 +15,7 @@ module Rack
|
|
15
15
|
attr_accessor :auto_inject, :base_url_path, :pre_authorize_cb, :position,
|
16
16
|
:backtrace_remove, :backtrace_includes, :backtrace_ignores, :skip_schema_queries,
|
17
17
|
:storage, :user_provider, :storage_instance, :storage_options, :skip_paths, :authorization_mode,
|
18
|
-
:toggle_shortcut, :start_hidden
|
18
|
+
:toggle_shortcut, :start_hidden, :backtrace_threshold_ms
|
19
19
|
|
20
20
|
# Deprecated options
|
21
21
|
attr_accessor :use_existing_jquery
|
@@ -36,6 +36,7 @@ module Rack
|
|
36
36
|
@authorization_mode = :allow_all
|
37
37
|
@toggle_shortcut = 'Alt+P'
|
38
38
|
@start_hidden = false
|
39
|
+
@backtrace_threshold_ms = 0
|
39
40
|
self
|
40
41
|
}
|
41
42
|
end
|
@@ -6,9 +6,9 @@ class Rack::MiniProfiler::FlameGraph
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def graph_data
|
9
|
-
height = 0
|
9
|
+
height = 0
|
10
10
|
|
11
|
-
table = []
|
11
|
+
table = []
|
12
12
|
prev = []
|
13
13
|
|
14
14
|
# a 2d array makes collapsing easy
|
@@ -17,7 +17,7 @@ class Rack::MiniProfiler::FlameGraph
|
|
17
17
|
|
18
18
|
stack.reverse.map{|r| r.to_s}.each_with_index do |frame, i|
|
19
19
|
|
20
|
-
if !prev[i].nil?
|
20
|
+
if !prev[i].nil?
|
21
21
|
last_col = prev[i]
|
22
22
|
if last_col[0] == frame
|
23
23
|
last_col[1] += 1
|
@@ -26,7 +26,7 @@ class Rack::MiniProfiler::FlameGraph
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
prev[i] = [frame, 1]
|
29
|
+
prev[i] = [frame, 1]
|
30
30
|
col << prev[i]
|
31
31
|
end
|
32
32
|
prev = prev[0..col.length-1].to_a
|
@@ -123,7 +123,7 @@ module Rack
|
|
123
123
|
|
124
124
|
# Otherwise give the HTML back
|
125
125
|
html = MiniProfiler.share_template.dup
|
126
|
-
html.gsub!(/\{path\}/, @config.base_url_path)
|
126
|
+
html.gsub!(/\{path\}/, "#{env['SCRIPT_NAME']}#{@config.base_url_path}")
|
127
127
|
html.gsub!(/\{version\}/, MiniProfiler::VERSION)
|
128
128
|
html.gsub!(/\{json\}/, result_json)
|
129
129
|
html.gsub!(/\{includes\}/, get_profile_script(env))
|
@@ -239,7 +239,7 @@ module Rack
|
|
239
239
|
done_sampling = false
|
240
240
|
quit_sampler = false
|
241
241
|
backtraces = nil
|
242
|
-
|
242
|
+
|
243
243
|
if query_string =~ /pp=sample/ || query_string =~ /pp=flamegraph/
|
244
244
|
current.measure = false
|
245
245
|
skip_frames = 0
|
@@ -255,7 +255,7 @@ module Rack
|
|
255
255
|
break if done_sampling
|
256
256
|
i -= 1
|
257
257
|
backtraces << (has_backtrace_locations ? t.backtrace_locations : t.backtrace)
|
258
|
-
|
258
|
+
|
259
259
|
# On my machine using Ruby 2.0 this give me excellent fidelity of stack trace per 1.2ms
|
260
260
|
# with this fidelity analysis becomes very powerful
|
261
261
|
sleep 0.0005
|
@@ -272,8 +272,8 @@ module Rack
|
|
272
272
|
|
273
273
|
# Strip all the caching headers so we don't get 304s back
|
274
274
|
# This solves a very annoying bug where rack mini profiler never shows up
|
275
|
-
env['HTTP_IF_MODIFIED_SINCE'] =
|
276
|
-
env['HTTP_IF_NONE_MATCH'] =
|
275
|
+
env['HTTP_IF_MODIFIED_SINCE'] = ''
|
276
|
+
env['HTTP_IF_NONE_MATCH'] = ''
|
277
277
|
|
278
278
|
status,headers,body = @app.call(env)
|
279
279
|
client_settings.write!(headers)
|
@@ -316,7 +316,7 @@ module Rack
|
|
316
316
|
body.close if body.respond_to? :close
|
317
317
|
if query_string =~ /pp=sample/
|
318
318
|
return analyze(backtraces, page_struct)
|
319
|
-
else
|
319
|
+
else
|
320
320
|
return flame_graph(backtraces, page_struct)
|
321
321
|
end
|
322
322
|
end
|
@@ -326,8 +326,9 @@ module Rack
|
|
326
326
|
@storage.set_unviewed(page_struct['User'], page_struct['Id'])
|
327
327
|
@storage.save(page_struct)
|
328
328
|
|
329
|
+
content_type = headers['Content-Type']
|
329
330
|
# inject headers, script
|
330
|
-
if status == 200
|
331
|
+
if content_type && status == 200
|
331
332
|
|
332
333
|
client_settings.write!(headers)
|
333
334
|
|
@@ -342,11 +343,7 @@ module Rack
|
|
342
343
|
headers['X-MiniProfiler-Ids'] = ids_json(env)
|
343
344
|
end
|
344
345
|
|
345
|
-
|
346
|
-
if current.inject_js \
|
347
|
-
&& headers.has_key?('Content-Type') \
|
348
|
-
&& !headers['Content-Type'].match(/text\/html/).nil? then
|
349
|
-
|
346
|
+
if current.inject_js && content_type =~ /text\/html/
|
350
347
|
response = Rack::Response.new([], status, headers)
|
351
348
|
script = self.get_profile_script(env)
|
352
349
|
|
@@ -388,9 +385,9 @@ module Rack
|
|
388
385
|
index = 1
|
389
386
|
fragment.gsub(regex) do
|
390
387
|
# though malformed there is an edge case where /body exists earlier in the html, work around
|
391
|
-
if index < matches
|
388
|
+
if index < matches
|
392
389
|
index += 1
|
393
|
-
close_tag
|
390
|
+
close_tag
|
394
391
|
else
|
395
392
|
|
396
393
|
# if for whatever crazy reason we dont get a utf string,
|
@@ -451,7 +448,7 @@ module Rack
|
|
451
448
|
data = graph.graph_data
|
452
449
|
|
453
450
|
headers = {'Content-Type' => 'text/html'}
|
454
|
-
|
451
|
+
|
455
452
|
body = IO.read(::File.expand_path('../html/flamegraph.html', ::File.dirname(__FILE__)))
|
456
453
|
body.gsub!("/*DATA*/", ::JSON.generate(data));
|
457
454
|
|
@@ -511,7 +508,7 @@ module Rack
|
|
511
508
|
# * you do not want script to be automatically appended for the current page. You can also call cancel_auto_inject
|
512
509
|
def get_profile_script(env)
|
513
510
|
ids = ids_comma_separated(env)
|
514
|
-
path = @config.base_url_path
|
511
|
+
path = "#{env['SCRIPT_NAME']}#{@config.base_url_path}"
|
515
512
|
version = MiniProfiler::VERSION
|
516
513
|
position = @config.position
|
517
514
|
showTrivial = false
|
@@ -8,7 +8,7 @@ module Rack
|
|
8
8
|
def initialize(query, duration_ms, page, parent, skip_backtrace = false, full_backtrace = false)
|
9
9
|
|
10
10
|
stack_trace = nil
|
11
|
-
unless skip_backtrace
|
11
|
+
unless skip_backtrace || duration_ms < Rack::MiniProfiler.config.backtrace_threshold_ms
|
12
12
|
# Allow us to filter the stack trace
|
13
13
|
stack_trace = ""
|
14
14
|
# Clean up the stack trace if there are options to do so
|
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.27"
|
4
4
|
s.summary = "Profiles loading speed for rack applications."
|
5
5
|
s.authors = ["Sam Saffron", "Robin Ward","Aleks Totic"]
|
6
6
|
s.description = "Profiling toolkit for Rack applications with Rails integration. Client Side profiling, DB profiling and Server profiling."
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-mini-profiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.27
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-06-26 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rack
|