rack-mini-profiler 0.10.6 → 2.3.0

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.
Files changed (74) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +129 -16
  3. data/README.md +116 -63
  4. data/lib/enable_rails_patches.rb +5 -0
  5. data/lib/generators/rack_profiler/install_generator.rb +2 -0
  6. data/lib/generators/rack_profiler/templates/rack_profiler.rb +2 -0
  7. data/lib/html/dot.1.1.2.min.js +2 -0
  8. data/lib/html/includes.css +141 -40
  9. data/lib/html/includes.js +1398 -970
  10. data/lib/html/includes.scss +547 -442
  11. data/lib/html/includes.tmpl +227 -142
  12. data/lib/html/pretty-print.js +810 -0
  13. data/lib/html/profile_handler.js +1 -1
  14. data/lib/html/rack-mini-profiler.css +3 -0
  15. data/lib/html/rack-mini-profiler.js +2 -0
  16. data/lib/html/share.html +0 -1
  17. data/lib/html/speedscope/LICENSE +21 -0
  18. data/lib/html/speedscope/README.md +3 -0
  19. data/lib/html/speedscope/demangle-cpp.1768f4cc.js +4 -0
  20. data/lib/html/speedscope/favicon-16x16.f74b3187.png +0 -0
  21. data/lib/html/speedscope/favicon-32x32.bc503437.png +0 -0
  22. data/lib/html/speedscope/file-format-schema.json +324 -0
  23. data/lib/html/speedscope/import.cf0fa83f.js +115 -0
  24. data/lib/html/speedscope/index.html +2 -0
  25. data/lib/html/speedscope/release.txt +3 -0
  26. data/lib/html/speedscope/reset.8c46b7a1.css +2 -0
  27. data/lib/html/speedscope/source-map.438fa06b.js +24 -0
  28. data/lib/html/speedscope/speedscope.44364064.js +200 -0
  29. data/lib/html/vendor.js +848 -0
  30. data/lib/mini_profiler/asset_version.rb +3 -2
  31. data/lib/mini_profiler/client_settings.rb +27 -16
  32. data/lib/mini_profiler/config.rb +73 -46
  33. data/lib/mini_profiler/context.rb +5 -3
  34. data/lib/mini_profiler/gc_profiler.rb +17 -16
  35. data/lib/mini_profiler/profiler.rb +332 -94
  36. data/lib/mini_profiler/profiling_methods.rb +20 -15
  37. data/lib/mini_profiler/snapshots_transporter.rb +109 -0
  38. data/lib/mini_profiler/storage/abstract_store.rb +80 -0
  39. data/lib/mini_profiler/storage/file_store.rb +18 -13
  40. data/lib/mini_profiler/storage/memcache_store.rb +10 -7
  41. data/lib/mini_profiler/storage/memory_store.rb +63 -13
  42. data/lib/mini_profiler/storage/redis_store.rb +143 -7
  43. data/lib/mini_profiler/timer_struct/base.rb +4 -2
  44. data/lib/mini_profiler/timer_struct/client.rb +9 -8
  45. data/lib/mini_profiler/timer_struct/custom.rb +8 -5
  46. data/lib/mini_profiler/timer_struct/page.rb +79 -24
  47. data/lib/mini_profiler/timer_struct/request.rb +83 -38
  48. data/lib/mini_profiler/timer_struct/sql.rb +25 -22
  49. data/lib/mini_profiler/version.rb +3 -1
  50. data/lib/mini_profiler_rails/railtie.rb +91 -8
  51. data/lib/mini_profiler_rails/railtie_methods.rb +61 -0
  52. data/lib/patches/db/activerecord.rb +5 -14
  53. data/lib/patches/db/mongo.rb +3 -1
  54. data/lib/patches/db/moped.rb +5 -3
  55. data/lib/patches/db/mysql2.rb +8 -6
  56. data/lib/patches/db/neo4j.rb +3 -1
  57. data/lib/patches/db/nobrainer.rb +4 -2
  58. data/lib/patches/db/oracle_enhanced.rb +4 -2
  59. data/lib/patches/db/pg.rb +41 -21
  60. data/lib/patches/db/plucky.rb +7 -5
  61. data/lib/patches/db/riak.rb +15 -13
  62. data/lib/patches/db/rsolr.rb +6 -4
  63. data/lib/patches/db/sequel.rb +2 -0
  64. data/lib/patches/net_patches.rb +20 -8
  65. data/lib/patches/sql_patches.rb +17 -7
  66. data/lib/prepend_net_http_patch.rb +5 -0
  67. data/lib/rack-mini-profiler.rb +3 -3
  68. data/rack-mini-profiler.gemspec +23 -9
  69. metadata +146 -31
  70. data/lib/html/jquery.1.7.1.js +0 -4
  71. data/lib/html/jquery.tmpl.js +0 -486
  72. data/lib/html/list.css +0 -9
  73. data/lib/html/list.js +0 -38
  74. data/lib/html/list.tmpl +0 -34
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  module Rack
2
3
  class MiniProfiler
