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.
Files changed (59) hide show
  1. data/History.txt +21 -0
  2. data/README.md +115 -0
  3. data/Rakefile +6 -19
  4. data/Thorfile +109 -0
  5. data/lib/rack/bug.rb +4 -2
  6. data/lib/rack/bug/filtered_backtrace.rb +38 -0
  7. data/lib/rack/bug/options.rb +4 -4
  8. data/lib/rack/bug/panel.rb +12 -12
  9. data/lib/rack/bug/panel_app.rb +8 -8
  10. data/lib/rack/bug/panels/active_record_panel.rb +11 -11
  11. data/lib/rack/bug/panels/active_record_panel/activerecord_extensions.rb +3 -3
  12. data/lib/rack/bug/panels/cache_panel.rb +1 -1
  13. data/lib/rack/bug/panels/cache_panel/memcache_extension.rb +4 -4
  14. data/lib/rack/bug/panels/cache_panel/panel_app.rb +11 -11
  15. data/lib/rack/bug/panels/cache_panel/stats.rb +20 -20
  16. data/lib/rack/bug/panels/log_panel.rb +27 -10
  17. data/lib/rack/bug/panels/log_panel/rails_extension.rb +2 -2
  18. data/lib/rack/bug/panels/memory_panel.rb +8 -8
  19. data/lib/rack/bug/panels/rails_info_panel.rb +5 -5
  20. data/lib/rack/bug/panels/redis_panel.rb +3 -3
  21. data/lib/rack/bug/panels/redis_panel/redis_extension.rb +3 -3
  22. data/lib/rack/bug/panels/redis_panel/stats.rb +17 -13
  23. data/lib/rack/bug/panels/request_variables_panel.rb +7 -7
  24. data/lib/rack/bug/panels/sphinx_panel.rb +44 -0
  25. data/lib/rack/bug/panels/sphinx_panel/sphinx_extension.rb +13 -0
  26. data/lib/rack/bug/panels/sphinx_panel/stats.rb +96 -0
  27. data/lib/rack/bug/panels/sql_panel.rb +1 -1
  28. data/lib/rack/bug/panels/sql_panel/panel_app.rb +7 -7
  29. data/lib/rack/bug/panels/sql_panel/query.rb +13 -23
  30. data/lib/rack/bug/panels/sql_panel/sql_extension.rb +2 -2
  31. data/lib/rack/bug/panels/templates_panel.rb +1 -1
  32. data/lib/rack/bug/panels/templates_panel/actionview_extension.rb +1 -1
  33. data/lib/rack/bug/panels/templates_panel/rendering.rb +14 -14
  34. data/lib/rack/bug/panels/templates_panel/trace.rb +8 -8
  35. data/lib/rack/bug/panels/timer_panel.rb +10 -10
  36. data/lib/rack/bug/params_signature.rb +18 -18
  37. data/lib/rack/bug/public/__rack_bug__/bookmarklet.js +7 -5
  38. data/lib/rack/bug/render.rb +16 -16
  39. data/lib/rack/bug/toolbar.rb +39 -33
  40. data/lib/rack/bug/views/panels/log.html.erb +4 -6
  41. data/lib/rack/bug/views/panels/redis.html.erb +14 -0
  42. data/lib/rack/bug/views/panels/sphinx.html.erb +32 -0
  43. data/rack-bug.gemspec +102 -97
  44. data/spec/fixtures/config.ru +3 -1
  45. data/spec/fixtures/sample_app.rb +7 -6
  46. data/spec/rack/bug/panels/active_record_panel_spec.rb +6 -6
  47. data/spec/rack/bug/panels/cache_panel_spec.rb +46 -46
  48. data/spec/rack/bug/panels/log_panel_spec.rb +8 -7
  49. data/spec/rack/bug/panels/memory_panel_spec.rb +6 -6
  50. data/spec/rack/bug/panels/rails_info_panel_spec.rb +5 -5
  51. data/spec/rack/bug/panels/redis_panel_spec.rb +31 -19
  52. data/spec/rack/bug/panels/sql_panel_spec.rb +45 -45
  53. data/spec/rack/bug/panels/templates_panel_spec.rb +18 -18
  54. data/spec/rack/bug/panels/timer_panel_spec.rb +12 -12
  55. data/spec/rack/toolbar_spec.rb +34 -28
  56. data/spec/spec_helper.rb +19 -9
  57. metadata +44 -13
  58. data/README.rdoc +0 -29
  59. 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("&amp;")
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
- alert('Rack::Bug Disabled');
206
+ window.location.reload();
207
207
  } else {
208
- var password = prompt("Rack::Bug password:", "")
209
- document.createCookie('rack_bug_password', document.SHA1('rack_bug:'+password));
210
- document.createCookie('rack_bug_enabled', "1");
211
- alert('Rack::Bug Enabled');
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
 
@@ -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
@@ -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
- elsif modify?
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["X-Requested-With"] != "XMLHttpRequest" &&
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 |log| %>
12
+ <% logs.each do |entry| %>
14
13
  <tr class="<%= i % 2 == 0 ? "even" : "odd" %>">
15
- <td></td>
16
- <td></td>
17
- <td><%= log.to_s.gsub(/\e\[[;\d]+m/, "") %></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 %>