rack-webprofiler 0.1.0.pre.beta2 → 0.1.0
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.
- 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
|