rack-mini-profiler 0.1.2 → 0.1.3
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.
- data/{CHANGELOG.md → CHANGELOG} +9 -0
- data/README.md +17 -2
- data/lib/mini_profiler/config.rb +3 -3
- data/lib/mini_profiler/profiler.rb +46 -27
- data/lib/mini_profiler/request_timer_struct.rb +2 -2
- data/lib/mini_profiler/sql_timer_struct.rb +3 -3
- data/lib/mini_profiler_rails/railtie.rb +6 -3
- data/rack-mini-profiler.gemspec +2 -2
- metadata +5 -5
data/{CHANGELOG.md → CHANGELOG}
RENAMED
@@ -6,3 +6,12 @@
|
|
6
6
|
* Fixed bug where unviewed missing ids never got cleared
|
7
7
|
* Supress all '/assets/' in the rails tie (makes debugging easier)
|
8
8
|
* record_sql was mega buggy
|
9
|
+
|
10
|
+
9-July-2012 - Sam
|
11
|
+
|
12
|
+
* Cleaned up mechanism for profiling in production, all you need to do now
|
13
|
+
is call Rack::MiniProfiler.authorize_request to get profiling working in
|
14
|
+
production
|
15
|
+
* Added option to display full backtraces pp=full-backtrace
|
16
|
+
* Cleaned up railties, got rid of the post authorize callback
|
17
|
+
* Version 0.1.3
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Middleware that displays speed badge for every html page. Designed to work both in production and in development.
|
4
4
|
|
5
|
-
## Using mini-profiler in your app
|
5
|
+
## Using rack-mini-profiler in your app
|
6
6
|
|
7
7
|
Install/add to Gemfile
|
8
8
|
|
@@ -13,6 +13,20 @@ Using Rails:
|
|
13
13
|
|
14
14
|
All you have to do is include the Gem and you're good to go in development.
|
15
15
|
|
16
|
+
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.
|
17
|
+
|
18
|
+
For example:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
# A hook in your ApplicationController
|
22
|
+
def authorize
|
23
|
+
if current_user.is_admin?
|
24
|
+
Rack::MiniProfiler.authorize_request
|
25
|
+
end
|
26
|
+
end
|
27
|
+
````
|
28
|
+
|
29
|
+
|
16
30
|
Using Builder:
|
17
31
|
|
18
32
|
```ruby
|
@@ -56,9 +70,10 @@ In a Rails app, this can be done conveniently in an initializer such as config/i
|
|
56
70
|
## Available Options
|
57
71
|
|
58
72
|
* 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.
|
59
|
-
* post_authorize_cb - A lambda that is called after your request executed to ensure you really have access to the results.
|
60
73
|
* position - Can either be 'right' or 'left'. Default is 'left'.
|
61
74
|
* 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.
|
62
75
|
|
76
|
+
## Special query strings
|
63
77
|
|
78
|
+
If you include the query string `pp=help` at the end of your request you will see the various option you have. You can use these options to extend or contract the amount of diagnostics rack-mini-profiler gathers.
|
64
79
|
|
data/lib/mini_profiler/config.rb
CHANGED
@@ -12,9 +12,9 @@ module Rack
|
|
12
12
|
@attributes
|
13
13
|
end
|
14
14
|
|
15
|
-
attr_accessor :auto_inject, :base_url_path, :pre_authorize_cb, :
|
15
|
+
attr_accessor :auto_inject, :base_url_path, :pre_authorize_cb, :position,
|
16
16
|
:backtrace_remove, :backtrace_filter, :skip_schema_queries,
|
17
|
-
:storage, :user_provider, :storage_instance, :storage_options, :skip_paths
|
17
|
+
:storage, :user_provider, :storage_instance, :storage_options, :skip_paths, :authorization_mode
|
18
18
|
|
19
19
|
def self.default
|
20
20
|
new.instance_eval {
|
@@ -25,11 +25,11 @@ module Rack
|
|
25
25
|
@pre_authorize_cb = lambda {|env| true}
|
26
26
|
|
27
27
|
# called after rack chain, to ensure we are REALLY allowed to profile
|
28
|
-
@post_authorize_cb = nil
|
29
28
|
@position = 'left' # Where it is displayed
|
30
29
|
@skip_schema_queries = false
|
31
30
|
@storage = MiniProfiler::MemoryStore
|
32
31
|
@user_provider = Proc.new{|env| Rack::Request.new(env).ip}
|
32
|
+
@authorization_mode = :allow_all
|
33
33
|
self
|
34
34
|
}
|
35
35
|
end
|
@@ -114,15 +114,26 @@ module Rack
|
|
114
114
|
# we use TLS cause we need access to this from sql blocks and code blocks that have no access to env
|
115
115
|
Thread.current['profiler.mini.private'] = c
|
116
116
|
end
|
117
|
+
|
118
|
+
def current
|
119
|
+
MiniProfiler.current
|
120
|
+
end
|
121
|
+
|
122
|
+
def current=(c)
|
123
|
+
MiniProfiler.current=c
|
124
|
+
end
|
117
125
|
|
126
|
+
# discard existing results, don't track this request
|
118
127
|
def self.discard_results
|
119
128
|
current[:discard] = true if current
|
120
129
|
end
|
121
|
-
|
130
|
+
|
131
|
+
# user has the mini profiler cookie, only used when config.authorization_mode == :whitelist
|
122
132
|
def self.has_profiling_cookie?(env)
|
123
133
|
env['HTTP_COOKIE'] && env['HTTP_COOKIE'].include?("__profilin=stylin")
|
124
134
|
end
|
125
135
|
|
136
|
+
# remove the mini profiler cookie, only used when config.authorization_mode == :whitelist
|
126
137
|
def self.remove_profiling_cookie(headers)
|
127
138
|
Rack::Utils.delete_cookie_header!(headers, '__profilin')
|
128
139
|
end
|
@@ -131,14 +142,6 @@ module Rack
|
|
131
142
|
Rack::Utils.set_cookie_header!(headers, '__profilin', 'stylin')
|
132
143
|
end
|
133
144
|
|
134
|
-
def current
|
135
|
-
MiniProfiler.current
|
136
|
-
end
|
137
|
-
|
138
|
-
def current=(c)
|
139
|
-
MiniProfiler.current=c
|
140
|
-
end
|
141
|
-
|
142
145
|
def config
|
143
146
|
@config
|
144
147
|
end
|
@@ -151,21 +154,32 @@ module Rack
|
|
151
154
|
self.current['current_timer'] = current['page_struct']['Root']
|
152
155
|
end
|
153
156
|
|
157
|
+
def self.authorize_request
|
158
|
+
Thread.current[:mp_authorized] = true
|
159
|
+
end
|
154
160
|
|
155
|
-
|
156
|
-
|
161
|
+
def self.deauthorize_request
|
162
|
+
Thread.current[:mp_authorized] = nil
|
163
|
+
end
|
157
164
|
|
165
|
+
def self.request_authorized?
|
166
|
+
Thread.current[:mp_authorized]
|
167
|
+
end
|
168
|
+
|
169
|
+
def call(env)
|
170
|
+
status = headers = body = nil
|
158
171
|
path = env['PATH_INFO']
|
159
|
-
# only profile if authorized
|
160
|
-
if !@config.pre_authorize_cb.call(env) ||
|
161
|
-
(@config.skip_paths && @config.skip_paths.any?{ |p| path[0,p.length] == p}) ||
|
162
|
-
env["QUERY_STRING"] =~ /pp=skip/
|
163
172
|
|
173
|
+
skip_it = (@config.pre_authorize_cb && !@config.pre_authorize_cb.call(env)) ||
|
174
|
+
(@config.skip_paths && @config.skip_paths.any?{ |p| path[0,p.length] == p}) ||
|
175
|
+
env["QUERY_STRING"] =~ /pp=skip/
|
176
|
+
|
177
|
+
has_profiling_cookie = self.class.has_profiling_cookie?(env)
|
178
|
+
|
179
|
+
if skip_it || (@config.authorization_mode == :whitelist && !has_profiling_cookie)
|
164
180
|
status,headers,body = @app.call(env)
|
165
|
-
if @config.
|
166
|
-
|
167
|
-
self.class.set_profiling_cookie(headers)
|
168
|
-
end
|
181
|
+
if !skip_it && @config.authorization_mode == :whitelist && !has_profiling_cookie && MiniProfiler.request_authorized?
|
182
|
+
self.class.set_profiling_cookie(headers)
|
169
183
|
end
|
170
184
|
return [status,headers,body]
|
171
185
|
end
|
@@ -174,10 +188,14 @@ module Rack
|
|
174
188
|
return serve_html(env) if env['PATH_INFO'].start_with? @config.base_url_path
|
175
189
|
|
176
190
|
MiniProfiler.create_current(env, @config)
|
191
|
+
|
192
|
+
MiniProfiler.deauthorize_request if @config.authorization_mode == :whitelist
|
177
193
|
if env["QUERY_STRING"] =~ /pp=no-backtrace/
|
178
194
|
current['skip-backtrace'] = true
|
195
|
+
elsif env["QUERY_STRING"] =~ /pp=full-backtrace/
|
196
|
+
current['full-backtrace'] = true
|
179
197
|
end
|
180
|
-
|
198
|
+
|
181
199
|
done_sampling = false
|
182
200
|
quit_sampler = false
|
183
201
|
backtraces = nil
|
@@ -212,15 +230,15 @@ module Rack
|
|
212
230
|
end
|
213
231
|
end
|
214
232
|
|
215
|
-
skip_it = current[
|
216
|
-
if
|
217
|
-
|
233
|
+
skip_it = current[:discard]
|
234
|
+
if (config.authorization_mode == :whitelist && !MiniProfiler.request_authorized?)
|
235
|
+
MiniProfiler.remove_profiling_cookie(headers)
|
218
236
|
skip_it = true
|
219
237
|
end
|
220
|
-
|
238
|
+
|
221
239
|
return [status,headers,body] if skip_it
|
222
240
|
|
223
|
-
# we must do this here, otherwise current[
|
241
|
+
# we must do this here, otherwise current[:discard] is not being properly treated
|
224
242
|
if env["QUERY_STRING"] =~ /pp=env/
|
225
243
|
body.close if body.respond_to? :close
|
226
244
|
return dump_env env
|
@@ -287,7 +305,8 @@ module Rack
|
|
287
305
|
pp=help : display this screen
|
288
306
|
pp=env : display the rack environment
|
289
307
|
pp=skip : skip mini profiler for this request
|
290
|
-
pp=no-backtrace : don't collect stack traces from all the SQL
|
308
|
+
pp=no-backtrace : don't collect stack traces from all the SQL executed
|
309
|
+
pp=full-backtrace : enable full backtrace for SQL executed
|
291
310
|
pp=sample : sample stack traces and return a report isolating heavy usage (requires the stacktrace gem)
|
292
311
|
"
|
293
312
|
#headers['Content-Length'] = body.length
|
@@ -383,7 +402,7 @@ module Rack
|
|
383
402
|
|
384
403
|
def record_sql(query, elapsed_ms)
|
385
404
|
c = current
|
386
|
-
c['current_timer'].add_sql(query, elapsed_ms, c['page_struct'], c['skip-backtrace']) if (c && c['current_timer'])
|
405
|
+
c['current_timer'].add_sql(query, elapsed_ms, c['page_struct'], c['skip-backtrace'], c['full-backtrace']) if (c && c['current_timer'])
|
387
406
|
end
|
388
407
|
|
389
408
|
end
|
@@ -45,8 +45,8 @@ module Rack
|
|
45
45
|
@children_duration += request_timer['DurationMilliseconds']
|
46
46
|
end
|
47
47
|
|
48
|
-
def add_sql(query, elapsed_ms, page, skip_backtrace = false)
|
49
|
-
timer = SqlTimerStruct.new(query, elapsed_ms, page, skip_backtrace)
|
48
|
+
def add_sql(query, elapsed_ms, page, skip_backtrace = false, full_backtrace = false)
|
49
|
+
timer = SqlTimerStruct.new(query, elapsed_ms, page, skip_backtrace, full_backtrace)
|
50
50
|
timer['ParentTimingId'] = self['Id']
|
51
51
|
self['SqlTimings'].push(timer)
|
52
52
|
self['HasSqlTimings'] = true
|
@@ -5,7 +5,7 @@ module Rack
|
|
5
5
|
|
6
6
|
# Timing system for a SQL query
|
7
7
|
class SqlTimerStruct < TimerStruct
|
8
|
-
def initialize(query, duration_ms, page, skip_backtrace = false)
|
8
|
+
def initialize(query, duration_ms, page, skip_backtrace = false, full_backtrace = false)
|
9
9
|
|
10
10
|
stack_trace = nil
|
11
11
|
unless skip_backtrace
|
@@ -13,8 +13,8 @@ module Rack
|
|
13
13
|
stack_trace = ""
|
14
14
|
# Clean up the stack trace if there are options to do so
|
15
15
|
Kernel.caller.each do |ln|
|
16
|
-
ln.gsub!(Rack::MiniProfiler.config.backtrace_remove, '') if Rack::MiniProfiler.config.backtrace_remove
|
17
|
-
if Rack::MiniProfiler.config.backtrace_filter.nil? or ln =~ Rack::MiniProfiler.config.backtrace_filter
|
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
|
18
18
|
stack_trace << ln << "\n"
|
19
19
|
end
|
20
20
|
end
|
@@ -6,8 +6,7 @@ module MiniProfilerRails
|
|
6
6
|
|
7
7
|
# By default, only show the MiniProfiler in development mode, in production allow profiling if post_authorize_cb is set
|
8
8
|
c.pre_authorize_cb = lambda { |env|
|
9
|
-
Rails.env.development? ||
|
10
|
-
(Rack::MiniProfiler.config.post_authorize_cb && Rack::MiniProfiler.has_profiling_cookie?(env))
|
9
|
+
Rails.env.development? || Rails.env.production?
|
11
10
|
}
|
12
11
|
|
13
12
|
if Rails.env.development?
|
@@ -16,6 +15,10 @@ module MiniProfilerRails
|
|
16
15
|
c.skip_schema_queries = true
|
17
16
|
end
|
18
17
|
|
18
|
+
if Rails.env.production?
|
19
|
+
c.authorization_mode = :whitelist
|
20
|
+
end
|
21
|
+
|
19
22
|
# The file store is just so much less flaky
|
20
23
|
tmp = Rails.root.to_s + "/tmp/miniprofiler"
|
21
24
|
Dir::mkdir(tmp) unless File.exists?(tmp)
|
@@ -29,7 +32,7 @@ module MiniProfilerRails
|
|
29
32
|
c.skip_schema_queries = Rails.env != 'production'
|
30
33
|
|
31
34
|
# Install the Middleware
|
32
|
-
app.middleware.
|
35
|
+
app.middleware.insert(0, Rack::MiniProfiler)
|
33
36
|
|
34
37
|
# Attach to various Rails methods
|
35
38
|
::Rack::MiniProfiler.profile_method(ActionController::Base, :process) {|action| "Executing action: #{action}"}
|
data/rack-mini-profiler.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rack-mini-profiler"
|
3
|
-
s.version = "0.1.
|
3
|
+
s.version = "0.1.3"
|
4
4
|
s.summary = "Profiles loading speed for rack applications."
|
5
5
|
s.authors = ["Aleks Totic","Sam Saffron", "Robin Ward"]
|
6
6
|
s.date = "2012-04-02"
|
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
|
|
12
12
|
].concat( Dir.glob('lib/**/*').reject {|f| File.directory?(f) || f =~ /~$/ } )
|
13
13
|
s.extra_rdoc_files = [
|
14
14
|
"README.md",
|
15
|
-
"CHANGELOG
|
15
|
+
"CHANGELOG"
|
16
16
|
]
|
17
17
|
s.add_runtime_dependency 'rack', '>= 1.1.3'
|
18
18
|
if RUBY_VERSION < "1.9"
|
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.1.
|
4
|
+
version: 0.1.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -84,7 +84,7 @@ executables: []
|
|
84
84
|
extensions: []
|
85
85
|
extra_rdoc_files:
|
86
86
|
- README.md
|
87
|
-
- CHANGELOG
|
87
|
+
- CHANGELOG
|
88
88
|
files:
|
89
89
|
- rack-mini-profiler.gemspec
|
90
90
|
- lib/mini_profiler/sql_timer_struct.rb
|
@@ -115,7 +115,7 @@ files:
|
|
115
115
|
- lib/mini_profiler_rails/railtie.rb
|
116
116
|
- lib/patches/sql_patches.rb
|
117
117
|
- README.md
|
118
|
-
- CHANGELOG
|
118
|
+
- CHANGELOG
|
119
119
|
homepage: http://miniprofiler.com
|
120
120
|
licenses: []
|
121
121
|
post_install_message:
|
@@ -130,7 +130,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
130
|
version: '0'
|
131
131
|
segments:
|
132
132
|
- 0
|
133
|
-
hash:
|
133
|
+
hash: 809318397
|
134
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
135
|
none: false
|
136
136
|
requirements:
|
@@ -139,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
139
|
version: '0'
|
140
140
|
segments:
|
141
141
|
- 0
|
142
|
-
hash:
|
142
|
+
hash: 809318397
|
143
143
|
requirements: []
|
144
144
|
rubyforge_project:
|
145
145
|
rubygems_version: 1.8.24
|