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
@@ -0,0 +1,21 @@
1
+ == 0.3.0 / 2010-05-28
2
+
3
+ * New features
4
+
5
+ * Log panel includes log level and timestamp (Tim Connor)
6
+ * Sphinx panel (George Chatzigeorgiou)
7
+ * Backtraces for Redis panel (Luke Melia & Joey Aghion)
8
+
9
+ * Minor fixes
10
+
11
+ * Don't "enable" rack bug if you hit cancel on the bookmarklet prompt (Mischa Fierer)
12
+
13
+ * Compatibilty
14
+
15
+ * backtrace filtering now supports more than just Rails (Alex Chaffee)
16
+ * compatibility with current rack-test (Luke Melia & Joey Aghion)
17
+ * update Sinatra sample app (Tim Conner)
18
+
19
+ == 0.2.1
20
+
21
+ * The beginning of recorded history
@@ -0,0 +1,115 @@
1
+ Rack::Bug
2
+ =========
3
+
4
+ * Repository: [http://github.com/brynary/rack-bug](http://github.com/brynary/rack-bug)
5
+
6
+ Description
7
+ -----------
8
+
9
+ Rack::Bug adds a diagnostics toolbar to Rack apps. When enabled, it injects a floating div
10
+ allowing exploration of logging, database queries, template rendering times, etc.
11
+
12
+ Features
13
+ --------
14
+
15
+ * Password-based security
16
+ * IP-based security
17
+ * Rack::Bug instrumentation/reporting is broken up into panels.
18
+ * Panels in default configuration:
19
+ * Rails Info
20
+ * Timer
21
+ * Request Variables
22
+ * SQL
23
+ * Active Record
24
+ * Cache
25
+ * Templates
26
+ * Log
27
+ * Memory
28
+ * Other bundled panels:
29
+ * Redis
30
+ * Sphinx
31
+ * The API for adding your own panels is simple and powerful
32
+
33
+ Rails quick start
34
+ ---------------------------
35
+
36
+ script/plugin install git://github.com/brynary/rack-bug.git
37
+
38
+ In config/environments/development.rb, add:
39
+
40
+ config.middleware.use "Rack::Bug",
41
+ :secret_key => "someverylongandveryhardtoguesspreferablyrandomstring"
42
+
43
+ Add the bookmarklet to your browser:
44
+
45
+ open http://RAILS_APP/__rack_bug__/bookmarklet.html
46
+
47
+ Using with non-Rails Rack apps
48
+ ------------------------------
49
+ Nothing should prevent this from being possible. Please contribute docs if you do this. :-)
50
+
51
+ Configuring custom panels
52
+ -------------------------
53
+
54
+ Specify the set of panels you want, in the order you want them to appear:
55
+
56
+ require "rack/bug"
57
+
58
+ ActionController::Dispatcher.middleware.use Rack::Bug,
59
+ :secret_key => "someverylongandveryhardtoguesspreferablyrandomstring",
60
+ :panel_classes => [
61
+ Rack::Bug::TimerPanel,
62
+ Rack::Bug::RequestVariablesPanel,
63
+ Rack::Bug::RedisPanel,
64
+ Rack::Bug::TemplatesPanel,
65
+ Rack::Bug::LogPanel,
66
+ Rack::Bug::MemoryPanel
67
+ ]
68
+
69
+
70
+ Running Rack::Bug in staging or production
71
+ ------------------------------------------
72
+
73
+ We have have found that Rack::Bug is fast enough to run in production for specific troubleshooting efforts.
74
+
75
+ ### Configuration ####
76
+
77
+ Add the middleware configuration to an initializer or the appropriate environment files, taking the rest of this section into consideration.
78
+
79
+ ### Security ####
80
+
81
+ Restrict access to particular IP addresses:
82
+
83
+ require "ipaddr"
84
+
85
+ ActionController::Dispatcher.middleware.use "Rack::Bug"
86
+ :secret_key => "someverylongandveryhardtoguesspreferablyrandomstring",
87
+ :ip_masks => [IPAddr.new("2.2.2.2/0")]
88
+
89
+ Restrict access using a password:
90
+
91
+ ActionController::Dispatcher.middleware.use "Rack::Bug",
92
+ :secret_key => "someverylongandveryhardtoguesspreferablyrandomstring",
93
+ :password => "yourpassword"
94
+
95
+
96
+ Authors
97
+ -------
98
+
99
+ - Maintained by [Bryan Helmkamp](mailto:bryan@brynary.com)
100
+ - Contributions from Luke Melia, Joey Aghion, and more
101
+
102
+ Thanks
103
+ ------
104
+ Inspiration for Rack::Bug is primarily from the Django debug toolbar. Additional ideas from Rails footnotes, Rack's ShowException middleware, Oink, and Rack::Cache
105
+
106
+ Thanks to Weplay.com for supporting the development of Rack::Bug
107
+
108
+ Development
109
+ -----------
110
+ For development, you'll need to install the following gems: rspec, rack-test, webrat, sinatra
111
+
112
+ License
113
+ -------
114
+
115
+ See MIT-LICENSE.txt in this directory.
data/Rakefile CHANGED
@@ -1,24 +1,6 @@
1
1
  require "rubygems"
