rack-mini-profiler 0.1.8 → 0.1.13.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.

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