rack-webprofiler 0.1.0.pre.beta2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +5 -13
  2. data/CHANGELOG.md +36 -12
  3. data/README.md +16 -12
  4. data/docs/DSL.md +152 -0
  5. data/docs/GettingStarted.md +51 -0
  6. data/docs/README.md +6 -0
  7. data/lib/rack/templates/assets/css/profiler.css +1 -1
  8. data/lib/rack/templates/assets/css/rwpt.css +1 -1
  9. data/lib/rack/templates/assets/sass/_variables.scss +21 -2
  10. data/lib/rack/templates/assets/sass/profiler.scss +73 -61
  11. data/lib/rack/templates/assets/sass/rwpt.scss +2 -2
  12. data/lib/rack/templates/panel/show.erb +4 -4
  13. data/lib/rack/templates/profiler.erb +4 -0
  14. data/lib/rack/web_profiler/collector.rb +197 -125
  15. data/lib/rack/web_profiler/collectors/rack_collector.rb +74 -0
  16. data/lib/rack/web_profiler/{collector/rack → collectors}/request_collector.rb +43 -60
  17. data/lib/rack/web_profiler/{collector → collectors}/ruby_collector.rb +4 -3
  18. data/lib/rack/web_profiler/{collector → collectors}/time_collector.rb +12 -6
  19. data/lib/rack/web_profiler/collectors.rb +21 -27
  20. data/lib/rack/web_profiler/config.rb +4 -9
  21. data/lib/rack/web_profiler/controller.rb +131 -126
  22. data/lib/rack/web_profiler/engine.rb +10 -14
  23. data/lib/rack/web_profiler/model.rb +74 -23
  24. data/lib/rack/web_profiler/request.rb +22 -7
  25. data/lib/rack/web_profiler/response.rb +27 -0
  26. data/lib/rack/web_profiler/rouge/html_formatter.rb +25 -0
  27. data/lib/rack/web_profiler/router.rb +11 -6
  28. data/lib/rack/web_profiler/version.rb +1 -1
  29. data/lib/rack/web_profiler/view.rb +255 -139
  30. data/lib/rack/web_profiler.rb +47 -4
  31. data/rack-webprofiler.gemspec +1 -3
  32. metadata +32 -32
  33. data/lib/rack/web_profiler/collector/debug_collector.rb +0 -31
  34. data/lib/rack/web_profiler/collector/erb_collector.rb +0 -0
  35. data/lib/rack/web_profiler/collector/performance_collector.rb +0 -1
  36. data/lib/rack/web_profiler/collector/rack/rack_collector.rb +0 -23
  37. data/lib/rack/web_profiler/collector/view.rb +0 -44
  38. data/lib/rack/web_profiler/model/collection_record.rb +0 -46
@@ -0,0 +1,25 @@
1
+ module Rack
2
+ #
3
+ class WebProfiler::Rouge::HTMLFormatter < ::Rouge::Formatter
4
+
5
+ # Initialize the Formatter.
6
+ #
7
+ # @param request [Hash]
8
+ def initialize(opts = {})
9
+ @formatter = opts[:inline_theme] \
10
+ ? ::Rouge::Formatters::HTMLInline.new(opts[:inline_theme])
11
+ : ::Rouge::Formatters::HTML.new
12
+
13
+ if opts[:line_numbers]
14
+ @formatter = ::Rouge::Formatters::HTMLTable.new(@formatter, opts)
15
+ else
16
+ @formatter = ::Rouge::Formatters::HTMLPygments.new(@formatter)
17
+ end
18
+ end
19
+
20
+ # @yield the html output.
21
+ def stream(tokens, &b)
22
+ @formatter.stream(tokens, &b)
23
+ end
24
+ end
25
+ end
@@ -28,6 +28,7 @@ module Rack
28
28
  # Route the request.
29
29
  #
30
30
  # @param request [Rack::WebProfiler::Request]
