rack-mini-profiler 0.1.26 → 0.1.27

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 943d309dfe7e69d839ea284e6c9d525e61e5411e
4
- data.tar.gz: bdf30a92d384c74ab69e5d5c19ca853135100d77
3
+ metadata.gz: 6cc0ebab51bb03cdde11e69f1c1b2d4f204e6c04
4
+ data.tar.gz: 704a46d89f38d3a956d193a9913bc00321299453
5
5
  SHA512:
6
- metadata.gz: db02f40f91da2a44a6e0d001d24e5d12946499a1e152a20068e252ff551c57627196648ee3b101fa4d746a0752e431497658c74610b37fb36b8e4e4061c4e71a
7
- data.tar.gz: 5ca22681b6b47bdb4b0e1d5929a9199e7b4b8974d144a9d318b737e6c5988929d11aeff8dd06f890f7975093c63c3eeb8c8ebbc799121aca290f713306eb0f03
6
+ metadata.gz: 0c084c48f8a7ca7bf9ad5a85f608e66b212b1e874c295a8c8b9a238887064e7a00c4a5e6edae2f2dfb73f958ba0972fcf7b8f74c69c920471627df6dba17b69b
7
+ data.tar.gz: 0c99b98715befd9127dc3da931682d2eded099d70b31bc74d134695d4d7e5b11a96c9a4c22b202e572f6ac2198d212dde015c218a8ad8747acb8ff4947baca7e
@@ -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
 
@@ -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="http://code.jquery.com/jquery-1.9.1.min.js"></script>
5
- <script src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.0.8/d3.min.js"></script>
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
- return "(" + samples +
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
 
@@ -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'] = nil
276
- env['HTTP_IF_NONE_MATCH'] = nil
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
- # inject script
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
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class MiniProfiler
3
- VERSION = 'e777c6e0fdfb9a725e857c8ca3eab18f'.freeze
3
+ VERSION = 'cc5e38497a61f98499f27184d21dbcd1'.freeze
4
4
  end
5
5
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rack-mini-profiler"
3
- s.version = "0.1.26"
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.26
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-04-11 00:00:00.000000000 Z
13
+ date: 2013-06-26 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack