rack-bug 0.2.1 → 0.3.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.
- data/History.txt +21 -0
- data/README.md +115 -0
- data/Rakefile +6 -19
- data/Thorfile +109 -0
- data/lib/rack/bug.rb +4 -2
- data/lib/rack/bug/filtered_backtrace.rb +38 -0
- data/lib/rack/bug/options.rb +4 -4
- data/lib/rack/bug/panel.rb +12 -12
- data/lib/rack/bug/panel_app.rb +8 -8
- data/lib/rack/bug/panels/active_record_panel.rb +11 -11
- data/lib/rack/bug/panels/active_record_panel/activerecord_extensions.rb +3 -3
- data/lib/rack/bug/panels/cache_panel.rb +1 -1
- data/lib/rack/bug/panels/cache_panel/memcache_extension.rb +4 -4
- data/lib/rack/bug/panels/cache_panel/panel_app.rb +11 -11
- data/lib/rack/bug/panels/cache_panel/stats.rb +20 -20
- data/lib/rack/bug/panels/log_panel.rb +27 -10
- data/lib/rack/bug/panels/log_panel/rails_extension.rb +2 -2
- data/lib/rack/bug/panels/memory_panel.rb +8 -8
- data/lib/rack/bug/panels/rails_info_panel.rb +5 -5
- data/lib/rack/bug/panels/redis_panel.rb +3 -3
- data/lib/rack/bug/panels/redis_panel/redis_extension.rb +3 -3
- data/lib/rack/bug/panels/redis_panel/stats.rb +17 -13
- data/lib/rack/bug/panels/request_variables_panel.rb +7 -7
- data/lib/rack/bug/panels/sphinx_panel.rb +44 -0
- data/lib/rack/bug/panels/sphinx_panel/sphinx_extension.rb +13 -0
- data/lib/rack/bug/panels/sphinx_panel/stats.rb +96 -0
- data/lib/rack/bug/panels/sql_panel.rb +1 -1
- data/lib/rack/bug/panels/sql_panel/panel_app.rb +7 -7
- data/lib/rack/bug/panels/sql_panel/query.rb +13 -23
- data/lib/rack/bug/panels/sql_panel/sql_extension.rb +2 -2
- data/lib/rack/bug/panels/templates_panel.rb +1 -1
- data/lib/rack/bug/panels/templates_panel/actionview_extension.rb +1 -1
- data/lib/rack/bug/panels/templates_panel/rendering.rb +14 -14
- data/lib/rack/bug/panels/templates_panel/trace.rb +8 -8
- data/lib/rack/bug/panels/timer_panel.rb +10 -10
- data/lib/rack/bug/params_signature.rb +18 -18
- data/lib/rack/bug/public/__rack_bug__/bookmarklet.js +7 -5
- data/lib/rack/bug/render.rb +16 -16
- data/lib/rack/bug/toolbar.rb +39 -33
- data/lib/rack/bug/views/panels/log.html.erb +4 -6
- data/lib/rack/bug/views/panels/redis.html.erb +14 -0
- data/lib/rack/bug/views/panels/sphinx.html.erb +32 -0
- data/rack-bug.gemspec +102 -97
- data/spec/fixtures/config.ru +3 -1
- data/spec/fixtures/sample_app.rb +7 -6
- data/spec/rack/bug/panels/active_record_panel_spec.rb +6 -6
- data/spec/rack/bug/panels/cache_panel_spec.rb +46 -46
- data/spec/rack/bug/panels/log_panel_spec.rb +8 -7
- data/spec/rack/bug/panels/memory_panel_spec.rb +6 -6
- data/spec/rack/bug/panels/rails_info_panel_spec.rb +5 -5
- data/spec/rack/bug/panels/redis_panel_spec.rb +31 -19
- data/spec/rack/bug/panels/sql_panel_spec.rb +45 -45
- data/spec/rack/bug/panels/templates_panel_spec.rb +18 -18
- data/spec/rack/bug/panels/timer_panel_spec.rb +12 -12
- data/spec/rack/toolbar_spec.rb +34 -28
- data/spec/spec_helper.rb +19 -9
- metadata +44 -13
- data/README.rdoc +0 -29
- data/VERSION +0 -1
@@ -1,34 +1,34 @@
|
|
1
1
|
module Rack
|
2
2
|
module Bug
|
3
3
|
class TemplatesPanel
|
4
|
-
|
4
|
+
|
5
5
|
class Trace
|
6
|
-
|
6
|
+
|
7
7
|
def start(template_name)
|
8
8
|
rendering = Rendering.new(template_name)
|
9
9
|
rendering.start_time = Time.now
|
10
10
|
@current.add(rendering)
|
11
11
|
@current = rendering
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def finished(template_name)
|
15
15
|
@current.end_time = Time.now
|
16
16
|
@current = @current.parent
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def initialize
|
20
20
|
@current = root
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def total_time
|
24
24
|
root.child_time
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def root
|
28
28
|
@root ||= Rendering.new("root")
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
end
|
33
33
|
end
|
34
|
-
end
|
34
|
+
end
|
@@ -2,39 +2,39 @@ require "benchmark"
|
|
2
2
|
|
3
3
|
module Rack
|
4
4
|
module Bug
|
5
|
-
|
5
|
+
|
6
6
|
class TimerPanel < Panel
|
7
|
-
|
7
|
+
|
8
8
|
def name
|
9
9
|
"timer"
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def call(env)
|
13
13
|
status, headers, body = nil
|
14
14
|
@times = Benchmark.measure do
|
15
15
|
status, headers, body = @app.call(env)
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
@measurements = [
|
19
19
|
["User CPU time", "%.2fms" % (@times.utime * 1_000)],
|
20
20
|
["System CPU time", "%.2fms" % (@times.stime * 1_000)],
|
21
21
|
["Total CPU time", "%.2fms" % (@times.total * 1_000)],
|
22
22
|
["Elapsed time", "%.2fms" % (@times.real * 1_000)]
|
23
23
|
]
|
24
|
-
|
24
|
+
|
25
25
|
env["rack-bug.panels"] << self
|
26
26
|
return [status, headers, body]
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def heading
|
30
30
|
"%.2fms" % (@times.real * 1_000)
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def content
|
34
34
|
render_template "panels/timer", :measurements => @measurements
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
end
|
40
|
-
end
|
40
|
+
end
|
@@ -2,64 +2,64 @@ require "digest"
|
|
2
2
|
|
3
3
|
module Rack
|
4
4
|
module Bug
|
5
|
-
|
5
|
+
|
6
6
|
class ParamsSignature
|
7
7
|
extend ERB::Util
|
8
|
-
|
8
|
+
|
9
9
|
def self.sign(request, hash)
|
10
10
|
parts = []
|
11
|
-
|
11
|
+
|
12
12
|
hash.keys.sort.each do |key|
|
13
13
|
parts << "#{key}=#{u(hash[key])}"
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
signature = new(request).signature(hash)
|
17
17
|
parts << "hash=#{u(signature)}"
|
18
|
-
|
18
|
+
|
19
19
|
parts.join("&")
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
attr_reader :request
|
23
|
-
|
23
|
+
|
24
24
|
def initialize(request)
|
25
25
|
@request = request
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def secret_key
|
29
29
|
@request.env['rack-bug.secret_key']
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def secret_key_blank?
|
33
33
|
secret_key.nil? || secret_key == ""
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
def validate!
|
37
37
|
if secret_key_blank?
|
38
38
|
raise SecurityError.new("Missing secret key")
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
if secret_key_blank? || request.params["hash"] != signature(request.params)
|
42
42
|
raise SecurityError.new("Invalid query hash.")
|
43
43
|
end
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
def signature(params)
|
47
47
|
Digest::SHA1.hexdigest(signature_base(params))
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
def signature_base(params)
|
51
51
|
signature = []
|
52
52
|
signature << secret_key
|
53
|
-
|
53
|
+
|
54
54
|
params.keys.sort.each do |key|
|
55
55
|
next if key == "hash"
|
56
56
|
signature << params[key].to_s
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
signature.join(":")
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
end
|
65
|
-
end
|
65
|
+
end
|
@@ -203,12 +203,14 @@ document.rackBugBookmarklet = function() {
|
|
203
203
|
if (document.readCookie('rack_bug_password')) {
|
204
204
|
document.eraseCookie('rack_bug_password');
|
205
205
|
document.eraseCookie('rack_bug_enabled');
|
206
|
-
|
206
|
+
window.location.reload();
|
207
207
|
} else {
|
208
|
-
var password = prompt("Rack::Bug password:", "")
|
209
|
-
|
210
|
-
|
211
|
-
|
208
|
+
var password = prompt("Rack::Bug password:", "");
|
209
|
+
if (password != null) {
|
210
|
+
document.createCookie('rack_bug_password', document.SHA1('rack_bug:'+password));
|
211
|
+
document.createCookie('rack_bug_enabled', "1");
|
212
|
+
window.location.reload();
|
213
|
+
}
|
212
214
|
}
|
213
215
|
}
|
214
216
|
|
data/lib/rack/bug/render.rb
CHANGED
@@ -2,50 +2,50 @@ require "erb"
|
|
2
2
|
|
3
3
|
module Rack
|
4
4
|
module Bug
|
5
|
-
|
5
|
+
|
6
6
|
module Render
|
7
7
|
include ERB::Util
|
8
|
-
|
8
|
+
|
9
9
|
def signed_params(hash)
|
10
10
|
ParamsSignature.sign(request, hash)
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
module CompiledTemplates
|
14
14
|
end
|
15
15
|
include CompiledTemplates
|
16
|
-
|
16
|
+
|
17
17
|
def render_template(filename, local_assigns = {})
|
18
18
|
compile(filename, local_assigns)
|
19
19
|
render_symbol = method_name(filename, local_assigns)
|
20
20
|
send(render_symbol, local_assigns)
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def compile(filename, local_assigns)
|
24
24
|
render_symbol = method_name(filename, local_assigns)
|
25
|
-
|
25
|
+
|
26
26
|
if !CompiledTemplates.instance_methods.include?(render_symbol.to_s)
|
27
27
|
compile!(filename, local_assigns)
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
def compile!(filename, local_assigns)
|
32
|
-
render_symbol = method_name(filename, local_assigns)
|
32
|
+
render_symbol = method_name(filename, local_assigns)
|
33
33
|
locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join
|
34
|
-
|
34
|
+
|
35
35
|
source = <<-end_src
|
36
36
|
def #{render_symbol}(local_assigns)
|
37
37
|
#{locals_code}
|
38
38
|
#{compiled_source(filename)}
|
39
39
|
end
|
40
40
|
end_src
|
41
|
-
|
41
|
+
|
42
42
|
CompiledTemplates.module_eval(source, filename, 0)
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
def compiled_source(filename)
|
46
46
|
::ERB.new(::File.read(::File.dirname(__FILE__) + "/../bug/views/#{filename}.html.erb"), nil, "-").src
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
def method_name(filename, local_assigns)
|
50
50
|
if local_assigns && local_assigns.any?
|
51
51
|
method_name = method_name_without_locals(filename).dup
|
@@ -55,12 +55,12 @@ module Rack
|
|
55
55
|
end
|
56
56
|
method_name.to_sym
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
def method_name_without_locals(filename)
|
60
60
|
filename.split("/").join("_")
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
end
|
66
|
-
end
|
66
|
+
end
|
data/lib/rack/bug/toolbar.rb
CHANGED
@@ -8,7 +8,7 @@ module Rack
|
|
8
8
|
@app = app
|
9
9
|
@static_app = static_app
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
def call(env)
|
13
13
|
if env["PATH_INFO"]
|
14
14
|
@static_app.call(env)
|
@@ -17,27 +17,27 @@ module Rack
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
class Toolbar
|
22
22
|
include Options
|
23
23
|
include Render
|
24
|
-
|
24
|
+
|
25
25
|
MIME_TYPES = ["text/html", "application/xhtml+xml"]
|
26
|
-
|
26
|
+
|
27
27
|
def initialize(app, options = {})
|
28
28
|
@app = asset_server(app)
|
29
29
|
initialize_options options
|
30
30
|
instance_eval(&block) if block_given?
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
def asset_server(app)
|
34
34
|
RackStaticBugAvoider.new(app, Rack::Static.new(app, :urls => ["/__rack_bug__"], :root => public_path))
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def public_path
|
38
38
|
::File.expand_path(::File.dirname(__FILE__) + "/../bug/public")
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def call(env)
|
42
42
|
env.replace @default_options.merge(env)
|
43
43
|
@env = env
|
@@ -49,29 +49,30 @@ module Rack
|
|
49
49
|
pass
|
50
50
|
end
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
def pass
|
54
54
|
@app.call(@env)
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
def dispatch
|
58
58
|
@env["rack-bug.panels"] = []
|
59
|
-
|
59
|
+
|
60
60
|
Rack::Bug.enable
|
61
61
|
status, headers, body = builder.call(@env)
|
62
62
|
Rack::Bug.disable
|
63
|
-
|
63
|
+
|
64
64
|
@response = Rack::Response.new(body, status, headers)
|
65
|
-
|
65
|
+
|
66
66
|
if @response.redirect? && options["rack-bug.intercept_redirects"]
|
67
67
|
intercept_redirect
|
68
|
-
|
68
|
+
end
|
69
|
+
if modify?
|
69
70
|
inject_toolbar
|
70
71
|
end
|
71
|
-
|
72
|
+
|
72
73
|
return @response.to_a
|
73
74
|
end
|
74
|
-
|
75
|
+
|
75
76
|
def intercept_redirect
|
76
77
|
redirect_to = @response.location
|
77
78
|
new_body = render_template("redirect", :redirect_to => @response.location)
|
@@ -79,59 +80,64 @@ module Rack
|
|
79
80
|
new_response["Content-Length"] = new_body.size.to_s
|
80
81
|
@response = new_response
|
81
82
|
end
|
82
|
-
|
83
|
+
|
83
84
|
def toolbar_requested?
|
84
85
|
@original_request.cookies["rack_bug_enabled"]
|
85
86
|
end
|
86
|
-
|
87
|
+
|
87
88
|
def ip_authorized?
|
88
89
|
return true unless options["rack-bug.ip_masks"]
|
89
|
-
|
90
|
+
|
90
91
|
options["rack-bug.ip_masks"].any? do |ip_mask|
|
91
92
|
ip_mask.include?(IPAddr.new(@original_request.ip))
|
92
93
|
end
|
93
94
|
end
|
94
|
-
|
95
|
+
|
95
96
|
def password_authorized?
|
96
97
|
return true unless options["rack-bug.password"]
|
97
|
-
|
98
|
+
|
98
99
|
expected_sha = Digest::SHA1.hexdigest ["rack_bug", options["rack-bug.password"]].join(":")
|
99
100
|
actual_sha = @original_request.cookies["rack_bug_password"]
|
100
|
-
|
101
|
+
|
101
102
|
actual_sha == expected_sha
|
102
103
|
end
|
103
|
-
|
104
|
+
|
104
105
|
def modify?
|
105
106
|
@response.ok? &&
|
106
|
-
@env["
|
107
|
+
@env["HTTP_X_REQUESTED_WITH"] != "XMLHttpRequest" &&
|
107
108
|
MIME_TYPES.include?(@response.content_type.split(";").first)
|
108
109
|
end
|
109
|
-
|
110
|
+
|
110
111
|
def builder
|
111
112
|
builder = Rack::Builder.new
|
112
|
-
|
113
|
+
|
113
114
|
options["rack-bug.panel_classes"].each do |panel_class|
|
114
115
|
builder.use panel_class
|
115
116
|
end
|
116
|
-
|
117
|
+
|
117
118
|
builder.run @app
|
118
|
-
|
119
|
+
|
119
120
|
return builder
|
120
121
|
end
|
121
|
-
|
122
|
+
|
122
123
|
def inject_toolbar
|
123
124
|
full_body = @response.body.join
|
124
125
|
full_body.sub! /<\/body>/, render + "</body>"
|
125
|
-
|
126
|
+
|
126
127
|
@response["Content-Length"] = full_body.size.to_s
|
128
|
+
|
129
|
+
# Ensure that browser does
|
130
|
+
@response["Etag"] = ""
|
131
|
+
@response["Cache-Control"] = "no-cache"
|
132
|
+
|
127
133
|
@response.body = [full_body]
|
128
134
|
end
|
129
|
-
|
135
|
+
|
130
136
|
def render
|
131
137
|
render_template("toolbar", :panels => @env["rack-bug.panels"].reverse)
|
132
138
|
end
|
133
|
-
|
139
|
+
|
134
140
|
end
|
135
|
-
|
141
|
+
|
136
142
|
end
|
137
|
-
end
|
143
|
+
end
|
@@ -5,17 +5,15 @@
|
|
5
5
|
<th>Level</th>
|
6
6
|
<th>Time</th>
|
7
7
|
<th>Message</th>
|
8
|
-
<th>Location</th>
|
9
8
|
</tr>
|
10
9
|
</thead>
|
11
10
|
<tbody>
|
12
11
|
<% i = 1 %>
|
13
|
-
<% logs.each do |
|
12
|
+
<% logs.each do |entry| %>
|
14
13
|
<tr class="<%= i % 2 == 0 ? "even" : "odd" %>">
|
15
|
-
<td
|
16
|
-
<td
|
17
|
-
<td><%=
|
18
|
-
<td></td>
|
14
|
+
<td><%= entry.level %></td>
|
15
|
+
<td><%= entry.time %>ms</td>
|
16
|
+
<td><%= entry.cleaned_message %></td>
|
19
17
|
</tr>
|
20
18
|
<% i += 1 %>
|
21
19
|
<% end %>
|