31
+ # @param path [String]
31
32
  #
32
33
  # @return [Rack::Reponse, false]
33
34
  def route(request, path)
@@ -58,8 +59,6 @@ module Rack
58
59
  request = @request.dup
59
60
  request.env[PATH_INFO] = "/#{path}"
60
61
 
61
- path_info = Utils.unescape(request.env[PATH_INFO])
62
- clean_path_info = Utils.clean_path_info(path_info)
63
62
 
64
63
  status, headers, body = rf.call(request.env)
65
64
  Rack::Response.new(body, status, headers)
@@ -71,7 +70,7 @@ module Rack
71
70
  #
72
71
  # @return [String]
73
72
  def url_for_asset(path)
74
- "#{@request.script_name}#{BASE_PATH}/assets/#{path}"
73
+ "#{get_base_path}/assets/#{path}"
75
74
  end
76
75
 
77
76
  # Get url for toobar.
@@ -80,7 +79,7 @@ module Rack
80
79
  #
81
80
  # @return [String]
82
81
  def url_for_toolbar(token)
83
- "#{@request.script_name}#{BASE_PATH}/toolbar/#{token}"
82
+ "#{get_base_path}/toolbar/#{token}"
84
83
  end
85
84
 
86
85
  # Get url for the webprofiler.
@@ -92,14 +91,20 @@ module Rack
92
91
  def url_for_profiler(token = nil, panel = nil)
93
92
  query = ""
94
93
  query = "?panel=#{panel}" unless panel.nil?
95
- "#{@request.script_name}#{BASE_PATH}/#{token}#{query}"
94
+ "#{get_base_path}/#{token}#{query}"
96
95
  end
97
96
 
98
97
  # Get url to clean webprofiler.
99
98
  #
100
99
  # @return [String]
101
100
  def url_for_clean_profiler
102
- "#{@request.script_name}#{BASE_PATH}/clean"
101
+ "#{get_base_path}/clean"
102
+ end
103
+
104
+ private
105
+
106
+ def get_base_path
107
+ "#{@request.env["ORIGINAL_SCRIPT_NAME"]}#{BASE_PATH}"
103
108
  end
104
109
  end
105
110
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class WebProfiler
3
- VERSION = "0.1.0-beta2".freeze
3
+ VERSION = "0.1.0".freeze
4
4
  end
5
5
  end
@@ -5,29 +5,53 @@ module Rack
5
5
  class WebProfiler
6
6
  # View
7
7
  class View
8
+ # Initialize a new view.
9
+ #
10
+ # @param template [String] template file path or content
11
+ # @option layout [String, nil] layout file path or content
12
+ # @option context [Rack::WebProfiler::View::Context, nil]
8
13
  def initialize(template, layout: nil, context: nil)
9
14
  @template = template
10
15
  @layout = layout
11
16
  @context = context
17
+
18
+ @erb_options = {
19
+ safe_level: nil,
20
+ trim_mode: "<>-",
21
+ eoutvar: "@_erbout",
22
+ }
12
23
  end
13
24
 
25
+ # Get the result of view rendering.
26
+ #
27
+ # @param variables [Hash, Binding] view variables
28
+ #
29
+ # @return [String]
14
30
  def result(variables = {})
15
31
  unless @template.nil?
16
32
  templates = [read_template(@template)]
17
33
  templates << read_template(@layout) unless @layout.nil?
18
34
 
19
- content = templates.inject(nil) do |prev, temp|
35
+ templates.inject(nil) do |prev, temp|
20
36
  render(temp, variables) { prev }
21
37
  end
22
38
  end
23
39
  end
24
40
 
41
+ # Get the context.
42
+ #
43
+ # @return [Rack::WebProfiler::View::Context]
25
44
  def context
26
45
  @context ||= Context.new
27
46
  end
28
47
 
29
- private
48
+ protected
30
49
 
