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.

@@ -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
 
@@ -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, :post_authorize_cb, :position,
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
- def call(env)
156
- status = headers = body = nil
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.post_authorize_cb
166
- if @config.post_authorize_cb.call(env)
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['discard']
216
- if @config.post_authorize_cb && !@config.post_authorize_cb.call(env)
217
- self.class.remove_profiling_cookie(headers)
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['discard'] is not being properly treated
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 calls
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.insert_before 'Rack::Lock', 'Rack::MiniProfiler'
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}"}
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rack-mini-profiler"
3
- s.version = "0.1.2"
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.md"
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.2
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.md
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.md
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: 876564877
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: 876564877
142
+ hash: 809318397
143
143
  requirements: []
144
144
  rubyforge_project:
145
145
  rubygems_version: 1.8.24