rack-mini-profiler 0.9.7 → 0.9.8

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: 2417d22f7d7896ced32bc242d3e7f0b43eb73f6f
4
- data.tar.gz: 0a5d429ac232a90772dd17de9650fb12f6eb355c
3
+ metadata.gz: 661dc965f1499d7a00baa35f5699e91e1552ff68
4
+ data.tar.gz: 7bbccf4b17154aab14f7bd2012afcf2dac0efe25
5
5
  SHA512:
6
- metadata.gz: 1b33304bb3ccb9e659fc5a274d939cb2e8455a9a5427bd3fa46a98ff8d88d5b238ebfe3a46f6b2cee9730f88a1ebe585bae41ac716f988e5feecc6ac17231d48
7
- data.tar.gz: 8799e05e0fcea21ab023aa7e4594cb75e21c7315fa0c25478d275a3df815b37731cb490d3e64756d0bc2d206d00292b9c395a368349715c22cd7dbe328f2093b
6
+ metadata.gz: 903fe47823489fae4a2b18aff1cddca204130c1e41b2132c5db951007a5c1fe85b7b110f3264b8abc2f22c07d438071b81c93251bc31cbe26db725b868ca0a2a
7
+ data.tar.gz: 400bb2bf85475461de90d238eb95cbac925710f758f576c7371cb7b25ef0998bf39d637835520b42dd96fbbeb7cd53f36fe531f83e9e9c8c1cf36022795fcb8c
@@ -1,5 +1,14 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.9.8 - 2015-11-27 (Sam Saffron)
4
+
5
+ - [FEATURE] disable_env_dump config setting (@mathias)
6
+ - [FEATURE] set X-MiniProfiler-Ids for all 2XX reqs (@tymagu2)
7
+ - [FEATURE] add support for NoBrainer (rethinkdb) profiling (@niv)
8
+ - [FEATURE] add oracle enhanced adapter profiling (@rrooding)
9
+ - [FEATURE] pp=profile-memory can now parse query params (@dgynn)
10
+
11
+
3
12
  ## 0.9.7 - 2015-08-03 (Sam Saffron)
4
13
 
5
14
  - [FEATURE] remove confusing pp=profile-gc-time (Nate Berkopec)
data/README.md CHANGED
@@ -6,7 +6,7 @@ Middleware that displays speed badge for every html page. Designed to work both
6
6
 
7
7
  #### Features
8
8
 
9
- * database profiling. Currently supports Mysql2, Postgres, and Mongoid3 (with fallback support to ActiveRecord)
9
+ * database profiling. Currently supports Mysql2, Postgres, Oracle (oracle_enhanced ~> 1.5.0) and Mongoid3 (with fallback support to ActiveRecord)
10
10
 
11
11
  #### Learn more
12
12
 