50
+ # Read a template. Returns file content if template is a file path.
51
+ #
52
+ # @param template [String] template file path or content
53
+ #
54
+ # @return [String]
31
55
  def read_template(template)
32
56
  unless template.empty?
33
57
  path = ::File.expand_path("../../templates/#{template}", __FILE__)
@@ -36,36 +60,35 @@ module Rack
36
60
  template
37
61
  end
38
62
 
39
- def options
40
- @options ||= {
41
- :safe_level => nil,
42
- :trim_mode => '%-',
43
- :eoutvar => '@_erbout',
44
- }
45
- end
46
-
63
+ # Render view.
64
+ #
65
+ # @param str [String] view content
66
+ # @param variables [Hash, Binding] view variables
67
+ #
68
+ # @return [String]
69
+ #
70
+ # @todo better error when there is an ERB error.
47
71
  def render(str, variables = {})
48
- opts = options
49
-
50
72
  format_variables(variables).each do |name, value|
51
73
  context.instance_variable_set("@#{name}", value)
52
74
  end
53
75
 
76
+ erb = ::ERB.new(str, *@erb_options.values_at(:safe_level, :trim_mode, :eoutvar))
77
+
54
78
  context.instance_eval do
55
- erb = ::ERB.new(str, *opts.values_at(:safe_level, :trim_mode, :eoutvar))
56
- erb.result(binding).sub(/\A\n/, '')
79
+ erb.result(binding).sub(/\A\n/, "")
57
80
  end
58
- # @todo better error when there is an ERB error.
59
81
  end
60
82
 
83
+ # Format variables to inject them into view context.
84
+ #
85
+ # @param v [Hash, Binding] variables
86
+ #
87
+ # @return [Hash]
61
88
  def format_variables(v)
62
89
  case v
63
90
  when Binding
64
- h = {}
65
- v.eval("instance_variables").each do |k|
66
- h[k.to_s.sub(/^@/, '')] = v.eval("instance_variable_get(:#{k})")
67
- end
68
- h
91
+ binding_to_hash(v)
69
92
  when Hash
70
93
  v
71
94
  else
@@ -73,163 +96,256 @@ module Rack
73
96
  end
74
97
  end
75
98
 
76
- # CommonHelpers.
77
- module CommonHelpers
78
- def content_for(key, content = nil, &block)
79
- block ||= proc { |*| content }
80
- content_blocks[key.to_sym] << capture_later(&block)
81
- end
82
-
83
- def content_for?(key)
84
- content_blocks[key.to_sym].any?
99
+ # Returns a [Hash] from a [Binding].
100
+ #
101
+ # @param v [Binding]
102
+ #
103
+ # @return [Hash]
104
+ def binding_to_hash(v)
105
+ h = {}
106
+ v.eval("instance_variables").each do |k|
107
+ h[k.to_s.sub(/^@/, "")] = v.eval("instance_variable_get(:#{k})")
85
108
  end
109
+ h
110
+ end
86
111
 
87
- def yield_content(key, default = nil)
88
- return default if content_blocks[key.to_sym].empty?
89
- content_blocks[key.to_sym].map { |b| capture(&b) }.join
90
- end
91
-
92
- #
93
- def partial(path, variables: nil)
94
- return "" if path.nil?
95
-
96
- variables ||= binding if variables.nil?
97
-
98
- capture do
99
- WebProfiler::View.new(path, context: self).result(variables)
112
+ # Helpers.
113
+ module Helpers
114
+ # Common helpers.
115
+ module Common
116
+ def content_for(key, content = nil, &block)
117
+ block ||= proc { |*| content }
118
+ content_blocks[key.to_sym] << capture_later(&block)
100
119
  end
101
- end
102
120
 
103
- #
104
- def h(obj)
105
- case obj
106
- when String
107
- ::ERB::Util.html_escape(obj)
108
- else
109
- ::ERB::Util.html_escape(obj.inspect)
121
+ def content_for?(key)
122
+ content_blocks[key.to_sym].any?
110
123
  end