3
- ASSET_VERSION = '812af6927f7534f73488ece21dc89b62'.freeze
4
+ ASSET_VERSION = '10da952c710f6abd9f1bd50fe50ed714'
4
5
  end
5
- end
6
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  class MiniProfiler
3
5
  class ClientSettings
@@ -11,18 +13,19 @@ module Rack
11
13
  attr_accessor :disable_profiling
12
14
  attr_accessor :backtrace_level
13
15
 
14
-
15
16
  def initialize(env, store, start)
16
- request = ::Rack::Request.new(env)
17
- @cookie = request.cookies[COOKIE_NAME]
17
+ @request = ::Rack::Request.new(env)
18
+ @cookie = @request.cookies[COOKIE_NAME]
18
19
  @store = store
19
20
  @start = start
21
+ @backtrace_level = nil
22
+ @orig_disable_profiling = @disable_profiling = nil
20
23
 
21
24
  @allowed_tokens, @orig_auth_tokens = nil
22
25
 
23
26
  if @cookie
24
- @cookie.split(",").map{|pair| pair.split("=")}.each do |k,v|
25
- @orig_disable_profiling = @disable_profiling = (v=='t') if k == "dp"
27
+ @cookie.split(",").map { |pair| pair.split("=") }.each do |k, v|
28
+ @orig_disable_profiling = @disable_profiling = (v == 't') if k == "dp"
26
29
  @backtrace_level = v.to_i if k == "bt"
27
30
  @orig_auth_tokens = v.to_s.split("|") if k == "a"
28
31
  end
@@ -37,12 +40,12 @@ module Rack
37
40
  end
38
41
 
39
42
  def handle_cookie(result)
40
- status,headers,_body = result
43
+ status, headers, _body = result
41
44
 
42
45
  if (MiniProfiler.config.authorization_mode == :whitelist && !MiniProfiler.request_authorized?)
43
46
  # this is non-obvious, don't kill the profiling cookie on errors or short requests
44
47
  # this ensures that stuff that never reaches the rails stack does not kill profiling
45
- if status.to_i >= 200 && status.to_i < 300 && ((Time.now - @start) > 0.1)
48
+ if status.to_i >= 200 && status.to_i < 300 && ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - @start) > 0.1)
46
49
  discard_cookie!(headers)
47
50
  end
48
51
  else
@@ -66,36 +69,44 @@ module Rack
66
69
  @cookie.nil? ||
67
70
  tokens_changed
68
71
 
69
- settings = {"p" => "t" }
72
+ settings = { "p" => "t" }
70
73
  settings["dp"] = "t" if @disable_profiling
71
74
  settings["bt"] = @backtrace_level if @backtrace_level
72
75
  settings["a"] = @allowed_tokens.join("|") if @allowed_tokens && MiniProfiler.request_authorized?
73
-
74
- settings_string = settings.map{|k,v| "#{k}=#{v}"}.join(",")
75
- Rack::Utils.set_cookie_header!(headers, COOKIE_NAME, :value => settings_string, :path => '/')
76
+ settings_string = settings.map { |k, v| "#{k}=#{v}" }.join(",")
77
+ cookie = { value: settings_string, path: '/', httponly: true }
78
+ cookie[:secure] = true if @request.ssl?
79
+ cookie[:same_site] = 'Lax'
80
+ Rack::Utils.set_cookie_header!(headers, COOKIE_NAME, cookie)
76
81
  end
77
82
  end
78
83
 
79
84
  def discard_cookie!(headers)
80
85
  if @cookie
81
- Rack::Utils.delete_cookie_header!(headers, COOKIE_NAME, :path => '/')
86
+ Rack::Utils.delete_cookie_header!(headers, COOKIE_NAME, path: '/')
82
87
  end
83
88
  end
84
89
 
85
90
  def has_valid_cookie?
86
91
  valid_cookie = !@cookie.nil?
87
92
 
