rack-mini-profiler 0.9.7 → 0.9.8
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +10 -8
- data/lib/mini_profiler/config.rb +8 -4
- data/lib/mini_profiler/profiler.rb +16 -6
- data/lib/mini_profiler/storage/file_store.rb +8 -2
- data/lib/mini_profiler/version.rb +1 -1
- data/lib/mini_profiler_rails/railtie.rb +12 -1
- data/lib/patches/db/mongo.rb +12 -0
- data/lib/patches/db/nobrainer.rb +29 -0
- data/lib/patches/db/oracle_enhanced.rb +70 -0
- data/lib/patches/sql_patches.rb +16 -7
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 661dc965f1499d7a00baa35f5699e91e1552ff68
|
4
|
+
data.tar.gz: 7bbccf4b17154aab14f7bd2012afcf2dac0efe25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 903fe47823489fae4a2b18aff1cddca204130c1e41b2132c5db951007a5c1fe85b7b110f3264b8abc2f22c07d438071b81c93251bc31cbe26db725b868ca0a2a
|
7
|
+
data.tar.gz: 400bb2bf85475461de90d238eb95cbac925710f758f576c7371cb7b25ef0998bf39d637835520b42dd96fbbeb7cd53f36fe531f83e9e9c8c1cf36022795fcb8c
|
data/CHANGELOG.md
CHANGED
@@ -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.
|
92
|
+
Flamegraph generation is supported in MRI 2.0, 2.1, and 2.2 only.
|
93
93
|
|
94
94
|
|
95
|
-
## Access control in
|
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
|
-
#
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
|
data/lib/mini_profiler/config.rb
CHANGED
@@ -12,10 +12,13 @@ module Rack
|
|
12
12
|
@attributes
|
13
13
|
end
|
14
14
|
|
15
|
-
attr_accessor :authorization_mode, :auto_inject, :backtrace_ignores,
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
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
|
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
|
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
|
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
|
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
|
-
|
30
|
-
|
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
|
|
@@ -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
|
data/lib/patches/sql_patches.rb
CHANGED
@@ -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'
|
41
|
-
require 'patches/db/pg'
|
42
|
-
require 'patches/db/
|
43
|
-
require 'patches/db/
|
44
|
-
require 'patches/db/
|
45
|
-
require 'patches/db/
|
46
|
-
require 'patches/db/
|
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.
|
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-
|
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.
|