@@ -89,20 +89,21 @@ To generate [flamegraphs](http://samsaffron.com/archive/2013/03/19/flame-graphs-
89
89
  * add the [**flamegraph**](https://github.com/SamSaffron/flamegraph) gem to your Gemfile
90
90
  * visit a page in your app with `?pp=flamegraph`
91
91
 
92
- Flamegraph generation is supported in MRI 2.0 and 2.1 only.
92
+ Flamegraph generation is supported in MRI 2.0, 2.1, and 2.2 only.
93
93
 
94
94
 
95
- ## Access control in production
95
+ ## Access control in non-development environments
96
96
 
97
97
  rack-mini-profiler is designed with production profiling in mind. To enable that just run `Rack::MiniProfiler.authorize_request` once you know a request is allowed to profile.
98
98
 
99
99
  ```ruby
100
- # A hook in your ApplicationController
101
- def authorize
102
- if current_user.is_admin?
103
- Rack::MiniProfiler.authorize_request
100
+ # inside your ApplicationController
101
+
102
+ before_action do
103
+ if current_user && current_user.is_admin?
104
+ Rack::MiniProfiler.authorize_request
105
+ end
104
106
  end
105
- end
106
107
  ```
107
108
 
108
109
  ## Configuration
@@ -189,6 +190,7 @@ The available configuration options are:
189
190
  * start_hidden (default false) - Whether or not you want the mini_profiler to be visible when loading a page
190
191
  * 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.
191
192
  * flamegraph_sample_rate (default 0.5ms) - How often fast_stack should get stack trace info to generate flamegraphs
193
+ * disable_env_dump (default false) - When enabled, disables the `?pp=env` which can be useful when you are concerned about not sending ENV vars out over HTTP.
192
194
 
193
195
  ### Custom middleware ordering (required if using `Rack::Deflate` with Rails)
194
196
 
@@ -12,10 +12,13 @@ module Rack
12
12
  @attributes
13
13
  end
14
14
 
15
- attr_accessor :authorization_mode, :auto_inject, :backtrace_ignores, :backtrace_includes, :backtrace_remove,
16
- :backtrace_threshold_ms, :base_url_path, :disable_caching, :enabled, :flamegraph_sample_rate, :logger, :position,
17
- :pre_authorize_cb, :skip_paths, :skip_schema_queries, :start_hidden, :storage, :storage_failure,
18
- :storage_instance, :storage_options, :toggle_shortcut, :user_provider
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, :position, :pre_authorize_cb,
19
+ :skip_paths, :skip_schema_queries, :start_hidden, :storage,
20
+ :storage_failure, :storage_instance, :storage_options, :toggle_shortcut,
21
+ :user_provider
19
22
 
20
23
  # Deprecated options
21
24
  attr_accessor :use_existing_jquery
@@ -44,6 +47,7 @@ module Rack
44
47
  end
45
48
  end
46
49
  @enabled = true
50
+ @disable_env_dump = false
47
51
  self
48
52
  }
49
53
  end
@@ -203,8 +203,14 @@ module Rack
203
203
  end
204
204
 
205
205
  if query_string =~ /pp=profile-memory/
206
+ query_params = Rack::Utils.parse_nested_query(query_string)
207
+ options = {
208
+ :ignore_files => query_params['memory_profiler_ignore_files'],
209
+ :allow_files => query_params['memory_profiler_allow_files'],
210
+ }
211
+ options[:top]= Integer(query_params['memory_profiler_top']) if query_params.key?('memory_profiler_top')
206
212
  result = StringIO.new
207
- report = MemoryProfiler.report do
213
+ report = MemoryProfiler.report(options) do
208
214
  _,_,body = @app.call(env)
209
215
  body.close if body.respond_to? :close
210
216
  end
@@ -285,7 +291,7 @@ module Rack
285
291
  if (config.authorization_mode == :whitelist && !MiniProfiler.request_authorized?)
286
292
  # this is non-obvious, don't kill the profiling cookie on errors or short requests
287
293
  # this ensures that stuff that never reaches the rails stack does not kill profiling
288
- if status == 200 && ((Time.now - start) > 0.1)
294
+ if status >= 200 && status < 300 && ((Time.now - start) > 0.1)
289
295
  client_settings.discard_cookie!(headers)
290
296
  end
291
297
  skip_it = true
@@ -299,7 +305,7 @@ module Rack
299
305
  return dump_exceptions exceptions
300
306
  end
301
307
 
302
- if query_string =~ /pp=env/
308
+ if query_string =~ /pp=env/ && !config.disable_env_dump
303
309
  body.close if body.respond_to? :close
304
310
  return dump_env env
305
311
  end
@@ -330,7 +336,7 @@ module Rack
330
336
  @storage.save(page_struct)
331
337
 
332
338
  # inject headers, script
333
- if headers['Content-Type'] && status == 200
339
+ if status >= 200 && status < 300
334
340
  client_settings.write!(headers)
335
341
  result = inject_profiler(env,status,headers,body)
336
342
  return result if result
@@ -552,7 +558,7 @@ Append the following to your query string:
552
558
  #{make_link "flamegraph", env} : works best on Ruby 2.0, a graph representing sampled activity (requires the flamegraph gem).
553
559
  #{make_link "flamegraph&flamegraph_sample_rate=1", env}: creates a flamegraph with the specified sample rate (in ms). Overrides value set in config
554
560
  #{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.
555
- #{make_link "trace-exceptions", env} : requires Ruby 2.0, will return all the spots where your application raises execptions
561
+ #{make_link "trace-exceptions", env} : requires Ruby 2.0, will return all the spots where your application raises exceptions
556
562
  #{make_link "analyze-memory", env} : requires Ruby 2.0, will perform basic memory analysis of heap
557
563
  </pre>
558
564
  </body>
@@ -588,7 +594,11 @@ Append the following to your query string:
588
594
  # * you have disabled auto append behaviour throught :auto_inject => false flag
589
595
  # * you do not want script to be automatically appended for the current page. You can also call cancel_auto_inject
590
596
  def get_profile_script(env)
591
- path = "#{env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME']}#{@config.base_url_path}"
597
+ path = if env["action_controller.instance"]
598
+ env["action_controller.instance"].url_for("#{@config.base_url_path}")
599
+ else
600
+ "#{env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME']}#{@config.base_url_path}"
601
+ end
592
602
 
593
603
  settings = {
594
604
  :path => path,
@@ -26,8 +26,14 @@ module Rack
26
26
  end
27
27
 
28
28
  private
29
- def path(key)
30
- @path + "/" + @prefix + "_" + key
29
+ if RUBY_PLATFORM =~ /mswin(?!ce)|mingw|cygwin|bccwin/
30
+ def path(key)
31
+ @path + "/" + @prefix + "_" + key.gsub(/:/, '_')
32
+ end
33
+ else
34
+ def path(key)
35
+ @path + "/" + @prefix + "_" + key
36
+ end
31
37
  end
32
38
  end
33
39
 
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class MiniProfiler
3
- VERSION = '0.9.7'
3
+ VERSION = '0.9.8'
4
4
  end
5
5
  end
@@ -24,8 +24,9 @@ module Rack::MiniProfilerRails
24
24
 
25
25
  c.skip_paths ||= []
26
26
 
27
+ c.skip_paths << app.config.assets.prefix if serves_static_assets?(app)
28
+
27
29
  if Rails.env.development?
28
- c.skip_paths << app.config.assets.prefix if app.respond_to? :assets
29
30
  c.skip_schema_queries = true
30
31
  end
31
32
 
@@ -64,6 +65,16 @@ module Rack::MiniProfilerRails
64
65
  @already_initialized = true
65
66
  end
66
67
 
68
+ def self.serves_static_assets?(app)
69
+ return false if !app.respond_to?(:assets)
70
+ # Rails 4.2 deprecates serve_static_assets in favor of serve_static_files
71
+ if app.config.respond_to?(:serve_static_files)
72
+ app.config.serve_static_files
73
+ else
74
+ app.config.serve_static_assets
75
+ end
76
+ end
77
+
67
78
  class Railtie < ::Rails::Railtie
68
79
 
69
80
  initializer "rack_mini_profiler.configure_rails_initialization" do |app|
@@ -0,0 +1,12 @@
1
+ # Mongo/Mongoid 5 patches
2
+ class Mongo::Server::Connection
3
+ def dispatch_with_timing(*args, &blk)
4
+ return dispatch_without_timing(*args, &blk) unless SqlPatches.should_measure?
5
+
6
+ result, _record = SqlPatches.record_sql(args[0][0].payload.inspect) do
7
+ dispatch_without_timing(*args, &blk)
8
+ end
9
+ return result
10
+ end
11
+ alias_method_chain :dispatch, :timing
12
+ end
@@ -0,0 +1,29 @@
1
+ class Rack::MiniProfiler::NoBrainerProfiler
2
+
3
+ def on_query(env)
4
+ if SqlPatches.should_measure?
5
+ not_indexed = env[:criteria] && env[:criteria].where_present? &&
6
+ !env[:criteria].where_indexed? &&
7
+ !env[:criteria].model.try(:perf_warnings_disabled)
8
+
9
+ query = ""
10
+
11
+ # per-model/query database overrides
12
+ query << "[#{env[:options][:db]}] " if env[:options][:db]
13
+
14
+ # "read", "write" prefix
15
+ # query << "(#{NoBrainer::RQL.type_of(env[:query]).to_s}) "
16
+
17
+ query << "NOT USING INDEX: " if not_indexed
18
+ query << env[:query].inspect.gsub(/\n/, '').gsub(/ +/, ' ') + " "
19
+
20
+ if env[:exception]
21
+ query << "exception: #{env[:exception].class} #{env[:exception].message.split("\n").first} "
22
+ end
23
+
24
+ ::Rack::MiniProfiler.record_sql query.strip, env[:duration] * 1000.0
25
+ end
26
+ end
27
+
28
+ NoBrainer::Profiler.register self.new
29
+ end
@@ -0,0 +1,70 @@
1
+ class ActiveRecord::Result
2
+ alias_method :each_without_profiling, :each
3
+ def each(&blk)
4
+ return each_without_profiling(&blk) unless @miniprofiler_sql_id
5
+
6
+ start = Time.now
7
+ result = each_without_profiling(&blk)
8
+ elapsed_time = SqlPatches.elapsed_time(start)
9
+ @miniprofiler_sql_id.report_reader_duration(elapsed_time)
10
+
11
+ result
12
+ end
13
+ end
14
+
15
+ class ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter
16
+ SCHEMA_QUERY_TYPES = ["Sequence", "Primary Key", "Primary Key Trigger", nil].freeze
17
+
18
+ alias_method :execute_without_profiling, :execute
19
+ def execute(sql, name = nil)
20
+ mp_profile_sql(sql, name) { execute_without_profiling(sql, name) }
21
+ end
22
+
23
+ alias_method :exec_query_without_profiling, :exec_query
24
+ def exec_query(sql, name = 'SQL', binds = [])
25
+ mp_profile_sql(sql, name) { exec_query_without_profiling(sql, name, binds) }
26
+ end
27
+
28
+ alias_method :exec_insert_without_profiling, :exec_insert
29
+ def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
30
+ mp_profile_sql(sql, name) { exec_insert_without_profiling(sql, name, binds, pk, sequence_name) }
31
+ end
32
+
33
+ alias_method :exec_update_without_profiling, :exec_update
34
+ def exec_update(sql, name, binds)
35
+ mp_profile_sql(sql, name) { exec_update_without_profiling(sql, name, binds) }
36
+ end
37
+
38
+ # See oracle-enhanced/lib/active_record/connection_adapters/oracle_enhanced_database_statements.rb:183
39
+ # where the exec delete method is aliased in the same way. We just have to do it again here to make sure
40
+ # the new exec_delete alias is linked to our profiling-enabled version.
41
+ alias :exec_delete :exec_update
42
+
43
+ private
44
+
45
+ def mp_profile_sql(sql, name, &blk)
46
+ return yield unless mp_should_measure?(name)
47
+
48
+ start = Time.now
49
+ result = yield
50
+ elapsed_time = SqlPatches.elapsed_time(start)
51
+ record = ::Rack::MiniProfiler.record_sql(sql, elapsed_time)
52
+
53
+ # Some queries return the row count as a Fixnum and will be frozen, don't save a record
54
+ # for those.
55
+ result.instance_variable_set("@miniprofiler_sql_id", record) if (result && !result.frozen?)
56
+
57
+ result
58
+ end
59
+
60
+ # Only measure when profiling is enabled
61
+ # When skip_schema_queries is set to true, it will ignore any query of the types
62
+ # in the schema_query_types array
63
+ def mp_should_measure?(name)
64
+ return false unless SqlPatches.should_measure?
65
+
66
+ !(Rack::MiniProfiler.config.skip_schema_queries && SCHEMA_QUERY_TYPES.include?(name))
67
+ end
68
+ end
69
+
70
+ SqlPatches.patched = true
@@ -14,6 +14,12 @@ class SqlPatches
14
14
  false
15
15
  end
16
16
 
17
+ def self.correct_version?(required_version, klass)
18
+ Gem::Dependency.new('', required_version).match?('', klass::VERSION)
19
+ rescue NameError
20
+ false
21
+ end
22
+
17
23
  def self.module_exists?(name)
18
24
  eval(name + ".class").to_s.eql?('Module')
19
25
  rescue NameError
@@ -37,10 +43,13 @@ class SqlPatches
37
43
  end
38
44
  end
39
45
 
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")
46
+ require 'patches/db/mysql2' if defined?(Mysql2::Client) && SqlPatches.class_exists?("Mysql2::Client")
47
+ require 'patches/db/pg' if defined?(PG::Result) && SqlPatches.class_exists?("PG::Result")
48
+ require 'patches/db/oracle_enhanced' if defined?(ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter) && SqlPatches.class_exists?("ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter") && SqlPatches.correct_version?('~> 1.5.0', ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter)
49
+ require 'patches/db/mongo' if defined?(Mongo) &&!SqlPatches.patched? && SqlPatches.module_exists?("Mongo")
50
+ require 'patches/db/moped' if defined?(Moped::Node) && SqlPatches.class_exists?("Moped::Node")
51
+ require 'patches/db/plucky' if defined?(Plucky::Query) && SqlPatches.class_exists?("Plucky::Query")
52
+ require 'patches/db/rsolr' if defined?(RSolr::Connection) && SqlPatches.class_exists?("RSolr::Connection") && RSolr::VERSION[0] != "0"
53
+ require 'patches/db/sequel' if defined?(Sequel::Database) && !SqlPatches.patched? && SqlPatches.class_exists?("Sequel::Database")
54
+ require 'patches/db/activerecord' if defined?(ActiveRecord) &&!SqlPatches.patched? && SqlPatches.module_exists?("ActiveRecord")
55
+ require 'patches/db/nobrainer' if defined?(NoBrainer) && SqlPatches.module_exists?("NoBrainer")
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.7
4
+ version: 0.9.8
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-08-03 00:00:00.000000000 Z
13
+ date: 2015-11-27 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack
@@ -223,8 +223,11 @@ files:
223
223
  - lib/mini_profiler/version.rb
224
224
  - lib/mini_profiler_rails/railtie.rb
225
225
  - lib/patches/db/activerecord.rb
226
+ - lib/patches/db/mongo.rb
226
227
  - lib/patches/db/moped.rb
227
228
  - lib/patches/db/mysql2.rb
229
+ - lib/patches/db/nobrainer.rb
230
+ - lib/patches/db/oracle_enhanced.rb
228
231
  - lib/patches/db/pg.rb
229
232
  - lib/patches/db/plucky.rb
230
233
  - lib/patches/db/rsolr.rb
@@ -253,7 +256,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
253
256
  version: '0'
254
257
  requirements: []
255
258
  rubyforge_project:
256
- rubygems_version: 2.4.5
259
+ rubygems_version: 2.4.5.1
257
260
  signing_key:
258
261
  specification_version: 4
259
262
  summary: Profiles loading speed for rack applications.