111
- end
112
124
 
113
- #
114
- def highlight(code: nil, language: nil)
115
- language = language.to_sym if language.is_a? String
116
-
117
- case language
118
- when :ruby
119
- lexer = Rouge::Lexers::Ruby.new
120
- when :json
121
- lexer = Rouge::Lexers::Jsonnet.new
122
- when :xml
123
- lexer = Rouge::Lexers::XML.new
124
- else
125
- lexer = Rouge::Lexers::PlainText.new
125
+ def yield_content(key, default = nil)
126
+ return default if content_blocks[key.to_sym].empty?
127
+ content_blocks[key.to_sym].map { |b| capture(&b) }.join
126
128
  end
127
129
 
128
- code = capture(&Proc.new) if block_given?
130
+ # Render a partial view.
131
+ #
132
+ # @param path [String] path to partial
133
+ # @option variables [Hash, nil] variables for partial
134
+ #
135
+ # @return [String]
136
+ def partial(path, variables: nil)
137
+ return "" if path.nil?
129
138
 
130
- formatter = Rouge::Formatters::HTML.new
131
- formatter = Rouge::Formatters::HTMLPygments.new(formatter, css_class='highlight')
139
+ variables ||= binding if variables.nil?
132
140
 
133
- "<div class=\"highlight\">#{formatter.format(lexer.lex(code))}</div>"
134
- end
141
+ capture do
142
+ WebProfiler::View.new(path, context: self).result(variables)
143
+ end
144
+ end
135
145
 
136
- def capture(&block)
137
- @capture = nil
138
- @_erbout, _buf_was = '', @_erbout
139
- result = yield
140
- @_erbout = _buf_was
141
- result.strip.empty? && @capture ? @capture : result
142
- end
146
+ # Escape html.
147
+ #
148
+ # @param obj
149
+ #
150
+ # @return [String]
151
+ def h(obj)
152
+ case obj
153
+ when String
154
+ ::ERB::Util.html_escape(obj)
155
+ else
156
+ ::ERB::Util.html_escape(obj.inspect)
157
+ end
158
+ end
143
159
 
144
- private
160
+ # Highlight text.
161
+ #
162
+ # @option code [String]
163
+ # @option mimetype [String, nil]
164
+ # @option language [String, nil]
165
+ # @option formatter_opts [Hash]
166
+ #
167
+ # @yield code.
168
+ #
169
+ # @return [String]
170
+ def highlight(code: "", mimetype: nil, language: nil, formatter_opts: {})
171
+ language = language.to_s if language.is_a? Symbol
172
+
173
+ lexer = ::Rouge::Lexer.guess(mimetype: mimetype) if mimetype.is_a? String
174
+ lexer = ::Rouge::Lexer.find_fancy(language) if language.is_a? String
175
+ lexer ||= ::Rouge::Lexers::PlainText.new
176
+
177
+ code = capture(&Proc.new) if block_given?
178
+ code ||= ""
179
+
180
+ formatter = WebProfiler::Rouge::HTMLFormatter.new(formatter_opts)
181
+
182
+ "<div class=\"highlight\">#{formatter.format(lexer.lex(code))}</div>"
183
+ end
145
184
 
146
- def capture_later(&block)
147
- proc { |*| @capture = capture(&block) }
148
- end
185
+ #
186
+ #
187
+ # @yield
188
+ def capture(&block)
189
+ @capture = nil
190
+ buf_was = @_erbout
191
+ @_erbout = ""
149
192
 
150
- def content_blocks
151
- @content_blocks ||= Hash.new {|h,k| h[k] = [] }
152
- end
153
- end
193
+ result = yield
154
194
 
155
- # CollectorHelpers.
156
- module CollectorHelpers
195
+ @_erbout = buf_was
196
+ result.strip.empty? && @capture ? @capture : result
197
+ end
157
198
 
