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.
- checksums.yaml +5 -13
- data/CHANGELOG.md +36 -12
- data/README.md +16 -12
- data/docs/DSL.md +152 -0
- data/docs/GettingStarted.md +51 -0
- data/docs/README.md +6 -0
- data/lib/rack/templates/assets/css/profiler.css +1 -1
- data/lib/rack/templates/assets/css/rwpt.css +1 -1
- data/lib/rack/templates/assets/sass/_variables.scss +21 -2
- data/lib/rack/templates/assets/sass/profiler.scss +73 -61
- data/lib/rack/templates/assets/sass/rwpt.scss +2 -2
- data/lib/rack/templates/panel/show.erb +4 -4
- data/lib/rack/templates/profiler.erb +4 -0
- data/lib/rack/web_profiler/collector.rb +197 -125
- data/lib/rack/web_profiler/collectors/rack_collector.rb +74 -0
- data/lib/rack/web_profiler/{collector/rack → collectors}/request_collector.rb +43 -60
- data/lib/rack/web_profiler/{collector → collectors}/ruby_collector.rb +4 -3
- data/lib/rack/web_profiler/{collector → collectors}/time_collector.rb +12 -6
- data/lib/rack/web_profiler/collectors.rb +21 -27
- data/lib/rack/web_profiler/config.rb +4 -9
- data/lib/rack/web_profiler/controller.rb +131 -126
- data/lib/rack/web_profiler/engine.rb +10 -14
- data/lib/rack/web_profiler/model.rb +74 -23
- data/lib/rack/web_profiler/request.rb +22 -7
- data/lib/rack/web_profiler/response.rb +27 -0
- data/lib/rack/web_profiler/rouge/html_formatter.rb +25 -0
- data/lib/rack/web_profiler/router.rb +11 -6
- data/lib/rack/web_profiler/version.rb +1 -1
- data/lib/rack/web_profiler/view.rb +255 -139
- data/lib/rack/web_profiler.rb +47 -4
- data/rack-webprofiler.gemspec +1 -3
- metadata +32 -32
- data/lib/rack/web_profiler/collector/debug_collector.rb +0 -31
- data/lib/rack/web_profiler/collector/erb_collector.rb +0 -0
- data/lib/rack/web_profiler/collector/performance_collector.rb +0 -1
- data/lib/rack/web_profiler/collector/rack/rack_collector.rb +0 -23
- data/lib/rack/web_profiler/collector/view.rb +0 -44
- 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
|
-
"#{
|
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
|
-
"#{
|
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
|
-
"#{
|
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
|
-
"#{
|
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
|
@@ -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
|
-
|
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
|
-
|
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
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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
|
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
|
-
|
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
|
-
#
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
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
|
-
|
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
|
-
|
115
|
-
|
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
|
-
|
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
|
-
|
131
|
-
formatter = Rouge::Formatters::HTMLPygments.new(formatter, css_class='highlight')
|
139
|
+
variables ||= binding if variables.nil?
|
132
140
|
|
133
|
-
|
134
|
-
|
141
|
+
capture do
|
142
|
+
WebProfiler::View.new(path, context: self).result(variables)
|
143
|
+
end
|
144
|
+
end
|
135
145
|
|
136
|
-
|
137
|
-
|
138
|
-
@
|
139
|
-
|
140
|
-
@
|
141
|
-
|
142
|
-
|
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
|
-
|
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
|
-
|
147
|
-
|
148
|
-
|
185
|
+
#
|
186
|
+
#
|
187
|
+
# @yield
|
188
|
+
def capture(&block)
|
189
|
+
@capture = nil
|
190
|
+
buf_was = @_erbout
|
191
|
+
@_erbout = ""
|
149
192
|
|
150
|
-
|
151
|
-
@content_blocks ||= Hash.new {|h,k| h[k] = [] }
|
152
|
-
end
|
153
|
-
end
|
193
|
+
result = yield
|
154
194
|
|
155
|
-
|
156
|
-
|
195
|
+
@_erbout = buf_was
|
196
|
+
result.strip.empty? && @capture ? @capture : result
|
197
|
+
end
|
157
198
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
199
|
+
#
|
200
|
+
#
|
201
|
+
# @yield
|
202
|
+
def capture_later(&block)
|
203
|
+
proc { |*| @capture = capture(&block) }
|
204
|
+
end
|
205
|
+
|
206
|
+
private
|
162
207
|
|
163
|
-
|
164
|
-
|
165
|
-
|
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
|
-
|
169
|
-
|
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
|
-
|
172
|
-
|
173
|
-
|
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
|
-
|
176
|
-
|
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
|
-
|
179
|
-
|
180
|
-
|
242
|
+
c = collector_view_context(collector, collection)
|
243
|
+
c.tab_content
|
244
|
+
end
|
181
245
|
|
182
|
-
|
183
|
-
|
184
|
-
|
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
|
-
|
187
|
-
|
188
|
-
|
252
|
+
c = collector_view_context(collector, collection)
|
253
|
+
c.panel_content
|
254
|
+
end
|
189
255
|
|
190
|
-
|
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
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
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
|
-
|
201
|
-
|
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
|
-
|
204
|
-
|
205
|
-
|
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
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
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
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
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
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
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
|
-
|
332
|
+
private
|
224
333
|
|
225
|
-
|
226
|
-
|
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
|
-
|
232
|
-
|
345
|
+
|
346
|
+
# Include helpers into the Context.
|
347
|
+
include Helpers::Common
|
348
|
+
include Helpers::Collector
|
233
349
|
end
|
234
350
|
end
|
235
351
|
end
|
data/lib/rack/web_profiler.rb
CHANGED
@@ -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
|
-
|
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.
|
119
|
+
request.env[ENV_RUNTIME] = Time.now.to_f - request.env[ENV_RUNTIME_START]
|
120
|
+
request.env[ENV_EXCEPTION] = nil
|
78
121
|
|
79
|
-
|
80
|
-
request.
|
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
|