2
2
  require "spec/rake/spectask"
3
3
 
4
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/lib'
5
- require "rack/bug"
6
-
7
- begin
8
- require 'jeweler'
9
- Jeweler::Tasks.new do |s|
10
- s.name = "rack-bug"
11
- s.author = "Bryan Helmkamp"
12
- s.email = "bryan" + "@" + "brynary.com"
13
- s.homepage = "http://github.com/brynary/rack-bug"
14
- s.summary = "Debugging toolbar for Rack applications implemented as middleware"
15
- # s.description = "TODO"
16
- s.extra_rdoc_files = %w(README.rdoc MIT-LICENSE.txt)
17
- end
18
- rescue LoadError
19
- puts "Jeweler not available. Install it with: gem install jeweler"
20
- end
21
-
22
4
  Spec::Rake::SpecTask.new do |t|
23
5
  t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
24
6
  end
@@ -33,4 +15,9 @@ Spec::Rake::SpecTask.new(:rcov) do |t|
33
15
  end
34
16
 
35
17
  desc "Run the specs"
36
- task :default => :spec
18
+ task :default => :spec
19
+
20
+ desc 'Removes trailing whitespace'
21
+ task :whitespace do
22
+ sh %{find . -name '*.rb' -exec sed -i '' 's/ *$//g' {} \\;}
23
+ end
@@ -0,0 +1,109 @@
1
+ module GemHelpers
2
+
3
+ def generate_gemspec
4
+ $LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), "lib")))
5
+ require "rack/bug"
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "rack-bug"
9
+ s.version = Rack::Bug::VERSION
10
+ s.author = "Bryan Helmkamp"
11
+ s.email = "bryan@brynary.com"
12
+ s.homepage = "http://github.com/brynary/rack-bug"
13
+ s.summary = "Debugging toolbar for Rack applications implemented as middleware"
14
+ # s.description = "TODO"
15
+ s.rubyforge_project = "rack-bug"
16
+
17
+ require "git"
18
+ repo = Git.open(".")
19
+
20
+ s.files = normalize_files(repo.ls_files.keys - repo.lib.ignored_files)
21
+ s.test_files = normalize_files(Dir['spec/**/*.rb'] - repo.lib.ignored_files)
22
+
23
+ s.has_rdoc = true
24
+ s.extra_rdoc_files = %w[README.md MIT-LICENSE.txt]
25
+
26
+ s.add_dependency "rack", ">= 1.0"
27
+ end
28
+ end
29
+
30
+ def normalize_files(array)
31
+ # only keep files, no directories, and sort
32
+ array.select do |path|
33
+ File.file?(path)
34
+ end.sort
35
+ end
36
+
37
+ # Adds extra space when outputting an array. This helps create better version
38
+ # control diffs, because otherwise it is all on the same line.
39
+ def prettyify_array(gemspec_ruby, array_name)
40
+ gemspec_ruby.gsub(/s\.#{array_name.to_s} = \[.+?\]/) do |match|
41
+ leadin, files = match[0..-2].split("[")
42
+ leadin + "[\n #{files.split(",").join(",\n ")}\n ]"
43
+ end
44
+ end
45
+
46
+ def read_gemspec
47
+ @read_gemspec ||= eval(File.read("rack-bug.gemspec"))
48
+ end
49
+
50
+ def sh(command)
51
+ puts command
52
+ system command
53
+ end
54
+ end
55
+
56
+ class Default < Thor
57
+ include GemHelpers
58
+
59
+ desc "gemspec", "Regenerate rack-bug.gemspec"
60
+ def gemspec
61
+ File.open("rack-bug.gemspec", "w") do |file|
62
+ gemspec_ruby = generate_gemspec.to_ruby
63
+ gemspec_ruby = prettyify_array(gemspec_ruby, :files)
64
+ gemspec_ruby = prettyify_array(gemspec_ruby, :test_files)
65
+ gemspec_ruby = prettyify_array(gemspec_ruby, :extra_rdoc_files)
66
+
67
+ file.write gemspec_ruby
68
+ end
69
+
70
+ puts "Wrote gemspec to rack-bug.gemspec"
71
+ read_gemspec.validate
72
+ end
73
+
74
+ desc "build", "Build a rack-bug gem"
75
+ def build
76
+ sh "gem build rack-bug.gemspec"
77
+ FileUtils.mkdir_p "pkg"
78
+ FileUtils.mv read_gemspec.file_name, "pkg"
79
+ end
80
+
81
+ desc "install", "Install the latest built gem"
82
+ def install
83
+ sh "gem install --local pkg/#{read_gemspec.file_name}"
84
+ end
85
+
86
+ desc "release", "Release the current branch to GitHub and Gemcutter"
87
+ def release
88
+ gemspec
89
+ build
90
+ Release.new.tag
91
+ Release.new.gem
92
+ end
93
+ end
94
+
95
+ class Release < Thor
96
+ include GemHelpers
97
+
98
+ desc "tag", "Tag the gem on the origin server"
99
+ def tag
100
+ release_tag = "v#{read_gemspec.version}"
101
+ sh "git tag -a #{release_tag} -m 'Tagging #{release_tag}'"
102
+ sh "git push origin #{release_tag}"
103
+ end
104
+
105
+ desc "gem", "Push the gem to Gemcutter"
106
+ def gem
107
+ sh "gem push pkg/#{read_gemspec.file_name}"
108
+ end
109
+ end
@@ -1,6 +1,7 @@
1
1
  require "rack"
2
2
 
3
3
  module Rack::Bug
4
+ autoload :FilteredBacktrace, "rack/bug/filtered_backtrace"
4
5
  autoload :Options, "rack/bug/options"
5
6
  autoload :Panel, "rack/bug/panel"
6
7
  autoload :PanelApp, "rack/bug/panel_app"
@@ -19,8 +20,9 @@ module Rack::Bug
19
20
  autoload :SQLPanel, "rack/bug/panels/sql_panel"
20
21
  autoload :TemplatesPanel, "rack/bug/panels/templates_panel"
21
22
  autoload :TimerPanel, "rack/bug/panels/timer_panel"
23
+ autoload :SphinxPanel, "rack/bug/panels/sphinx_panel"
22
24
 
23
- VERSION = File.read(File.join(File.dirname(__FILE__), "..", "..", "VERSION")).strip
25
+ VERSION = "0.3.0"
24
26
 
25
27
  class SecurityError < StandardError
26
28
  end
@@ -40,4 +42,4 @@ module Rack::Bug
40
42
  def self.new(*args, &block)
41
43
  Toolbar.new(*args, &block)
42
44
  end
43
- end
45
+ end
@@ -0,0 +1,38 @@
1
+ module Rack
2
+ module Bug
3
+ module FilteredBacktrace
4
+
5
+ def backtrace
6
+ @backtrace
7
+ end
8
+
9
+ def has_backtrace?
10
+ filtered_backtrace.any?
11
+ end
12
+
13
+ def filtered_backtrace
14
+ @filtered_backtrace ||= @backtrace.map{|l| l.to_s.strip }.select do |line|
15
+ root_for_backtrace_filtering.nil? ||
16
+ (line.index(root_for_backtrace_filtering) == 0) && !(line.index(root_for_backtrace_filtering("vendor")) == 0)
17
+ end
18
+ end
19
+
20
+ def root_for_backtrace_filtering(sub_path = nil)
21
+ if defined?(Rails) && Rails.respond_to?(:root)
22
+ sub_path ? Rails.root.join(sub_path) : Rails.root
23
+ else
24
+ root = if defined?(RAILS_ROOT)
25
+ RAILS_ROOT
26
+ elsif defined?(ROOT)
27
+ ROOT
28
+ elsif defined?(Sinatra::Application)
29
+ Sinatra::Application.root
30
+ else
31
+ nil
32
+ end
33
+ sub_path ? ::File.join(root, sub_path) : root
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -9,7 +9,7 @@ module Rack::Bug
9
9
  define_method("#{key}?") { || !! read_option(key) }
10
10
  end
11
11
  end
12
-
12
+
13
13
  option_accessor :secret_key
14
14
  option_accessor :ip_masks
15
15
  option_accessor :password
@@ -45,7 +45,7 @@ module Rack::Bug
45
45
  end
46
46
 
47
47
  private
48
-
48
+
49
49
  def read_option(key)
50
50
  options[option_name(key)]
51
51
  end
@@ -61,7 +61,7 @@ module Rack::Bug
61
61
  else raise ArgumentError
62
62
  end
63
63
  end
64
-
64
+
65
65
  def initialize_options(options={})
66
66
  @default_options = {
67
67
  'rack-bug.ip_masks' => [IPAddr.new("127.0.0.1")],
@@ -84,6 +84,6 @@ module Rack::Bug
84
84
  }
85
85
  self.options = options
86
86
  end
87
-
87
+
88
88
  end
89
89
  end
@@ -2,14 +2,14 @@ require "erb"
2
2
 
3
3
  module Rack
4
4
  module Bug
5
-
5
+
6
6
  # Panels are also Rack middleware
7
7
  class Panel
8
8
  include Render
9
9
  include ERB::Util
10
-
10
+
11
11
  attr_reader :request
12
-
12
+
13
13
  def initialize(app)
14
14
  if panel_app
15
15
  @app = Rack::Cascade.new([panel_app, app])
@@ -17,7 +17,7 @@ module Rack
17
17
  @app = app
18
18
  end
19
19
  end
20
-
20
+
21
21
  def call(env)
22
22
  before(env)
23
23
  status, headers, body = @app.call(env)
@@ -26,25 +26,25 @@ module Rack
26
26
  env["rack-bug.panels"] << self
27
27
  return [status, headers, body]
28
28
  end
29
-
29
+
30
30
  def panel_app
31
31
  nil
32
32
  end
33
-
33
+
34
34
  def has_content?
35
35
  true
36
36
  end
37
-
37
+
38
38
  def before(env)
39
39
  end
40
-
40
+
41
41
  def after(env, status, headers, body)
42
42
  end
43
-
43
+
44
44
  def render(template)
45
45
  end
46
-
46
+
47
47
  end
48
-
48
+
49
49
  end
50
- end
50
+ end
@@ -1,20 +1,20 @@
1
1
  module Rack
2
2
  module Bug
3
-
3
+
4
4
  class PanelApp
5
5
  include Rack::Bug::Render
6
-
6
+
7
7
  attr_reader :request
8
-
8
+
9
9
  def call(env)
10
10
  @request = Rack::Request.new(env)
11
11
  dispatch
12
12
  end
13
-
13
+
14
14
  def render_template(*args)
15
15
  Rack::Response.new([super]).to_a
16
16
  end
17
-
17
+
18
18
  def params
19
19
  @request.GET
20
20
  end
@@ -26,8 +26,8 @@ module Rack
26
26
  def validate_params
27
27
  ParamsSignature.new(request).validate!
28
28
  end
29
-
29
+
30
30
  end
31
-
31
+
32
32
  end
33
- end
33
+ end