158
- #
159
- def collector_status(collector, collection)
160
- collector_data_storage(collector, collection, :status)
161
- end
199
+ #
200
+ #
201
+ # @yield
202
+ def capture_later(&block)
203
+ proc { |*| @capture = capture(&block) }
204
+ end
205
+
206
+ private
162
207
 
163
- #
164
- def collector_datas(collector, collection)
165
- collector_data_storage(collector, collection, :datas)
208
+ #
209
+ #
210
+ # @return [Hash]
211
+ def content_blocks
212
+ @content_blocks ||= Hash.new { |h, k| h[k] = [] }
213
+ end
166
214
  end
167
215
 
168
- def collector_tab(collector, collection)
169
- return nil unless is_collection_contains_datas_for_collector?(collection, collector)
216
+ # Collector helpers.
217
+ module Collector
218
+ # Get collector status from a collection.
219
+ #
220
+ # @param collector [Rack::WebProfiler::Collector::Definition]
221
+ # @param collection [Rack::WebProfiler::Model::CollectionRecord]
222
+ #
223
+ # @return [Symbol, nil]
224
+ def collector_status(collector, collection)
225
+ collector_data_storage(collector, collection, :status)
226
+ end
170
227
 
171
- c = collector_view_context(collector, collection)
172
- c.tab_content
173
- end
228
+ #
229
+ #
230
+ # @param collector [Rack::WebProfiler::Collector::Definition]
231
+ # @param collection [Rack::WebProfiler::Model::CollectionRecord]
232
+ def collector_datas(collector, collection)
233
+ collector_data_storage(collector, collection, :datas)
234
+ end
174
235
 
175
- def collector_panel(collector, collection)
176
- return nil unless is_collection_contains_datas_for_collector?(collection, collector)
236
+ #
237
+ # @param collector [Rack::WebProfiler::Collector::Definition]
238
+ # @param collection [Rack::WebProfiler::Model::CollectionRecord]
239
+ def collector_tab(collector, collection)
240
+ return nil unless collection_contains_datas_for_collector?(collection, collector)
177
241
 
178
- c = collector_view_context(collector, collection)
179
- c.panel_content
180
- end
242
+ c = collector_view_context(collector, collection)
243
+ c.tab_content
244
+ end
181
245
 
182
- def collector_has_tab?(collector, collection)
183
- collector_data_storage(collector, collection, :show_tab)
184
- end
246
+ #
247
+ # @param collector [Rack::WebProfiler::Collector::Definition]
248
+ # @param collection [Rack::WebProfiler::Model::CollectionRecord]
249
+ def collector_panel(collector, collection)
250
+ return nil unless collection_contains_datas_for_collector?(collection, collector)
185
251
 
186
- def collector_has_panel?(collector, collection)
187
- collector_data_storage(collector, collection, :show_panel)
188
- end
252
+ c = collector_view_context(collector, collection)
253
+ c.panel_content
254
+ end
189
255
 
190
- private
256
+ #
257
+ # @param collector [Rack::WebProfiler::Collector::Definition]
258
+ # @param collection [Rack::WebProfiler::Model::CollectionRecord]
259
+ def collector_has_tab?(collector, collection)
260
+ collector_data_storage(collector, collection, :show_tab)
261
+ # !collector_tab(collector, collection).nil?
262
+ end
191
263
 
192
- def collector_view_context(collector, collection)
193
- collectors_view_context[collector.name] ||= begin
194
- v = WebProfiler::Collector::View.new(collector.template)
195
- v.result(collector: collector, collection: collection)
196
- v.context
264
+ #
265
+ # @param collector [Rack::WebProfiler::Collector::Definition]
266
+ # @param collection [Rack::WebProfiler::Model::CollectionRecord]
267
+ def collector_has_panel?(collector, collection)
268
+ collector_data_storage(collector, collection, :show_panel)
269
+ # !collector_panel(collector, collection).nil?
197
270
  end
