rack-bug 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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 %>