88
- if (MiniProfiler.config.authorization_mode == :whitelist)
89
- @allowed_tokens ||= @store.allowed_tokens
93
+ if (MiniProfiler.config.authorization_mode == :whitelist) && valid_cookie
94
+ begin
95
+ @allowed_tokens ||= @store.allowed_tokens
96
+ rescue => e
97
+ if MiniProfiler.config.storage_failure != nil
98
+ MiniProfiler.config.storage_failure.call(e)
99
+ end
100
+ end
90
101
 
91
- valid_cookie = (Array === @orig_auth_tokens) &&
102
+ valid_cookie = @allowed_tokens &&
103
+ (Array === @orig_auth_tokens) &&
92
104
  ((@allowed_tokens & @orig_auth_tokens).length > 0)
93
105
  end
94
106
 
95
107
  valid_cookie
96
108
  end
97
109
 
98
-
99
110
  def disable_profiling?
100
111
  @disable_profiling
101
112
  end
@@ -1,45 +1,30 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Rack
2
4
  class MiniProfiler
3
5
  class Config
6
+ def self.attr_accessor(*vars)
7
+ @attributes ||= []
8
+ @attributes.concat vars
9
+ super(*vars)
10
+ end
4
11
 
5
- def self.attr_accessor(*vars)
6
- @attributes ||= []
7
- @attributes.concat vars
8
- super(*vars)
9
- end
10
-
11
- def self.attributes
12
- @attributes
13
- end
14
-
15
- attr_accessor :authorization_mode, :auto_inject, :backtrace_ignores,
16
- :backtrace_includes, :backtrace_remove, :backtrace_threshold_ms,
17
- :base_url_path, :disable_caching, :disable_env_dump, :enabled,
18
- :flamegraph_sample_rate, :logger, :pre_authorize_cb, :skip_paths,
19
- :skip_schema_queries, :storage, :storage_failure, :storage_instance,
20
- :storage_options, :user_provider
21
- attr_accessor :skip_sql_param_names, :suppress_encoding, :max_sql_param_length
22
-
23
- # ui accessors
24
- attr_accessor :collapse_results, :max_traces_to_show, :position, :vertical_position, :horizontal_position,
25
- :show_children, :show_controls, :show_trivial, :start_hidden,
26
- :toggle_shortcut, :html_container
27
-
28
- # Deprecated options
29
- attr_accessor :use_existing_jquery
12
+ def self.attributes
13
+ @attributes
14
+ end
30
15
 
31
16
  def self.default
32
17
  new.instance_eval {
33
18
  @auto_inject = true # automatically inject on every html page
34
- @base_url_path = "/mini-profiler-resources/"
19
+ @base_url_path = "/mini-profiler-resources/".dup
35
20
  @disable_caching = true
36
21
  # called prior to rack chain, to ensure we are allowed to profile
37
- @pre_authorize_cb = lambda {|env| true}
22
+ @pre_authorize_cb = lambda { |env| true }
38
23
 
39
24
  # called after rack chain, to ensure we are REALLY allowed to profile
40
25
  @skip_schema_queries = false
41
26
  @storage = MiniProfiler::MemoryStore
42
- @user_provider = Proc.new{|env| Rack::Request.new(env).ip}
27
+ @user_provider = Proc.new { |env| Rack::Request.new(env).ip }
43
28
  @authorization_mode = :allow_all
44
29
  @backtrace_threshold_ms = 0
45
30
  @flamegraph_sample_rate = 0.5
@@ -49,44 +34,86 @@ module Rack
49
34
  end
50
35
  end
51
36
  @enabled = true
52
- @disable_env_dump = false
53
37
  @max_sql_param_length = 0 # disable sql parameter collection by default
54
38
  @skip_sql_param_names = /password/ # skips parameters with the name password by default
39
+ @enable_advanced_debugging_tools = false
40
+ @snapshot_every_n_requests = -1
41
+ @snapshots_limit = 1000
55
42
 
56
43
  # ui parameters
57
- @autorized = true
58
- @collapse_results = true
59
- @max_traces_to_show = 20
60
- @show_children = false
61
- @show_controls = false
62
- @show_trivial = false
63
- @start_hidden = false
64
- @toggle_shortcut = 'Alt+P'
65
- @html_container = 'body'
44
+ @autorized = true
45
+ @collapse_results = true
46
+ @max_traces_to_show = 20
47
+ @show_children = false
48
+ @show_controls = false
49
+ @show_trivial = false
50
+ @show_total_sql_count = false
51
+ @start_hidden = false
52
+ @toggle_shortcut = 'alt+p'
53
+ @html_container = 'body'
54
+ @position = "top-left"
55
+ @snapshot_hidden_custom_fields = []
56
+ @snapshots_transport_destination_url = nil
57
+ @snapshots_transport_auth_key = nil
58
+ @snapshots_redact_sql_queries = true
59
+ @snapshots_transport_gzip_requests = false
66
60
 
67
61
  self
68
62
  }