198
- end
199
271
 
200
- def collector_data_storage(collector, collection, key = nil)
201
- return nil unless is_collection_contains_datas_for_collector?(collection, collector)
272
+ private
273
+
274
+ # Get a collector view Context.
275
+ #
276
+ # @param collector [Rack::WebProfiler::Collector::Definition]
277
+ # @param collection [Rack::WebProfiler::Model::CollectionRecord]
278
+ #
279
+ # @return [Rack::WebProfiler::View::Context]
280
+ def collector_view_context(collector, collection)
281
+ collectors_view_context[collector.identifier] ||= begin
282
+ v = WebProfiler::Collector::View.new(collector.template)
283
+ v.result(collector: collector, collection: collection)
284
+ v.context
285
+ end
286
+ end
202
287
 
203
- storage = collection.datas[collector.name.to_sym]
204
- storage[key] if !key.nil? && storage.has_key?(key)
205
- end
288
+ #
289
+ #
290
+ # @param collector [Rack::WebProfiler::Collector::Definition]
291
+ # @param collection [Rack::WebProfiler::Model::CollectionRecord]
292
+ # @param key [Symbol, String]
293
+ #
294
+ # @return
295
+ def collector_data_storage(collector, collection, key = nil)
296
+ return nil unless collection_contains_datas_for_collector?(collection, collector)
297
+
298
+ storage = collection.datas[collector.identifier.to_sym]
299
+ storage[key] if !key.nil? && storage.key?(key)
300
+ end
206
301
 
207
- def is_valid_collector?(collector)
208
- !collector.nil? \
209
- && collector.kind_of?(WebProfiler::Collector::Definition)
210
- end
302
+ # Check if collector is valid.
303
+ #
304
+ # @param collector [Rack::WebProfiler::Collector::Definition]
305
+ #
306
+ # @return [Boolean]
307
+ def valid_collector?(collector)
308
+ !collector.nil? \
309
+ && collector.is_a?(WebProfiler::Collector::Definition)
310
+ end
211
311
 
212
- def is_valid_collection?(collection)
213
- !collection.nil? \
214
- && collection.kind_of?(WebProfiler::Model::CollectionRecord)
215
- end
312
+ # Check if collection is valid.
313
+ #
314
+ # @param collection [Rack::WebProfiler::Model::CollectionRecord]
315
+ #
316
+ # @return [Boolean]
317
+ def valid_collection?(collection)
318
+ !collection.nil? \
319
+ && collection.is_a?(WebProfiler::Model::CollectionRecord)
320
+ end
216
321
 
217
- def is_collection_contains_datas_for_collector?(collection, collector)
218
- is_valid_collector?(collector) \
219
- && is_valid_collection?(collection) \
220
- && collection.datas.has_key?(collector.name.to_sym)
221
- end
322
+ # @param collector [Rack::WebProfiler::Collector::Definition]
323
+ # @param collection [Rack::WebProfiler::Model::CollectionRecord]
324
+ #
325
+ # @return [Boolean]
326
+ def collection_contains_datas_for_collector?(collection, collector)
327
+ valid_collector?(collector) \
328
+ && valid_collection?(collection) \
329
+ && collection.datas.key?(collector.identifier.to_sym)
330
+ end
222
331
 
223
- private
332
+ private
224
333
 
225
- def collectors_view_context
226
- @collectors_view_context ||= {}
334
+ # Get the collectors view context.
335
+ #
336
+ # @return [Hash]
337
+ def collectors_view_context
338
+ @collectors_view_context ||= {}
339
+ end
227
340
  end
228
341
  end
229
342
 
343
+ # View Context.
230
344
  class Context
231
- include CommonHelpers
232
- include CollectorHelpers
345
+
346
+ # Include helpers into the Context.
347
+ include Helpers::Common
348
+ include Helpers::Collector
233
349
  end
