rack-mini-profiler 0.9.3 → 0.9.4

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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 915cfa4f71cab960c3f73128fa213cce013f0b65
4
- data.tar.gz: 3465e843ef28ed50178f1f76255de96b474903f6
3
+ metadata.gz: 6f6c4ad1e41a0b8cf00506f6c3d732a0a8ea2dc1
4
+ data.tar.gz: 0a4e5b357dd0473b157ba8728c069cd165fbb99f
5
5
  SHA512:
6
- metadata.gz: 7c232ba029fb050b15d6b4cdb08b9dc3a6079ed723c06beb7b99dcbc7b6d009822aa2686895661a8e57497a0c5e529a691bf7507c0a895639be9b0e0346ddf29
7
- data.tar.gz: 45b90274fd6828441a1a4ca14017a6d3b1f1292b65c157dbd03964748b7fd648b39f06484b36d56fd0340b52498bd9c8b0242fe6063e6e23dd115d4b99c10040
6
+ metadata.gz: 91b62e7d1beec331e6d104bbf3efe4b2e267c1d93e83166d3289d15798e3a777f847e8f7a0d49f138098e3fea075dcc771b13691534087c6911cf08072e157ee
7
+ data.tar.gz: 81115816fa927e35361804b8e8ef79148d39283cbf7b7609020dd993b811e7af4972f38b5c00d75a04f01eb3a3c1e33a2e0a3e5fbe74370efccd25694f069257
@@ -1,4 +1,9 @@
1
1
  # CHANGELOG
2
+ ## 0.9.4 - 2014-07-08 (Sam Saffron)
3
+ - [UX] added a link to "more" actions in profiler
4
+ - [FEATURE] pp=help now displays links
5
+ - [FEATURE] simple memory report with pp=analyze-memory
6
+
2
7
  ## 0.9.2 - 2014-06-26 (Sam Saffron)
3
8
  - [CHANGE] staging and other environments behave like production (Cedric Felizard)
4
9
  - [DOC] CHANGELOG reorg (Olivier Lacan)
data/README.md CHANGED
@@ -23,7 +23,6 @@ We have decided to restructure our repository so there is a central UI repo and
23
23
 
24
24
  - Setting up a build that reuses https://github.com/MiniProfiler/ui