69
63
  end
70
64
 
65
+ attr_accessor :authorization_mode, :auto_inject, :backtrace_ignores,
66
+ :backtrace_includes, :backtrace_remove, :backtrace_threshold_ms,
67
+ :base_url_path, :disable_caching, :enabled,
68
+ :flamegraph_sample_rate, :logger, :pre_authorize_cb, :skip_paths,
69
+ :skip_schema_queries, :storage, :storage_failure, :storage_instance,
70
+ :storage_options, :user_provider, :enable_advanced_debugging_tools,
71
+ :skip_sql_param_names, :suppress_encoding, :max_sql_param_length
72
+
73
+ # ui accessors
74
+ attr_accessor :collapse_results, :max_traces_to_show, :position,
75
+ :show_children, :show_controls, :show_trivial, :show_total_sql_count,
76
+ :start_hidden, :toggle_shortcut, :html_container
77
+
78
+ # snapshot related config
79
+ attr_accessor :snapshot_every_n_requests, :snapshots_limit,
80
+ :snapshot_hidden_custom_fields, :snapshots_transport_destination_url,
81
+ :snapshots_transport_auth_key, :snapshots_redact_sql_queries,
82
+ :snapshots_transport_gzip_requests
83
+
84
+ # Deprecated options
85
+ attr_accessor :use_existing_jquery
86
+
87
+ attr_reader :assets_url
88
+
89
+ def assets_url=(lmbda)
90
+ if defined?(Rack::MiniProfilerRails)
91
+ Rack::MiniProfilerRails.create_engine
92
+ end
93
+ @assets_url = lmbda
94
+ end
95
+
96
+ def vertical_position
97
+ position.include?('bottom') ? 'bottom' : 'top'
98
+ end
99
+
100
+ def horizontal_position
101
+ position.include?('right') ? 'right' : 'left'
102
+ end
103
+
71
104
  def merge!(config)
72
105
  if config
73
106
  if Hash === config
74
- config.each{|k,v| instance_variable_set "@#{k}",v}
107
+ config.each { |k, v| instance_variable_set "@#{k}", v }
75
108
  else