234
350
  end
235
351
  end
@@ -10,29 +10,69 @@ module Rack
10
10
  autoload :Controller, "rack/web_profiler/controller"
11
11
  autoload :Engine, "rack/web_profiler/engine"
12
12
  autoload :Model, "rack/web_profiler/model"
13
+ autoload :Response, "rack/web_profiler/response"
13
14
  autoload :Request, "rack/web_profiler/request"
14
15
  autoload :Router, "rack/web_profiler/router"
15
16
  autoload :View, "rack/web_profiler/view"
16
17
 
18
+ # Classes about Rouge gem customization.
19
+ module Rouge
20
+ autoload :HTMLFormatter, "rack/web_profiler/rouge/html_formatter"
21
+ end
22
+
23
+ # Env key constants.
24
+ ENV_RUNTIME_START = "rack_webprofiler.runtime_start".freeze
25
+ ENV_RUNTIME = "rack_webprofiler.runtime".freeze
26
+ ENV_EXCEPTION = "rack_webprofiler.exception".freeze
27
+
17
28
  class << self
29
+ # Configure the WebProfiler.
30
+ #
31
+ # @yield the Config object.
32
+ #
33
+ # @return [Rack::WebProfiler::Config]
18
34
  def config
19
35
  @config ||= Config.new
20
36
  @config.build!(&Proc.new) if block_given?
21
37
  @config
22
38
  end
23
39
 
40
+ # Register one or many collectors.
41
+ #
42
+ # @param collector_class [Array, Class]
24
43
  def register_collector(collector_class)
25
44
  config.collectors.add_collector collector_class
26
45
  end
46
+ alias register_collectors register_collector
27
47
 
48
+ # Unregister one or many collectors.
49
+ #
50
+ # @param collector_class [Array, Class]
28
51
  def unregister_collector(collector_class)
29
52
  config.collectors.remove_collector collector_class
30
53
  end
54
+ alias unregister_collectors unregister_collector
55
+
56
+ def data(k = nil, v = :undefined)
57
+ @data ||= {}
58
+
59
+ return @data if k === nil
60
+
61
+ @data[k] = v unless v === :undefined
62
+ @data[k] if @data.key?(k)
63
+ end
64
+
65
+ def reset_data!
66
+ @data = {}
67
+ end
31
68
  end
32
69
 
70
+ attr_reader :data
71
+
33
72
  # Initialize
34
73
  #
35
74
  # @param app [Proc]
75
+ # @option tmp_dir [String]
36
76
  def initialize(app, tmp_dir: nil)
37
77
  @app = app
38
78
 
@@ -46,9 +86,11 @@ module Rack
46
86
  #
47
87
  # @return [Array]
48
88
  def call(env)
89
+ WebProfiler.reset_data!
90
+
49
91
  begin
50
92
  request = WebProfiler::Request.new(env)
51
- request.start_runtime!
93
+ env[ENV_RUNTIME_START] = Time.now.to_f
52
94
 
53
95
  response = WebProfiler::Router.response_for(request)
54
96
  return response.finish if response.is_a? Rack::Response
@@ -74,10 +116,11 @@ module Rack
74
116
  #
75
117
  # @return [Rack::Response]
76
118
  def process(request, body, status, headers, exception = nil)
77
- request.save_runtime!
119
+ request.env[ENV_RUNTIME] = Time.now.to_f - request.env[ENV_RUNTIME_START]
120
+ request.env[ENV_EXCEPTION] = nil
78
121
 
79
- unless exception.nil?
80
- request.save_exception(exception)
122
+ if !exception.nil?
123
+ request.env[ENV_EXCEPTION] = exception
81
124
  WebProfiler::Engine.process_exception(request).finish
82
125
  else
83
126
  WebProfiler::Engine.process(request, body, status, headers).finish