rack-mini-profiler 0.1.1 → 0.1.2
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 +1 -0
- data/README.md +7 -15
- data/lib/html/includes.js +12 -0
- data/lib/mini_profiler/config.rb +51 -0
- data/lib/mini_profiler/profiler.rb +125 -45
- data/lib/mini_profiler/sql_timer_struct.rb +3 -3
- data/lib/mini_profiler_rails/railtie.rb +17 -8
- data/lib/patches/sql_patches.rb +2 -9
- data/rack-mini-profiler.gemspec +1 -1
- metadata +4 -3
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,13 +1,6 @@
|
|
1
1
|
# rack-mini-profiler
|
2
2
|
|
3
|
-
Middleware that displays speed badge for every html page.
|
4
|
-
|
5
|
-
## What does it do
|
6
|
-
|
7
|
-
MiniProfiler keeps you aware of your site's performance as you are developing it.
|
8
|
-
It does this by....
|
9
|
-
|
10
|
-
`env['profiler.mini']` is the profiler
|
3
|
+
Middleware that displays speed badge for every html page. Designed to work both in production and in development.
|
11
4
|
|
12
5
|
## Using mini-profiler in your app
|
13
6
|
|
@@ -16,12 +9,9 @@ Install/add to Gemfile
|
|
16
9
|
```ruby
|
17
10
|
gem 'rack-mini-profiler'
|
18
11
|
```
|
19
|
-
|
20
|
-
Add it to your middleware stack:
|
21
|
-
|
22
12
|
Using Rails:
|
23
13
|
|
24
|
-
All you have to do is include the Gem and you're good to go.
|
14
|
+
All you have to do is include the Gem and you're good to go in development.
|
25
15
|
|
26
16
|
Using Builder:
|
27
17
|
|
@@ -58,15 +48,17 @@ You can set configuration options using the configuration accessor on Rack::Mini
|
|
58
48
|
|
59
49
|
```
|
60
50
|
# Have Mini Profiler show up on the right
|
61
|
-
Rack::MiniProfiler.
|
51
|
+
Rack::MiniProfiler.config.position = 'right'
|
62
52
|
```
|
63
53
|
|
64
54
|
In a Rails app, this can be done conveniently in an initializer such as config/initializers/mini_profiler.rb.
|
65
55
|
|
66
56
|
## Available Options
|
67
57
|
|
68
|
-
*
|
58
|
+
* 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.
|
69
60
|
* position - Can either be 'right' or 'left'. Default is 'left'.
|
70
|
-
* skip_schema_queries - Whether or not you want to log the queries about the schema of your tables. Default is 'true'
|
61
|
+
* 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
|
+
|
71
63
|
|
72
64
|
|
data/lib/html/includes.js
CHANGED
@@ -475,6 +475,18 @@ var MiniProfiler = (function ($) {
|
|
475
475
|
})();
|
476
476
|
}
|
477
477
|
|
478
|
+
// also fetch results after ExtJS requests, in case it is being used
|
479
|
+
if (typeof (Ext) != 'undefined' && typeof (Ext.Ajax) != 'undefined' && typeof (Ext.Ajax.on) != 'undefined') {
|
480
|
+
// Ext.Ajax is a singleton, so we just have to attach to its 'requestcomplete' event
|
481
|
+
Ext.Ajax.on('requestcomplete', function(e, xhr, settings) {
|
482
|
+
var stringIds = xhr.getResponseHeader('X-MiniProfiler-Ids');
|
483
|
+
if (stringIds) {
|
484
|
+
var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
|
485
|
+
fetchResults(ids);
|
486
|
+
}
|
487
|
+
});
|
488
|
+
}
|
489
|
+
|
478
490
|
// some elements want to be hidden on certain doc events
|
479
491
|
bindDocumentEvents();
|
480
492
|
};
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Rack
|
2
|
+
class MiniProfiler
|
3
|
+
class Config
|
4
|
+
|
5
|
+
def self.attr_accessor(*vars)
|
6
|
+
@attributes ||= []
|
7
|
+
@attributes.concat vars
|
8
|
+
super(*vars)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.attributes
|
12
|
+
@attributes
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_accessor :auto_inject, :base_url_path, :pre_authorize_cb, :post_authorize_cb, :position,
|
16
|
+
:backtrace_remove, :backtrace_filter, :skip_schema_queries,
|
17
|
+
:storage, :user_provider, :storage_instance, :storage_options, :skip_paths
|
18
|
+
|
19
|
+
def self.default
|
20
|
+
new.instance_eval {
|
21
|
+
@auto_inject = true # automatically inject on every html page
|
22
|
+
@base_url_path = "/mini-profiler-resources/"
|
23
|
+
|
24
|
+
# called prior to rack chain, to ensure we are allowed to profile
|
25
|
+
@pre_authorize_cb = lambda {|env| true}
|
26
|
+
|
27
|
+
# called after rack chain, to ensure we are REALLY allowed to profile
|
28
|
+
@post_authorize_cb = nil
|
29
|
+
@position = 'left' # Where it is displayed
|
30
|
+
@skip_schema_queries = false
|
31
|
+
@storage = MiniProfiler::MemoryStore
|
32
|
+
@user_provider = Proc.new{|env| Rack::Request.new(env).ip}
|
33
|
+
self
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def merge!(config)
|
38
|
+
return unless config
|
39
|
+
if Hash === config
|
40
|
+
config.each{|k,v| instance_variable_set "@#{k}",v}
|
41
|
+
else
|
42
|
+
self.class.attributes.each{ |k|
|
43
|
+
v = config.send k
|
44
|
+
instance_variable_set "@#{k}", v if v
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -11,6 +11,7 @@ require 'mini_profiler/storage/abstract_store'
|
|
11
11
|
require 'mini_profiler/storage/memory_store'
|
12
12
|
require 'mini_profiler/storage/redis_store'
|
13
13
|
require 'mini_profiler/storage/file_store'
|
14
|
+
require 'mini_profiler/config'
|
14
15
|
|
15
16
|
module Rack
|
16
17
|
|
@@ -27,28 +28,13 @@ module Rack
|
|
27
28
|
rand(36**20).to_s(36)
|
28
29
|
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
{
|
33
|
-
:auto_inject => true, # automatically inject on every html page
|
34
|
-
:base_url_path => "/mini-profiler-resources/",
|
35
|
-
:authorize_cb => lambda {|env| true}, # callback returns true if this request is authorized to profile
|
36
|
-
:position => 'left', # Where it is displayed
|
37
|
-
:backtrace_remove => nil,
|
38
|
-
:backtrace_filter => nil,
|
39
|
-
:skip_schema_queries => true,
|
40
|
-
:storage => MiniProfiler::MemoryStore,
|
41
|
-
:user_provider => Proc.new{|env| Rack::Request.new(env).ip }
|
42
|
-
}
|
43
|
-
end
|
44
|
-
|
45
|
-
def self.reset_configuration
|
46
|
-
@configuration = configuration_defaults
|
31
|
+
def self.reset_config
|
32
|
+
@config = Config.default
|
47
33
|
end
|
48
34
|
|
49
35
|
# So we can change the configuration if we want
|
50
|
-
def self.
|
51
|
-
@
|
36
|
+
def self.config
|
37
|
+
@config ||= Config.default
|
52
38
|
end
|
53
39
|
|
54
40
|
def self.share_template
|
@@ -59,19 +45,19 @@ module Rack
|
|
59
45
|
#
|
60
46
|
# options:
|
61
47
|
# :auto_inject - should script be automatically injected on every html page (not xhr)
|
62
|
-
def initialize(app,
|
48
|
+
def initialize(app, config = nil)
|
63
49
|
@@instance = self
|
64
|
-
MiniProfiler.
|
65
|
-
@
|
50
|
+
MiniProfiler.config.merge!(config)
|
51
|
+
@config = MiniProfiler.config
|
66
52
|
@app = app
|
67
|
-
@
|
68
|
-
unless @
|
69
|
-
@storage = @
|
53
|
+
@config.base_url_path << "/" unless @config.base_url_path.end_with? "/"
|
54
|
+
unless @config.storage_instance
|
55
|
+
@storage = @config.storage_instance = @config.storage.new(@config.storage_options)
|
70
56
|
end
|
71
57
|
end
|
72
58
|
|
73
59
|
def user(env)
|
74
|
-
|
60
|
+
@config.user_provider.call(env)
|
75
61
|
end
|
76
62
|
|
77
63
|
def serve_results(env)
|
@@ -97,7 +83,7 @@ module Rack
|
|
97
83
|
|
98
84
|
# Otherwise give the HTML back
|
99
85
|
html = MiniProfiler.share_template.dup
|
100
|
-
html.gsub!(/\{path\}/, @
|
86
|
+
html.gsub!(/\{path\}/, @config.base_url_path)
|
101
87
|
html.gsub!(/\{version\}/, MiniProfiler::VERSION)
|
102
88
|
html.gsub!(/\{json\}/, result_json)
|
103
89
|
html.gsub!(/\{includes\}/, get_profile_script(env))
|
@@ -110,7 +96,7 @@ module Rack
|
|
110
96
|
end
|
111
97
|
|
112
98
|
def serve_html(env)
|
113
|
-
file_name = env['PATH_INFO'][(@
|
99
|
+
file_name = env['PATH_INFO'][(@config.base_url_path.length)..1000]
|
114
100
|
return serve_results(env) if file_name.eql?('results')
|
115
101
|
full_path = ::File.expand_path("../html/#{file_name}", ::File.dirname(__FILE__))
|
116
102
|
return [404, {}, ["Not found"]] unless ::File.exists? full_path
|
@@ -128,7 +114,23 @@ module Rack
|
|
128
114
|
# we use TLS cause we need access to this from sql blocks and code blocks that have no access to env
|
129
115
|
Thread.current['profiler.mini.private'] = c
|
130
116
|
end
|
131
|
-
|
117
|
+
|
118
|
+
def self.discard_results
|
119
|
+
current[:discard] = true if current
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.has_profiling_cookie?(env)
|
123
|
+
env['HTTP_COOKIE'] && env['HTTP_COOKIE'].include?("__profilin=stylin")
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.remove_profiling_cookie(headers)
|
127
|
+
Rack::Utils.delete_cookie_header!(headers, '__profilin')
|
128
|
+
end
|
129
|
+
|
130
|
+
def self.set_profiling_cookie(headers)
|
131
|
+
Rack::Utils.set_cookie_header!(headers, '__profilin', 'stylin')
|
132
|
+
end
|
133
|
+
|
132
134
|
def current
|
133
135
|
MiniProfiler.current
|
134
136
|
end
|
@@ -137,34 +139,45 @@ module Rack
|
|
137
139
|
MiniProfiler.current=c
|
138
140
|
end
|
139
141
|
|
140
|
-
def
|
141
|
-
@
|
142
|
+
def config
|
143
|
+
@config
|
142
144
|
end
|
143
145
|
|
144
146
|
def self.create_current(env={}, options={})
|
145
147
|
# profiling the request
|
146
148
|
self.current = {}
|
147
|
-
self.current['inject_js'] =
|
149
|
+
self.current['inject_js'] = config.auto_inject && (!env['HTTP_X_REQUESTED_WITH'].eql? 'XMLHttpRequest')
|
148
150
|
self.current['page_struct'] = PageTimerStruct.new(env)
|
149
151
|
self.current['current_timer'] = current['page_struct']['Root']
|
150
152
|
end
|
151
153
|
|
154
|
+
|
152
155
|
def call(env)
|
153
156
|
status = headers = body = nil
|
154
157
|
|
158
|
+
path = env['PATH_INFO']
|
155
159
|
# only profile if authorized
|
156
|
-
|
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
|
+
|
164
|
+
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
|
169
|
+
end
|
170
|
+
return [status,headers,body]
|
171
|
+
end
|
157
172
|
|
158
|
-
|
159
|
-
return serve_html(env) if env['PATH_INFO'].start_with? @
|
173
|
+
# handle all /mini-profiler requests here
|
174
|
+
return serve_html(env) if env['PATH_INFO'].start_with? @config.base_url_path
|
160
175
|
|
161
|
-
MiniProfiler.create_current(env, @
|
162
|
-
if env["QUERY_STRING"] =~ /pp=
|
176
|
+
MiniProfiler.create_current(env, @config)
|
177
|
+
if env["QUERY_STRING"] =~ /pp=no-backtrace/
|
163
178
|
current['skip-backtrace'] = true
|
164
179
|
end
|
165
|
-
|
166
|
-
start = Time.now
|
167
|
-
|
180
|
+
|
168
181
|
done_sampling = false
|
169
182
|
quit_sampler = false
|
170
183
|
backtraces = nil
|
@@ -172,10 +185,16 @@ module Rack
|
|
172
185
|
backtraces = []
|
173
186
|
t = Thread.current
|
174
187
|
Thread.new {
|
188
|
+
require 'stacktrace'
|
189
|
+
if !t.respond_to? :stacktrace
|
190
|
+
quit_sampler = true
|
191
|
+
return
|
192
|
+
end
|
175
193
|
i = 10000 # for sanity never grab more than 10k samples
|
176
|
-
|
194
|
+
while i > 0
|
195
|
+
break if done_sampling
|
177
196
|
i -= 1
|
178
|
-
backtraces << t.
|
197
|
+
backtraces << t.stacktrace
|
179
198
|
sleep 0.001
|
180
199
|
end
|
181
200
|
quit_sampler = true
|
@@ -183,8 +202,9 @@ module Rack
|
|
183
202
|
end
|
184
203
|
|
185
204
|
status, headers, body = nil
|
205
|
+
start = Time.now
|
186
206
|
begin
|
187
|
-
status,headers,
|
207
|
+
status,headers,body = @app.call(env)
|
188
208
|
ensure
|
189
209
|
if backtraces
|
190
210
|
done_sampling = true
|
@@ -192,9 +212,34 @@ module Rack
|
|
192
212
|
end
|
193
213
|
end
|
194
214
|
|
215
|
+
skip_it = current['discard']
|
216
|
+
if @config.post_authorize_cb && !@config.post_authorize_cb.call(env)
|
217
|
+
self.class.remove_profiling_cookie(headers)
|
218
|
+
skip_it = true
|
219
|
+
end
|
220
|
+
|
221
|
+
return [status,headers,body] if skip_it
|
222
|
+
|
223
|
+
# we must do this here, otherwise current['discard'] is not being properly treated
|
224
|
+
if env["QUERY_STRING"] =~ /pp=env/
|
225
|
+
body.close if body.respond_to? :close
|
226
|
+
return dump_env env
|
227
|
+
end
|
228
|
+
|
229
|
+
if env["QUERY_STRING"] =~ /pp=help/
|
230
|
+
body.close if body.respond_to? :close
|
231
|
+
return help
|
232
|
+
end
|
233
|
+
|
195
234
|
page_struct = current['page_struct']
|
196
235
|
page_struct['Root'].record_time((Time.now - start) * 1000)
|
197
236
|
|
237
|
+
if backtraces
|
238
|
+
body.close if body.respond_to? :close
|
239
|
+
return analyze(backtraces, page_struct)
|
240
|
+
end
|
241
|
+
|
242
|
+
|
198
243
|
# no matter what it is, it should be unviewed, otherwise we will miss POST
|
199
244
|
@storage.set_unviewed(user(env), page_struct['Id'])
|
200
245
|
@storage.save(page_struct)
|
@@ -226,6 +271,41 @@ module Rack
|
|
226
271
|
current = nil
|
227
272
|
end
|
228
273
|
|
274
|
+
def dump_env(env)
|
275
|
+
headers = {'Content-Type' => 'text/plain'}
|
276
|
+
body = ""
|
277
|
+
env.each do |k,v|
|
278
|
+
body << "#{k}: #{v}\n"
|
279
|
+
end
|
280
|
+
[200, headers, [body]]
|
281
|
+
end
|
282
|
+
|
283
|
+
def help
|
284
|
+
headers = {'Content-Type' => 'text/plain'}
|
285
|
+
body = "Append the following to your query string:
|
286
|
+
|
287
|
+
pp=help : display this screen
|
288
|
+
pp=env : display the rack environment
|
289
|
+
pp=skip : skip mini profiler for this request
|
290
|
+
pp=no-backtrace : don't collect stack traces from all the SQL calls
|
291
|
+
pp=sample : sample stack traces and return a report isolating heavy usage (requires the stacktrace gem)
|
292
|
+
"
|
293
|
+
#headers['Content-Length'] = body.length
|
294
|
+
[200, headers, [body]]
|
295
|
+
end
|
296
|
+
|
297
|
+
def analyze(traces, page_struct)
|
298
|
+
headers = {'Content-Type' => 'text/plain'}
|
299
|
+
body = "Collected: #{traces.count} stack traces. Duration(ms): #{page_struct.duration_ms}"
|
300
|
+
traces.each do |trace|
|
301
|
+
body << "\n\n"
|
302
|
+
trace.each do |frame|
|
303
|
+
body << "#{frame.klass} #{frame.method}\n"
|
304
|
+
end
|
305
|
+
end
|
306
|
+
[200, headers, [body]]
|
307
|
+
end
|
308
|
+
|
229
309
|
def ids_json(env)
|
230
310
|
ids = [current['page_struct']["Id"]] + (@storage.get_unviewed_ids(user(env)) || [])
|
231
311
|
::JSON.generate(ids.uniq)
|
@@ -239,9 +319,9 @@ module Rack
|
|
239
319
|
# * you do not want script to be automatically appended for the current page. You can also call cancel_auto_inject
|
240
320
|
def get_profile_script(env)
|
241
321
|
ids = ids_json(env)
|
242
|
-
path = @
|
322
|
+
path = @config.base_url_path
|
243
323
|
version = MiniProfiler::VERSION
|
244
|
-
position = @
|
324
|
+
position = @config.position
|
245
325
|
showTrivial = false
|
246
326
|
showChildren = false
|
247
327
|
maxTracesToShow = 10
|
@@ -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.
|
17
|
-
if Rack::MiniProfiler.
|
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
|
18
18
|
stack_trace << ln << "\n"
|
19
19
|
end
|
20
20
|
end
|
@@ -23,7 +23,7 @@ module Rack
|
|
23
23
|
super("ExecuteType" => 3, # TODO
|
24
24
|
"FormattedCommandString" => query,
|
25
25
|
"StackTraceSnippet" => stack_trace,
|
26
|
-
"StartMilliseconds" => (Time.now.to_f * 1000).to_i - page['Started'],
|
26
|
+
"StartMilliseconds" => ((Time.now.to_f * 1000).to_i - page['Started']) - duration_ms,
|
27
27
|
"DurationMilliseconds" => duration_ms,
|
28
28
|
"FirstFetchDurationMilliseconds" => 0,
|
29
29
|
"Parameters" => nil,
|
@@ -2,22 +2,31 @@ module MiniProfilerRails
|
|
2
2
|
class Railtie < ::Rails::Railtie
|
3
3
|
|
4
4
|
initializer "rack_mini_profiler.configure_rails_initialization" do |app|
|
5
|
+
c = Rack::MiniProfiler.config
|
5
6
|
|
6
|
-
# By default, only show the MiniProfiler in development mode
|
7
|
-
|
8
|
-
Rails.env.development?
|
7
|
+
# By default, only show the MiniProfiler in development mode, in production allow profiling if post_authorize_cb is set
|
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
11
|
}
|
10
12
|
|
13
|
+
if Rails.env.development?
|
14
|
+
c.skip_paths ||= []
|
15
|
+
c.skip_paths << "/assets/"
|
16
|
+
c.skip_schema_queries = true
|
17
|
+
end
|
18
|
+
|
11
19
|
# The file store is just so much less flaky
|
12
20
|
tmp = Rails.root.to_s + "/tmp/miniprofiler"
|
13
21
|
Dir::mkdir(tmp) unless File.exists?(tmp)
|
14
|
-
|
15
|
-
|
16
|
-
|
22
|
+
|
23
|
+
c.storage_options = {:path => tmp}
|
24
|
+
c.storage = Rack::MiniProfiler::FileStore
|
17
25
|
|
18
26
|
# Quiet the SQL stack traces
|
19
|
-
|
20
|
-
|
27
|
+
c.backtrace_remove = Rails.root.to_s + "/"
|
28
|
+
c.backtrace_filter = /^\/?(app|config|lib|test)/
|
29
|
+
c.skip_schema_queries = Rails.env != 'production'
|
21
30
|
|
22
31
|
# Install the Middleware
|
23
32
|
app.middleware.insert_before 'Rack::Lock', 'Rack::MiniProfiler'
|
data/lib/patches/sql_patches.rb
CHANGED
@@ -43,7 +43,7 @@ module Rack
|
|
43
43
|
return rval unless instance
|
44
44
|
|
45
45
|
# Don't log schema queries if the option is set
|
46
|
-
return rval if instance.
|
46
|
+
return rval if instance.config.skip_schema_queries and name =~ /SCHEMA/
|
47
47
|
|
48
48
|
elapsed_time = ((Time.now - t0).to_f * 1000).round(1)
|
49
49
|
instance.record_sql(sql, elapsed_time)
|
@@ -59,14 +59,7 @@ module Rack
|
|
59
59
|
end
|
60
60
|
|
61
61
|
if defined?(::Rails)
|
62
|
-
|
63
|
-
# in theory this is the right thing to do for rails 3 ... but it seems to work anyway
|
64
|
-
#Rails.configuration.after_initialize do
|
65
|
-
insert_instrumentation
|
66
|
-
#end
|
67
|
-
else
|
68
|
-
insert_instrumentation
|
69
|
-
end
|
62
|
+
insert_instrumentation
|
70
63
|
end
|
71
64
|
end
|
72
65
|
|
data/rack-mini-profiler.gemspec
CHANGED
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.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- lib/mini_profiler/request_timer_struct.rb
|
92
92
|
- lib/mini_profiler/timer_struct.rb
|
93
93
|
- lib/mini_profiler/page_timer_struct.rb
|
94
|
+
- lib/mini_profiler/config.rb
|
94
95
|
- lib/mini_profiler/body_add_proxy.rb
|
95
96
|
- lib/mini_profiler/client_timer_struct.rb
|
96
97
|
- lib/mini_profiler/profiler.rb
|
@@ -129,7 +130,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
129
130
|
version: '0'
|
130
131
|
segments:
|
131
132
|
- 0
|
132
|
-
hash:
|
133
|
+
hash: 876564877
|
133
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
135
|
none: false
|
135
136
|
requirements:
|
@@ -138,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
139
|
version: '0'
|
139
140
|
segments:
|
140
141
|
- 0
|
141
|
-
hash:
|
142
|
+
hash: 876564877
|
142
143
|
requirements: []
|
143
144
|
rubyforge_project:
|
144
145
|
rubygems_version: 1.8.24
|