rack-mini-profiler 0.1.8 → 0.1.13.pre

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.

data/CHANGELOG CHANGED
@@ -30,3 +30,36 @@
30
30
  * Bug fix to ensure non Rails installs have mini profiler
31
31
  * Version 0.1.7
32
32
 
33
+ 30-July-2012 - Sam
34
+
35
+ * Made compliant with ancient versions of Rack (including Rack used by Rails2)
36
+ * Fixed broken share link
37
+ * Fixed crashes on startup (in MemoryStore and FileStore)
38
+ * Version 0.1.8
39
+ * Unicode fix
40
+ * Version 0.1.9
41
+
42
+ 7-August-2012 - Sam
43
+
44
+ * Added option to disable profiler for the current session (pp=disable / pp=enable)
45
+ * yajl compatability contributed by Sven Riedel
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
data/README.md CHANGED
@@ -85,11 +85,44 @@ Rack::MiniProfiler.config.position = 'right'
85
85
 
86
86
  In a Rails app, this can be done conveniently in an initializer such as config/initializers/mini_profiler.rb.
87
87
 
88
+ ## Rails 2.X support
89
+
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
+ ```
117
+
88
118
  ## Available Options
89
119
 
90
120
  * pre_authorize_cb - A lambda callback you can set to determine whether or not mini_profiler should be visible on a given request. Default in a Rails environment is only on in development mode. If in a Rack app, the default is always on.
91
121
  * position - Can either be 'right' or 'left'. Default is 'left'.
92
122
  * skip_schema_queries - Whether or not you want to log the queries about the schema of your tables. Default is 'false', 'true' in rails development.
123
+ * use_existing_jquery - Use the version of jQuery on the page as opposed to the self contained one
124
+ * auto_inject (default true) - when false the miniprofiler script is not injected in the page
125
+ * backtrace_filter - a regex you can use to filter out unwanted lines from the backtraces
93
126
 
94
127
  ## Special query strings
95
128
 
@@ -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:hidden;background-color:#fff;}.profiler-results .profiler-queries th{font-size:17px;}
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;}
@@ -5,7 +5,8 @@ var MiniProfiler = (function ($) {
5
5
  container,
6
6
  controls,
7
7
  fetchedIds = [],
8
- fetchingIds = [] // so we never pull down a profiler twice
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 (id == options.currentId) {
77
-
78
- if (window.mPt) {
79
- clientProbes = mPt.t;
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.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.
@@ -359,7 +359,7 @@
359
359
  z-index:@zindex + 3;
360
360
  position:absolute;
361
361
  overflow-y:auto;
362
- overflow-x:hidden;
362
+ overflow-x:auto;
363
363
  background-color:#fff;
364
364
 
365
365
  th {
@@ -43,7 +43,7 @@
43
43
  {{if HasSqlTimings}}
44
44
  <td colspan="2" class="profiler-number profiler-percent-in-sql" title="${MiniProfiler.getSqlTimingsCount(Root)} queries spent ${MiniProfiler.formatDuration(DurationMillisecondsInSql)} ms of total request time">
45
45
  ${MiniProfiler.formatDuration(DurationMillisecondsInSql / DurationMilliseconds * 100)}
46
- <span class="profiler-unit">% in sql</span>
46
+ <span class="profiler-unit">% in qry</span>
47
47
  </td>
48
48
  {{/if}}
49
49
  </tr>
@@ -141,7 +141,7 @@
141
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">
142
142
  <a class="profiler-queries-show">
143
143
  {{if HasDuplicateSqlTimings}}<span class="profiler-nuclear">!</span>{{/if}}
144
- ${SqlTimings.length} <span class="profiler-unit">sql</span>
144
+ ${SqlTimings.length} <span class="profiler-unit">qry</span>
145
145
  </a>
146
146
  </td>
147
147
  <td class="profiler-duration" title="aggregate duration of all queries in this step (excludes children)">
@@ -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)
37
+ end
38
+ end
39
+
40
+ def discard_cookie!(headers)
41
+ Rack::Utils.delete_cookie_header!(headers, COOKIE_NAME)
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
@@ -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, :backtrace_filter, :skip_schema_queries,
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,6 +13,7 @@ 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
 
@@ -56,20 +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.delete_cookie_header!(headers, '__profilin')
67
- end
68
-
69
- def set_profiling_cookie(headers)
70
- Rack::Utils.set_cookie_header!(headers, '__profilin', 'stylin')
71
- end
72
-
73
60
  def create_current(env={}, options={})
74
61
  # profiling the request
75
62
  self.current = Context.new
@@ -180,54 +167,75 @@ module Rack
180
167
 
181
168
 
182
169
  def call(env)
170
+
171
+ client_settings = ClientSettings.new(env)
172
+
183
173
  status = headers = body = nil
174
+ query_string = env['QUERY_STRING']
184
175
  path = env['PATH_INFO']
185
176
 
186
177
  skip_it = (@config.pre_authorize_cb && !@config.pre_authorize_cb.call(env)) ||
187
178
  (@config.skip_paths && @config.skip_paths.any?{ |p| path[0,p.length] == p}) ||
188
- env["QUERY_STRING"] =~ /pp=skip/
179
+ query_string =~ /pp=skip/
189
180
 
190
- has_profiling_cookie = MiniProfiler.has_profiling_cookie?(env)
181
+ has_profiling_cookie = client_settings.has_cookie?
191
182
 
192
183
  if skip_it || (@config.authorization_mode == :whitelist && !has_profiling_cookie)
193
184
  status,headers,body = @app.call(env)
194
185
  if !skip_it && @config.authorization_mode == :whitelist && !has_profiling_cookie && MiniProfiler.request_authorized?
195
- MiniProfiler.set_profiling_cookie(headers)
186
+ client_settings.write!(headers)
196
187
  end
197
188
  return [status,headers,body]
198
189
  end
199
190
 
200
191
  # handle all /mini-profiler requests here
201
- return serve_html(env) if env['PATH_INFO'].start_with? @config.base_url_path
192
+ return serve_html(env) if path.start_with? @config.base_url_path
193
+
194
+ has_disable_cookie = client_settings.disable_profiling?
195
+ # manual session disable / enable
196
+ if query_string =~ /pp=disable/ || has_disable_cookie
197
+ skip_it = true
198
+ end
199
+
200
+ if query_string =~ /pp=enable/
201
+ skip_it = false
202
+ end
203
+
204
+ if skip_it
205
+ status,headers,body = @app.call(env)
206
+ client_settings.disable_profiling = true
207
+ client_settings.write!(headers)
208
+ return [status,headers,body]
209
+ end
202
210
 
203
211
  MiniProfiler.create_current(env, @config)
204
212
  MiniProfiler.deauthorize_request if @config.authorization_mode == :whitelist
205
- if env["QUERY_STRING"] =~ /pp=no-backtrace/
213
+ if query_string =~ /pp=normal-backtrace/
214
+ client_settings.backtrace_level = ClientSettings::BACKTRACE_DEFAULT
215
+ elsif query_string =~ /pp=no-backtrace/
206
216
  current.skip_backtrace = true
207
- elsif env["QUERY_STRING"] =~ /pp=full-backtrace/
217
+ client_settings.backtrace_level = ClientSettings::BACKTRACE_NONE
218
+ elsif query_string =~ /pp=full-backtrace/ || client_settings.backtrace_full?
208
219
  current.full_backtrace = true
220
+ client_settings.backtrace_level = ClientSettings::BACKTRACE_FULL
221
+ elsif client_settings.backtrace_none?
222
+ current.skip_backtrace = true
209
223
  end
210
224
 
211
225
  done_sampling = false
212
226
  quit_sampler = false
213
227
  backtraces = nil
214
228
  missing_stacktrace = false
215
- if env["QUERY_STRING"] =~ /pp=sample/
229
+ if query_string =~ /pp=sample/
216
230
  backtraces = []
217
231
  t = Thread.current
218
232
  Thread.new {
219
233
  begin
220
- require 'stacktrace' rescue nil
221
- if !t.respond_to? :stacktrace
222
- missing_stacktrace = true
223
- quit_sampler = true
224
- return
225
- end
226
234
  i = 10000 # for sanity never grab more than 10k samples
227
235
  while i > 0
228
236
  break if done_sampling
229
237
  i -= 1
230
- backtraces << t.stacktrace
238
+ backtraces << t.backtrace
231
239
  sleep 0.001
232
240
  end
233
241
  ensure
@@ -240,6 +248,7 @@ module Rack
240
248
  start = Time.now
241
249
  begin
242
250
  status,headers,body = @app.call(env)
251
+ client_settings.write!(headers)
243
252
  ensure
244
253
  if backtraces
245
254
  done_sampling = true
@@ -249,21 +258,21 @@ module Rack
249
258
 
250
259
  skip_it = current.discard
251
260
  if (config.authorization_mode == :whitelist && !MiniProfiler.request_authorized?)
252
- MiniProfiler.remove_profiling_cookie(headers)
261
+ client_settings.discard_cookie!(headers)
253
262
  skip_it = true
254
263
  end
255
264
 
256
265
  return [status,headers,body] if skip_it
257
266
 
258
267
  # we must do this here, otherwise current[:discard] is not being properly treated
259
- if env["QUERY_STRING"] =~ /pp=env/
268
+ if query_string =~ /pp=env/
260
269
  body.close if body.respond_to? :close
261
270
  return dump_env env
262
271
  end
263
272
 
264
- if env["QUERY_STRING"] =~ /pp=help/
273
+ if query_string =~ /pp=help/
265
274
  body.close if body.respond_to? :close
266
- return help
275
+ return help(nil, client_settings)
267
276
  end
268
277
 
269
278
  page_struct = current.page_struct
@@ -271,7 +280,7 @@ module Rack
271
280
 
272
281
  if backtraces
273
282
  body.close if body.respond_to? :close
274
- return help(:stacktrace) if missing_stacktrace
283
+ return help(:stacktrace, client_settings) if missing_stacktrace
275
284
  return analyze(backtraces, page_struct)
276
285
  end
277
286
 
@@ -282,6 +291,8 @@ module Rack
282
291
 
283
292
  # inject headers, script
284
293
  if status == 200
294
+
295
+ client_settings.write!(headers)
285
296
 
286
297
  # mini profiler is meddling with stuff, we can not cache cause we will get incorrect data
287
298
  # Rack::ETag has already inserted some nonesense in the chain
@@ -311,6 +322,7 @@ module Rack
311
322
  end
312
323
  end
313
324
 
325
+ client_settings.write!(headers)
314
326
  [status, headers, body]
315
327
  ensure
316
328
  # Make sure this always happens
@@ -318,7 +330,15 @@ module Rack
318
330
  end
319
331
 
320
332
  def inject(fragment, script)
321
- fragment.sub(/<\/body>/i, script + "</body>")
333
+ fragment.sub(/<\/body>/i) do
334
+ # if for whatever crazy reason we dont get a utf string,
335
+ # just force the encoding, no utf in the mp scripts anyway
336
+ if script.respond_to?(:encoding) && script.respond_to?(:force_encoding)
337
+ (script + "</body>").force_encoding(fragment.encoding)
338
+ else
339
+ script + "</body>"
340
+ end
341
+ end
322
342
  end
323
343
 
324
344
  def dump_env(env)
@@ -330,21 +350,25 @@ module Rack
330
350
  [200, headers, [body]]
331
351
  end
332
352
 
333
- def help(category = nil)
353
+ def help(category = nil, client_settings)
334
354
  headers = {'Content-Type' => 'text/plain'}
335
355
  body = "Append the following to your query string:
336
356
 
337
357
  pp=help : display this screen
338
358
  pp=env : display the rack environment
339
359
  pp=skip : skip mini profiler for this request
340
- pp=no-backtrace : don't collect stack traces from all the SQL executed
341
- pp=full-backtrace : enable full backtrace for SQL executed
342
- pp=sample : sample stack traces and return a report isolating heavy usage (requires the stacktrace gem)
360
+ 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)
361
+ pp=normal-backtrace #{"(*) " if client_settings.backtrace_default?}: collect stack traces from all the SQL executed and filter normally
362
+ pp=full-backtrace #{"(*) " if client_settings.backtrace_full?}: enable full backtraces for SQL executed (use pp=normal-backtrace to disable)
363
+ pp=sample : sample stack traces and return a report isolating heavy usage (experimental)
364
+ pp=disable : disable profiling for this session
365
+ pp=enable : enable profiling for this session (if previously disabled)
343
366
  "
344
367
  if (category == :stacktrace)
345
368
  body = "pp=stacktrace requires the stacktrace gem - add gem 'stacktrace' to your Gemfile"
346
369
  end
347
370
 
371
+ client_settings.write!(headers)
348
372
  [200, headers, [body]]
349
373
  end
350
374
 
@@ -358,13 +382,12 @@ module Rack
358
382
  fulldump << "\n\n"
359
383
  distinct = {}
360
384
  trace.each do |frame|
361
- name = "#{frame.klass} #{frame.method}"
362
- unless distinct[name]
363
- distinct[name] = true
364
- seen[name] ||= 0
365
- seen[name] += 1
385
+ unless distinct[frame]
386
+ distinct[frame] = true
387
+ seen[frame] ||= 0
388
+ seen[frame] += 1
366
389
  end
367
- fulldump << name << "\n"
390
+ fulldump << frame << "\n"
368
391
  end
369
392
  end
370
393
 
@@ -382,7 +405,8 @@ module Rack
382
405
  end
383
406
 
384
407
  def ids_json(env)
385
- ids = [current.page_struct["Id"]] + (@storage.get_unviewed_ids(user(env)) || [])
408
+ # cap at 10 ids, otherwise there is a chance you can blow the header
409
+ ids = [current.page_struct["Id"]] + (@storage.get_unviewed_ids(user(env)) || [])[0..8]
386
410
  ::JSON.generate(ids.uniq)
387
411
  end
388
412
 
@@ -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 full_backtrace or Rack::MiniProfiler.config.backtrace_filter.nil? or ln =~ Rack::MiniProfiler.config.backtrace_filter
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
@@ -58,7 +58,6 @@ module Rack
58
58
  @timer_struct_cache.delete_if { |k, v| v['Root']['StartMilliseconds'] < expire_older_than }
59
59
  }
60
60
  end
61
-
62
61
  end
63
62
  end
64
63
  end
File without changes
@@ -22,7 +22,9 @@ module Rack
22
22
  end
23
23
 
24
24
  def to_json(*a)
25
- ::JSON.generate(@attributes, a[0])
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 )
26
28
  end
27
29
 
28
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.backtrace_filter = /^\/?(app|config|lib|test)/
34
+ c.backtrace_includes = [/^\/?(app|config|lib|test)/]
35
35
  c.skip_schema_queries = Rails.env != 'production'
36
36
 
37
37
  # Install the Middleware
@@ -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
File without changes
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rack-mini-profiler"
3
- s.version = "0.1.8"
3
+ s.version = "0.1.13.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.8
5
- prerelease:
4
+ version: 0.1.13.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-07-30 00:00:00.000000000 Z
14
+ date: 2012-09-03 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: -902573215
134
+ hash: -879601329
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: '0'
140
- segments:
141
- - 0
142
- hash: -902573215
140
+ version: 1.3.1
143
141
  requirements: []
144
142
  rubyforge_project:
145
143
  rubygems_version: 1.8.24