rack-mini-profiler 0.1.2 → 0.1.3
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.
- 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
|