25
25
  - Migrating the internal data structures [per the spec](https://github.com/MiniProfiler/ui)
26
- - Cleaning up the [horrendous class structure that is using strings as keys and crazy non-objects](https://github.com/MiniProfiler/rack-mini-profiler/blob/master/lib/mini_profiler/timer_struct/sql.rb#L36-L44)
27
26
 
28
27
  If you feel like taking on any of this start an issue and update us on your progress.
29
28
 
@@ -184,7 +183,7 @@ The available configuration options are:
184
183
  * 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.
185
184
  * auto_inject (default true) - when false the miniprofiler script is not injected in the page
186
185
  * backtrace_filter - a regex you can use to filter out unwanted lines from the backtraces
187
- * 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.
186
+ * toggle_shortcut (default Alt+P) - a jquery.hotkeys.js-style keyboard shortcut, used to toggle the mini_profiler's visibility. See https://github.com/jeresig/jquery.hotkeys for more info.
188
187
  * start_hidden (default false) - Whether or not you want the mini_profiler to be visible when loading a page
189
188
  * 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.
190
189
  * flamegraph_sample_rate (default 0.5ms) - How often fast_stack should get stack trace info to generate flamegraphs
@@ -395,6 +395,9 @@
395
395
  padding: 0px;
396
396
  margin: 0px;
397
397
  }
398
+ .profiler-results .profiler-more-actions {
399
+ float: left;
400
+ }
398
401
  .profiler-queries-bg {
399
402
  z-index: 2147483642;
400
403
  display: none;
@@ -663,7 +663,7 @@ var MiniProfiler = (function () {
663
663
  // jquery.hotkeys.js
664
664
  // https://github.com/jeresig/jquery.hotkeys/blob/master/jquery.hotkeys.js
665
665
 
666
- if (jQuery.hotkeys === undefined) {
666
+ if (MiniProfiler.jQuery.hotkeys === undefined) {
667
667
  (function(d){function h(g){if("string"===typeof g.data){var h=g.handler,j=g.data.toLowerCase().split(" ");g.handler=function(b){if(!(this!==b.target&&(/textarea|select/i.test(b.target.nodeName)||"text"===b.target.type))){var c="keypress"!==b.type&&d.hotkeys.specialKeys[b.which],e=String.fromCharCode(b.which).toLowerCase(),a="",f={};b.altKey&&"alt"!==c&&(a+="alt+");b.ctrlKey&&"ctrl"!==c&&(a+="ctrl+");b.metaKey&&(!b.ctrlKey&&"meta"!==c)&&(a+="meta+");b.shiftKey&&"shift"!==c&&(a+="shift+");c?f[a+c]=
668
668
  !0:(f[a+e]=!0,f[a+d.hotkeys.shiftNums[e]]=!0,"shift+"===a&&(f[d.hotkeys.shiftNums[e]]=!0));c=0;for(e=j.length;c<e;c++)if(f[j[c]])return h.apply(this,arguments)}}}}d.hotkeys={version:"0.8",specialKeys:{8:"backspace",9:"tab",13:"return",16:"shift",17:"ctrl",18:"alt",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",
669
669
  109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",191:"/",224:"meta"},shiftNums:{"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(","0":")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|"}};d.each(["keydown","keyup","keypress"],function(){d.event.special[this]={add:h}})})(MiniProfiler.jQuery);
@@ -748,6 +748,12 @@ var MiniProfiler = (function () {
748
748
  return options.path + 'results?id=' + id;
749
749
  },
750
750
 
751
+ moreUrl: function () {
752
+ var loc = window.location.href;
753
+ loc = loc.indexOf("?") > 0 ? loc + "&pp=help" : "?pp=help";
754
+ return loc;
755
+ },
756
+
751
757
  getClientTimings: function (clientTimings) {
752
758
  var list = [];
753
759
  var t;
@@ -399,6 +399,9 @@
399
399
  padding: 0px;
400
400
  margin: 0px;
401
401
  }
402
+
403
+ .profiler-more-actions { float: left; }
404
+
402
405
  }
403
406
 
404
407
  // popup results' queries will be displayed in front of this
@@ -413,6 +416,7 @@
413
416
  min-width:100%;
414
417
  }
415
418
 
419
+
416
420
  // used when viewing a shared, full page result
417
421
  .profiler-result-full {
418
422
  .profiler-result {
@@ -484,4 +488,5 @@
484
488
  }
485
489
  }
486
490
  }
491
+
487
492
  }
@@ -123,6 +123,7 @@
123
123
 
124
124
  <script id="linksTemplate" type="text/x-jquery-tmpl">
125
125
  <a href="${MiniProfiler.shareUrl(id)}" class="profiler-share-profiler-results" target="_blank">share</a>
126
+ <a href="${MiniProfiler.moreUrl()}" class="profiler-more-actions">more</a>
126
127
  {{if custom_link}}
127
128
  <a href="${custom_link}" class="profiler-custom-link" target="_blank">${custom_link_name}</a>
128
129
  {{/if}}
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class MiniProfiler
3
- ASSET_VERSION = '9db1f8db18400644bd5c7449e5295620'.freeze
3
+ ASSET_VERSION = 'e0e50f551fa464f9d95c2e082bb2d45b'.freeze
4
4
  end
5
5
  end
@@ -100,7 +100,7 @@ module Rack
100
100
 
101
101
  # Otherwise give the HTML back
102
102
  html = MiniProfiler.share_template.dup
103
- html.gsub!(/\{path\}/, "#{env['SCRIPT_NAME']}#{@config.base_url_path}")
103
+ html.gsub!(/\{path\}/, "#{env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME']}#{@config.base_url_path}")
104
104
  html.gsub!(/\{version\}/, MiniProfiler::ASSET_VERSION)
105
105
  html.gsub!(/\{json\}/, result_json)
106
106
  html.gsub!(/\{includes\}/, get_profile_script(env))
@@ -157,8 +157,11 @@ module Rack
157
157
  query_string = env['QUERY_STRING']
158
158
  path = env['PATH_INFO']
159
159
 
160
+ # Someone (e.g. Rails engine) could change the SCRIPT_NAME so we save it
161
+ env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME'] = env['SCRIPT_NAME']
162
+
160
163
  skip_it = (@config.pre_authorize_cb && !@config.pre_authorize_cb.call(env)) ||
161
- (@config.skip_paths && @config.skip_paths.any?{ |p| path[0,p.length] == p}) ||
164
+ (@config.skip_paths && @config.skip_paths.any?{ |p| path.start_with?(p) }) ||
162
165
  query_string =~ /pp=skip/
163
166
 
164
167
  has_profiling_cookie = client_settings.has_cookie?
@@ -304,9 +307,14 @@ module Rack
304
307
  return dump_env env
305
308
  end
306
309
 
310
+ if query_string =~ /pp=analyze-memory/
311
+ body.close if body.respond_to? :close
312
+ return analyze_memory
313
+ end
314
+
307
315
  if query_string =~ /pp=help/
308
316
  body.close if body.respond_to? :close
309
- return help(client_settings)
317
+ return help(client_settings, env)
310
318
  end
311
319
 
312
320
  page_struct = current.page_struct
@@ -446,30 +454,79 @@ module Rack
446
454
  text_result(body)
447
455
  end
448
456
 
457
+ def trim_strings(strings, max_size)
458
+ strings.sort!{|a,b| b[1] <=> a[1]}
459
+ i = 0
460
+ strings.delete_if{|_| (i+=1) > max_size}
461
+ end
462
+
463
+ def analyze_memory
464
+ require 'objspace'
465
+
466
+ body = "ObjectSpace stats:\n\n"
467
+
468
+ body << ObjectSpace.count_objects
469
+ .sort{|a,b| b[1] <=> a[1]}
470
+ .map{|k,v| "#{k}: #{v}"}
471
+ .join("\n")
472
+
473
+ body << "\n\n\n1000 Largest strings:\n\n"
474
+
475
+ strings = []
476
+ max_size = 1000
477
+
478
+ GC.start
479
+ GC.start
480
+
481
+ ObjectSpace.each_object(String) do |str|
482
+ strings << [str[0..200], str.length]
483
+ if strings.length > max_size * 2
484
+ trim_strings(strings, max_size)
485
+ end
486
+ end
487
+
488
+ trim_strings(strings, max_size)
489
+
490
+ body << strings.map{|s,len| "#{s}\n(#{len})\n\n"}.join("\n")
491
+
492
+ text_result(body)
493
+ end
494
+
449
495
  def text_result(body)
450
496
  headers = {'Content-Type' => 'text/plain'}
451
497
  [200, headers, [body]]
452
498
  end
453
499
 
454
- def help(client_settings)
455
- headers = {'Content-Type' => 'text/plain'}
456
- body = "Append the following to your query string:
457
-
458
- pp=help : display this screen
459
- pp=env : display the rack environment
460
- pp=skip : skip mini profiler for this request
461
- 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)
462
- pp=normal-backtrace #{"(*) " if client_settings.backtrace_default?}: collect stack traces from all the SQL executed and filter normally
463
- pp=full-backtrace #{"(*) " if client_settings.backtrace_full?}: enable full backtraces for SQL executed (use pp=normal-backtrace to disable)
464
- pp=disable : disable profiling for this session
465
- pp=enable : enable profiling for this session (if previously disabled)
466
- pp=profile-gc: perform gc profiling on this request, analyzes ObjectSpace generated by request (ruby 1.9.3 only)
467
- pp=profile-gc-time: perform built-in gc profiling on this request (ruby 1.9.3 only)
468
- pp=profile-gc-ruby-head: requires the memory_profiler gem, new location based report
469
- pp=flamegraph: works best on Ruby 2.0, a graph representing sampled activity (requires the flamegraph gem).
470
- pp=flamegraph&flamegraph_sample_rate=1: creates a flamegraph with the specified sample rate (in ms). Overrides value set in config
471
- pp=flamegraph_embed: works best on Ruby 2.0, a graph representing sampled activity (requires the flamegraph gem), embedded resources for use on an intranet.
472
- pp=trace-exceptions: requires Ruby 2.0, will return all the spots where your application raises execptions
500
+ def make_link(postfix, env)
501
+ link = env["PATH_INFO"] + "?" + env["QUERY_STRING"].sub("pp=help", "pp=#{postfix}")
502
+ "pp=<a href='#{link}'>#{postfix}</a>"
503
+ end
504
+
505
+ def help(client_settings, env)
506
+ headers = {'Content-Type' => 'text/html'}
507
+ body = "<html><body>
508
+ <pre style='line-height: 30px; font-size: 16px;'>
509
+ Append the following to your query string:
510
+
511
+ #{make_link "help", env} : display this screen
512
+ #{make_link "env", env} : display the rack environment
513
+ #{make_link "skip", env} : skip mini profiler for this request
514
+ #{make_link "no-backtrace", env} #{"(*) " if client_settings.backtrace_none?}: don't collect stack traces from all the SQL executed (sticky, use pp=normal-backtrace to enable)
515
+ #{make_link "normal-backtrace", env} #{"(*) " if client_settings.backtrace_default?}: collect stack traces from all the SQL executed and filter normally
516
+ #{make_link "full-backtrace", env} #{"(*) " if client_settings.backtrace_full?}: enable full backtraces for SQL executed (use pp=normal-backtrace to disable)
517
+ #{make_link "disable", env} : disable profiling for this session
518
+ #{make_link "enable", env} : enable profiling for this session (if previously disabled)
519
+ #{make_link "profile-gc", env} : perform gc profiling on this request, analyzes ObjectSpace generated by request (ruby 1.9.3 only)
520
+ #{make_link "profile-gc-time", env} : perform built-in gc profiling on this request (ruby 1.9.3 only)
521
+ #{make_link "profile-gc-ruby-head", env} : requires the memory_profiler gem, new location based report
522
+ #{make_link "flamegraph", env} : works best on Ruby 2.0, a graph representing sampled activity (requires the flamegraph gem).
523
+ #{make_link "flamegraph&flamegraph_sample_rate=1", env}: creates a flamegraph with the specified sample rate (in ms). Overrides value set in config
524
+ #{make_link "flamegraph_embed", env} : works best on Ruby 2.0, a graph representing sampled activity (requires the flamegraph gem), embedded resources for use on an intranet.
525
+ #{make_link "trace-exceptions", env} : requires Ruby 2.0, will return all the spots where your application raises execptions
526
+ #{make_link "analyze-memory", env} : requires Ruby 2.0, will perform basic memory analysis of heap
527
+ </pre>
528
+ </body>
529
+ </html>
473
530
  "
474
531
 
475
532
  client_settings.write!(headers)
@@ -501,7 +558,7 @@ module Rack
501
558
  # * you have disabled auto append behaviour throught :auto_inject => false flag
502
559
  # * you do not want script to be automatically appended for the current page. You can also call cancel_auto_inject
503
560
  def get_profile_script(env)
504
- path = "#{env['SCRIPT_NAME']}#{@config.base_url_path}"
561
+ path = "#{env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME']}#{@config.base_url_path}"
505
562
 
506
563
  settings = {
507
564
  :path => path,
@@ -9,6 +9,7 @@ module Rack
9
9
  require 'dalli' unless defined? Dalli
10
10
  args ||= {}
11
11
  @prefix = args[:prefix] || "MPMemcacheStore"
12
+ @prefix += "-#{Rack::MiniProfiler::VERSION}"
12
13
  @client = args[:client] || Dalli::Client.new
13
14
  @expires_in_seconds = args[:expires_in] || EXPIRES_IN_SECONDS
14
15
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class MiniProfiler
3
- VERSION = '0.9.3'
3
+ VERSION = '0.9.4'
4
4
  end
5
5
  end
@@ -9,7 +9,12 @@ module Rack::MiniProfilerRails
9
9
 
10
10
  c = Rack::MiniProfiler.config
11
11
 
12
- # By default, only show the MiniProfiler in development mode, in production allow profiling if post_authorize_cb is set
12
+ # By default, only show the MiniProfiler in development mode.
13
+ # To use the MiniProfiler in production, call Rack::MiniProfiler.authorize_request
14
+ # from a hook in your ApplicationController
15
+ #
16
+ # Example:
17
+ # before_action { Rack::MiniProfiler.authorize_request if current_user.is_admin? }
13
18
  #
14
19
  # NOTE: this must be set here with = and not ||=
15
20
  # The out of the box default is "true"
@@ -37,10 +37,10 @@ class SqlPatches
37
37
  end
38
38
  end
39
39
 
40
- require 'patches/db/mysql2' if SqlPatches.class_exists? "Mysql2::Client"
41
- require 'patches/db/pg' if SqlPatches.class_exists? "PG::Result"
42
- require 'patches/db/moped' if SqlPatches.class_exists?("Moped::Node")
43
- require 'patches/db/plucky' if SqlPatches.class_exists?("Plucky::Query")
44
- require 'patches/db/rsolr' if SqlPatches.class_exists?("RSolr::Connection") && RSolr::VERSION[0] != "0"
45
- require 'patches/db/sequel' if !SqlPatches.patched? && SqlPatches.class_exists?("Sequel::Database")
46
- require 'patches/db/activerecord' if !SqlPatches.patched? && SqlPatches.module_exists?("ActiveRecord")
40
+ require 'patches/db/mysql2' if defined?(Mysql2::Client) && SqlPatches.class_exists?("Mysql2::Client")
41
+ require 'patches/db/pg' if defined?(PG::Result) && SqlPatches.class_exists?("PG::Result")
42
+ require 'patches/db/moped' if defined?(Moped::Node) && SqlPatches.class_exists?("Moped::Node")
43
+ require 'patches/db/plucky' if defined?(Plucky::Query) && SqlPatches.class_exists?("Plucky::Query")
44
+ require 'patches/db/rsolr' if defined?(RSolr::Connection) && SqlPatches.class_exists?("RSolr::Connection") && RSolr::VERSION[0] != "0"
45
+ require 'patches/db/sequel' if defined?(Sequel::Database) && !SqlPatches.patched? && SqlPatches.class_exists?("Sequel::Database")
46
+ require 'patches/db/activerecord' if defined?(ActiveRecord) &&!SqlPatches.patched? && SqlPatches.module_exists?("ActiveRecord")
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.9.3
4
+ version: 0.9.4
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: 2015-02-27 00:00:00.000000000 Z
13
+ date: 2015-07-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack
@@ -253,7 +253,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
253
253
  version: '0'
254
254
  requirements: []
255
255
  rubyforge_project:
256
- rubygems_version: 2.2.2
256
+ rubygems_version: 2.4.5
257
257
  signing_key:
258
258
  specification_version: 4
259
259
  summary: Profiles loading speed for rack applications.