76
- self.class.attributes.each{ |k|
109
+ self.class.attributes.each { |k|
77
110
  v = config.send k
78
111
  instance_variable_set "@#{k}", v if v
79
112
  }
80
113
  end
81
114
  end
82
- set_positions!
83
115
  end
84
116
 
85
- def set_positions!
86
- position = (self.position && self.position.match("-")) ? self.position.split("-") : ["top", "left"]
87
- self.vertical_position = position.first
88
- self.horizontal_position = position.last
89
- end
90
117
  end
91
118
  end
92
119
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Rack::MiniProfiler::Context
2
- attr_accessor :inject_js,:current_timer,:page_struct,:skip_backtrace,
3
- :full_backtrace,:discard, :mpt_init, :measure
4
+ attr_accessor :inject_js, :current_timer, :page_struct, :skip_backtrace,
5
+ :full_backtrace, :discard, :mpt_init, :measure
4
6
 
5
7
  def initialize(opts = {})
6
8
  opts["measure"] = true unless opts.key? "measure"
7
- opts.each do |k,v|
9
+ opts.each do |k, v|
8
10
  self.instance_variable_set('@' + k, v)
9
11
  end
10
12
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Rack::MiniProfiler::GCProfiler
2
4
 
3
5
  def initialize
@@ -28,7 +30,7 @@ class Rack::MiniProfiler::GCProfiler
28
30
  end
29
31
  end
30
32
 
31
- result = {:stats => stats, :ids => ids}
33
+ result = { stats: stats, ids: ids }
32
34
  @ignore << result.__id__
33
35
 
34
36
  result
@@ -36,10 +38,10 @@ class Rack::MiniProfiler::GCProfiler
36
38
 
37
39
  def diff_object_stats(before, after)
38
40
  diff = {}.compare_by_identity
39
- after.each do |k,v|
41
+ after.each do |k, v|
40
42
  diff[k] = v - before[k]
41
43
  end
42
- before.each do |k,v|
44
+ before.each do |k, v|
43
45
  diff[k] = 0 - v unless after.has_key?(k)
44
46
  end
45
47
 
@@ -48,7 +50,7 @@ class Rack::MiniProfiler::GCProfiler
48
50
 
49
51
  def analyze_strings(ids_before, ids_after)
50
52
  result = {}
51
- ids_after.each do |id,_|
53
+ ids_after.each do |id, _|
52
54
  obj = ObjectSpace._id2ref(id)
53
55
  if String === obj && !ids_before.include?(obj.object_id)
54
56
  result[obj] ||= 0
@@ -62,8 +64,8 @@ class Rack::MiniProfiler::GCProfiler
62
64
  new_objects = 0
63
65
  memory_allocated = 0
64
66
 
65
- ids_after.each do |id,_|
66
- if !ids_before.include?(id) && obj=ObjectSpace._id2ref(id)
67
+ ids_after.each do |id, _|
68
+ if !ids_before.include?(id) && obj = ObjectSpace._id2ref(id)
67
69
  # this is going to be version specific (may change in 2.1)
68
70
  size = ObjectSpace.memsize_of(obj)
69
71
  memory_allocated += size
@@ -78,15 +80,15 @@ class Rack::MiniProfiler::GCProfiler
78
80
  memory_allocated = 0
79
81
  objects = 0
80
82
 
81
- ids_before.each do |id,_|
82
- if obj=ObjectSpace._id2ref(id)
83
+ ids_before.each do |id, _|
84
+ if obj = ObjectSpace._id2ref(id)
83
85
  # this is going to be version specific (may change in 2.1)
84
86
  memory_allocated += ObjectSpace.memsize_of(obj)
85
87
  objects += 1
86
88
  end
87
89
  end
88
90
 
89
- [objects,memory_allocated]
91
+ [objects, memory_allocated]
90
92
  end
91
93
 
92
94
  def profile_gc(app, env)
@@ -105,7 +107,7 @@ class Rack::MiniProfiler::GCProfiler
105
107
  # so we don't blow out on memory
106
108
  prev_gc_state ? GC.disable : GC.enable
107
109
 
108
- diff = diff_object_stats(stat_before[:stats],stat_after[:stats])
110
+ diff = diff_object_stats(stat_before[:stats], stat_after[:stats])
109
111
  string_analysis = analyze_strings(stat_before[:ids], stat_after[:ids])
110
112
  new_objects, memory_allocated = analyze_growth(stat_before[:ids], stat_after[:ids])
111
113
  objects_before, memory_before = analyze_initial_state(stat_before[:ids])
@@ -120,7 +122,7 @@ Memory allocated outside heap (bytes): #{memory_before}
120
122
 
121
123
  GC Stats:
122
124
  --------
123
- #{stat.map{|k,v| "#{k} : #{v}" }.sort!.join("\n")}
125
+ #{stat.map { |k, v| "#{k} : #{v}" }.sort!.join("\n")}
124
126
 
125
127
  New bytes allocated outside of Ruby heaps: #{memory_allocated}
126
128
  New objects: #{new_objects}
@@ -129,7 +131,7 @@ New objects: #{new_objects}
129
131
  body << "
130
132
  ObjectSpace delta caused by request:
131
133
  -----------------------------------\n"
132
- diff.to_a.delete_if{|_k, v| v == 0}.sort_by! { |_k, v| v }.reverse_each do |k,v|
134
+ diff.to_a.delete_if { |_k, v| v == 0 }.sort_by! { |_k, v| v }.reverse_each do |k, v|
133
135
  body << "#{k} : #{v}\n"
134
136
  end
135
137
 
@@ -137,20 +139,19 @@ ObjectSpace delta caused by request:
137
139
  ObjectSpace stats:
138
140
  -----------------\n"
139
141
 
140
- stat_after[:stats].to_a.sort_by!{ |_k, v| v }.reverse_each do |k,v|
142
+ stat_after[:stats].to_a.sort_by! { |_k, v| v }.reverse_each do |k, v|
141
143
  body << "#{k} : #{v}\n"
142
144
  end
143
145
 
144
-
145
146
  body << "\n
146
147
  String stats:
147
148
  ------------\n"
148
149
 
149
- string_analysis.to_a.sort_by!{ |_k, v| -v }.take(1000).each do |string,count|
150
+ string_analysis.to_a.sort_by! { |_k, v| -v }.take(1000).each do |string, count|
150
151
  body << "#{count} : #{string}\n"
151
152
  end
152
153
 
153
- return [200, {'Content-Type' => 'text/plain'}, body]
154
+ [200, { 'Content-Type' => 'text/plain' }, body]
154
155
  ensure
155
156
  prev_gc_state ? GC.disable : GC.enable
156
157
  end