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
@@ -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