gentooboontoo-rack-bug 0.3.0.edge

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 (92) hide show
  1. data/.gitignore +3 -0
  2. data/History.txt +46 -0
  3. data/MIT-LICENSE.txt +19 -0
  4. data/README.md +120 -0
  5. data/Rakefile +23 -0
  6. data/Thorfile +113 -0
  7. data/lib/rack/bug/autoloading.rb +25 -0
  8. data/lib/rack/bug/filtered_backtrace.rb +38 -0
  9. data/lib/rack/bug/options.rb +89 -0
  10. data/lib/rack/bug/panel.rb +50 -0
  11. data/lib/rack/bug/panel_app.rb +33 -0
  12. data/lib/rack/bug/panels/active_record_panel/activerecord_extensions.rb +18 -0
  13. data/lib/rack/bug/panels/active_record_panel.rb +45 -0
  14. data/lib/rack/bug/panels/cache_panel/dalli_extension.rb +16 -0
  15. data/lib/rack/bug/panels/cache_panel/memcache_extension.rb +129 -0
  16. data/lib/rack/bug/panels/cache_panel/panel_app.rb +48 -0
  17. data/lib/rack/bug/panels/cache_panel/stats.rb +97 -0
  18. data/lib/rack/bug/panels/cache_panel.rb +51 -0
  19. data/lib/rack/bug/panels/log_panel/logger_extension.rb +24 -0
  20. data/lib/rack/bug/panels/log_panel.rb +56 -0
  21. data/lib/rack/bug/panels/memory_panel.rb +27 -0
  22. data/lib/rack/bug/panels/mongo_panel/mongo_extension.rb +27 -0
  23. data/lib/rack/bug/panels/mongo_panel/stats.rb +48 -0
  24. data/lib/rack/bug/panels/mongo_panel.rb +44 -0
  25. data/lib/rack/bug/panels/rails_info_panel.rb +23 -0
  26. data/lib/rack/bug/panels/redis_panel/redis_extension.rb +28 -0
  27. data/lib/rack/bug/panels/redis_panel/stats.rb +52 -0
  28. data/lib/rack/bug/panels/redis_panel.rb +44 -0
  29. data/lib/rack/bug/panels/request_variables_panel.rb +52 -0
  30. data/lib/rack/bug/panels/sphinx_panel/sphinx_extension.rb +25 -0
  31. data/lib/rack/bug/panels/sphinx_panel/stats.rb +96 -0
  32. data/lib/rack/bug/panels/sphinx_panel.rb +44 -0
  33. data/lib/rack/bug/panels/sql_panel/panel_app.rb +37 -0
  34. data/lib/rack/bug/panels/sql_panel/query.rb +63 -0
  35. data/lib/rack/bug/panels/sql_panel/sql_extension.rb +11 -0
  36. data/lib/rack/bug/panels/sql_panel.rb +55 -0
  37. data/lib/rack/bug/panels/templates_panel/actionview_extension.rb +12 -0
  38. data/lib/rack/bug/panels/templates_panel/rendering.rb +67 -0
  39. data/lib/rack/bug/panels/templates_panel/trace.rb +34 -0
  40. data/lib/rack/bug/panels/templates_panel.rb +47 -0
  41. data/lib/rack/bug/panels/timer_panel.rb +40 -0
  42. data/lib/rack/bug/params_signature.rb +63 -0
  43. data/lib/rack/bug/public/__rack_bug__/bookmarklet.html +10 -0
  44. data/lib/rack/bug/public/__rack_bug__/bookmarklet.js +217 -0
  45. data/lib/rack/bug/public/__rack_bug__/bug.css +220 -0
  46. data/lib/rack/bug/public/__rack_bug__/bug.js +84 -0
  47. data/lib/rack/bug/public/__rack_bug__/jquery-1.3.2.js +4376 -0
  48. data/lib/rack/bug/public/__rack_bug__/jquery.tablesorter.min.js +1 -0
  49. data/lib/rack/bug/public/__rack_bug__/spinner.gif +0 -0
  50. data/lib/rack/bug/rack_static_bug_avoider.rb +16 -0
  51. data/lib/rack/bug/redirect_interceptor.rb +27 -0
  52. data/lib/rack/bug/render.rb +67 -0
  53. data/lib/rack/bug/toolbar.rb +64 -0
  54. data/lib/rack/bug/views/error.html.erb +16 -0
  55. data/lib/rack/bug/views/panels/active_record.html.erb +17 -0
  56. data/lib/rack/bug/views/panels/cache.html.erb +93 -0
  57. data/lib/rack/bug/views/panels/execute_sql.html.erb +38 -0
  58. data/lib/rack/bug/views/panels/explain_sql.html.erb +38 -0
  59. data/lib/rack/bug/views/panels/log.html.erb +21 -0
  60. data/lib/rack/bug/views/panels/mongo.html.erb +32 -0
  61. data/lib/rack/bug/views/panels/profile_sql.html.erb +38 -0
  62. data/lib/rack/bug/views/panels/rails_info.html.erb +19 -0
  63. data/lib/rack/bug/views/panels/redis.html.erb +46 -0
  64. data/lib/rack/bug/views/panels/request_variables.html.erb +29 -0
  65. data/lib/rack/bug/views/panels/sphinx.html.erb +32 -0
  66. data/lib/rack/bug/views/panels/sql.html.erb +41 -0
  67. data/lib/rack/bug/views/panels/templates.html.erb +7 -0
  68. data/lib/rack/bug/views/panels/timer.html.erb +19 -0
  69. data/lib/rack/bug/views/panels/view_cache.html.erb +19 -0
  70. data/lib/rack/bug/views/redirect.html.erb +16 -0
  71. data/lib/rack/bug/views/toolbar.html.erb +42 -0
  72. data/lib/rack/bug.rb +82 -0
  73. data/rack-bug.gemspec +155 -0
  74. data/spec/custom_matchers.rb +21 -0
  75. data/spec/fixtures/config.ru +8 -0
  76. data/spec/fixtures/dummy_panel.rb +2 -0
  77. data/spec/fixtures/sample_app.rb +46 -0
  78. data/spec/rack/bug/panels/active_record_panel_spec.rb +30 -0
  79. data/spec/rack/bug/panels/cache_panel_spec.rb +167 -0
  80. data/spec/rack/bug/panels/log_panel_spec.rb +43 -0
  81. data/spec/rack/bug/panels/memory_panel_spec.rb +22 -0
  82. data/spec/rack/bug/panels/mongo_panel_spec.rb +51 -0
  83. data/spec/rack/bug/panels/rails_info_panel_spec.rb +40 -0
  84. data/spec/rack/bug/panels/redis_panel_spec.rb +69 -0
  85. data/spec/rack/bug/panels/sql_panel_spec.rb +146 -0
  86. data/spec/rack/bug/panels/templates_panel_spec.rb +71 -0
  87. data/spec/rack/bug/panels/timer_panel_spec.rb +38 -0
  88. data/spec/rack/bug_spec.rb +137 -0
  89. data/spec/rcov.opts +1 -0
  90. data/spec/spec.opts +1 -0
  91. data/spec/spec_helper.rb +44 -0
  92. metadata +245 -0
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ coverage
2
+ pkg
3
+ TODO
data/History.txt ADDED
@@ -0,0 +1,46 @@
1
+ == HEAD
2
+
3
+ * New features
4
+
5
+ * Can use LoggerPanel on ruby stdlib Logger in non-rails app (Tim Connor)
6
+
7
+ * Bug fixes
8
+
9
+ * Fix profile, explain and select in the queries tab, fixes issue #22 (ebertech)
10
+
11
+ * Minor fixes
12
+
13
+ * Explicitly require 'digest/sha1' (Jérémy Lecour)
14
+ * Eliminate unreachable code in params signature validation (Tim Connor)
15
+
16
+ * Compatibilty
17
+
18
+ * Make Redis panel compatible with latest redis-rb gem, without breaking older redis-rb versions (Luke Melia)
19
+ * Fix issues with Ruby 1.9.2 and with mysql2 (George Ogota)
20
+
21
+ * Other
22
+
23
+ * Refactoring and code cleanup (Tim Connor)
24
+ * Testing cleanup - better isolation of Rails vs. non-Rails in tests (Tim Connor)
25
+
26
+ == 0.3.0 / 2010-05-28
27
+
28
+ * New features
29
+
30
+ * Log panel includes log level and timestamp (Tim Connor)
31
+ * Sphinx panel (George Chatzigeorgiou)
32
+ * Backtraces for Redis panel (Luke Melia & Joey Aghion)
33
+
34
+ * Minor fixes
35
+
36
+ * Don't "enable" rack bug if you hit cancel on the bookmarklet prompt (Mischa Fierer)
37
+
38
+ * Compatibilty
39
+
40
+ * backtrace filtering now supports more than just Rails (Alex Chaffee)
41
+ * compatibility with current rack-test (Luke Melia & Joey Aghion)
42
+ * update Sinatra sample app (Tim Conner)
43
+
44
+ == 0.2.1
45
+
46
+ * The beginning of recorded history
data/MIT-LICENSE.txt ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2009 Bryan Helmkamp
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,120 @@
1
+ Rack::Bug
2
+ =========
3
+
4
+ Forked mainly to host an up to date versioned gem at Rubygems
5
+
6
+ * Repository: [http://github.com/brynary/rack-bug](http://github.com/brynary/rack-bug)
7
+
8
+ Description
9
+ -----------
10
+
11
+ Rack::Bug adds a diagnostics toolbar to Rack apps. When enabled, it injects a floating div
12
+ allowing exploration of logging, database queries, template rendering times, etc.
13
+
14
+ Features
15
+ --------
16
+
17
+ * Password-based security
18
+ * IP-based security
19
+ * Rack::Bug instrumentation/reporting is broken up into panels.
20
+ * Panels in default configuration:
21
+ * Rails Info
22
+ * Timer
23
+ * Request Variables
24
+ * SQL
25
+ * Active Record
26
+ * Cache
27
+ * Templates
28
+ * Log
29
+ * Memory
30
+ * Other bundled panels:
31
+ * Redis
32
+ * Sphinx
33
+ * The API for adding your own panels is simple and powerful
34
+
35
+ Rails quick start
36
+ ---------------------------
37
+
38
+ script/plugin install git://github.com/brynary/rack-bug.git
39
+
40
+ In config/environments/development.rb, add:
41
+
42
+ config.middleware.use "Rack::Bug",
43
+ :secret_key => "someverylongandveryhardtoguesspreferablyrandomstring"
44
+
45
+ Add the bookmarklet to your browser:
46
+
47
+ open http://RAILS_APP/__rack_bug__/bookmarklet.html
48
+
49
+ Using with non-Rails Rack apps
50
+ ------------------------------
51
+
52
+ Just 'use Rack::Bug' as any other middleware. See the SampleApp in the spec/fixtures folder for an example Sinatra app.
53
+
54
+ If you wish to use the logger panel define the LOGGER constant that is a ruby Logger or ActiveSupport::BufferedLogger
55
+
56
+ Configuring custom panels
57
+ -------------------------
58
+
59
+ Specify the set of panels you want, in the order you want them to appear:
60
+
61
+ require "rack/bug"
62
+
63
+ ActionController::Dispatcher.middleware.use Rack::Bug,
64
+ :secret_key => "someverylongandveryhardtoguesspreferablyrandomstring",
65
+ :panel_classes => [
66
+ Rack::Bug::TimerPanel,
67
+ Rack::Bug::RequestVariablesPanel,
68
+ Rack::Bug::RedisPanel,
69
+ Rack::Bug::TemplatesPanel,
70
+ Rack::Bug::LogPanel,
71
+ Rack::Bug::MemoryPanel
72
+ ]
73
+
74
+
75
+ Running Rack::Bug in staging or production
76
+ ------------------------------------------
77
+
78
+ We have have found that Rack::Bug is fast enough to run in production for specific troubleshooting efforts.
79
+
80
+ ### Configuration ####
81
+
82
+ Add the middleware configuration to an initializer or the appropriate environment files, taking the rest of this section into consideration.
83
+
84
+ ### Security ####
85
+
86
+ Restrict access to particular IP addresses:
87
+
88
+ require "ipaddr"
89
+
90
+ ActionController::Dispatcher.middleware.use "Rack::Bug"
91
+ :secret_key => "someverylongandveryhardtoguesspreferablyrandomstring",
92
+ :ip_masks => [IPAddr.new("2.2.2.2/0")]
93
+
94
+ Restrict access using a password:
95
+
96
+ ActionController::Dispatcher.middleware.use "Rack::Bug",
97
+ :secret_key => "someverylongandveryhardtoguesspreferablyrandomstring",
98
+ :password => "yourpassword"
99
+
100
+
101
+ Authors
102
+ -------
103
+
104
+ - Maintained by [Bryan Helmkamp](mailto:bryan@brynary.com)
105
+ - Contributions from Luke Melia, Joey Aghion, Tim Connor, and more
106
+
107
+ Thanks
108
+ ------
109
+ Inspiration for Rack::Bug is primarily from the Django debug toolbar. Additional ideas from Rails footnotes, Rack's ShowException middleware, Oink, and Rack::Cache
110
+
111
+ Thanks to Weplay.com for supporting the development of Rack::Bug
112
+
113
+ Development
114
+ -----------
115
+ For development, you'll need to install the following gems: rspec, rack-test, webrat, sinatra
116
+
117
+ License
118
+ -------
119
+
120
+ See MIT-LICENSE.txt in this directory.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require "rubygems"
2
+ require "spec/rake/spectask"
3
+
4
+ Spec::Rake::SpecTask.new do |t|
5
+ t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
6
+ end
7
+
8
+ desc "Run all specs in spec directory with RCov"
9
+ Spec::Rake::SpecTask.new(:rcov) do |t|
10
+ t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
11
+ t.rcov = true
12
+ t.rcov_opts = lambda do
13
+ IO.readlines(File.dirname(__FILE__) + "/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
14
+ end
15
+ end
16
+
17
+ desc "Run the specs"
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
data/Thorfile ADDED
@@ -0,0 +1,113 @@
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 = "gentooboontoo-rack-bug"
9
+ s.version = "#{Rack::Bug::VERSION}.edge"
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
+ s.add_development_dependency "webrat"
28
+ s.add_development_dependency "rspec"
29
+ s.add_development_dependency "sinatra"
30
+ s.add_development_dependency "git"
31
+ end
32
+ end
33
+
34
+ def normalize_files(array)
35
+ # only keep files, no directories, and sort
36
+ array.select do |path|
37
+ File.file?(path)
38
+ end.sort
39
+ end
40
+
41
+ # Adds extra space when outputting an array. This helps create better version
42
+ # control diffs, because otherwise it is all on the same line.
43
+ def prettyify_array(gemspec_ruby, array_name)
44
+ gemspec_ruby.gsub(/s\.#{array_name.to_s} = \[.+?\]/) do |match|
45
+ leadin, files = match[0..-2].split("[")
46
+ leadin + "[\n #{files.split(",").join(",\n ")}\n ]"
47
+ end
48
+ end
49
+
50
+ def read_gemspec
51
+ @read_gemspec ||= eval(File.read("rack-bug.gemspec"))
52
+ end
53
+
54
+ def sh(command)
55
+ puts command
56
+ system command
57
+ end
58
+ end
59
+
60
+ class Default < Thor
61
+ include GemHelpers
62
+
63
+ desc "gemspec", "Regenerate rack-bug.gemspec"
64
+ def gemspec
65
+ File.open("rack-bug.gemspec", "w") do |file|
66
+ gemspec_ruby = generate_gemspec.to_ruby
67
+ gemspec_ruby = prettyify_array(gemspec_ruby, :files)
68
+ gemspec_ruby = prettyify_array(gemspec_ruby, :test_files)
69
+ gemspec_ruby = prettyify_array(gemspec_ruby, :extra_rdoc_files)
70
+
71
+ file.write gemspec_ruby
72
+ end
73
+
74
+ puts "Wrote gemspec to rack-bug.gemspec"
75
+ read_gemspec.validate
76
+ end
77
+
78
+ desc "build", "Build a rack-bug gem"
79
+ def build
80
+ sh "gem build rack-bug.gemspec"
81
+ FileUtils.mkdir_p "pkg"
82
+ FileUtils.mv read_gemspec.file_name, "pkg"
83
+ end
84
+
85
+ desc "install", "Install the latest built gem"
86
+ def install
87
+ sh "gem install --local pkg/#{read_gemspec.file_name}"
88
+ end
89
+
90
+ desc "release", "Release the current branch to GitHub and Gemcutter"
91
+ def release
92
+ gemspec
93
+ build
94
+ Release.new.tag
95
+ Release.new.gem
96
+ end
97
+ end
98
+
99
+ class Release < Thor
100
+ include GemHelpers
101
+
102
+ desc "tag", "Tag the gem on the origin server"
103
+ def tag
104
+ release_tag = "v#{read_gemspec.version}"
105
+ sh "git tag -a #{release_tag} -m 'Tagging #{release_tag}'"
106
+ sh "git push origin #{release_tag}"
107
+ end
108
+
109
+ desc "gem", "Push the gem to Gemcutter"
110
+ def gem
111
+ sh "gem push pkg/#{read_gemspec.file_name}"
112
+ end
113
+ end
@@ -0,0 +1,25 @@
1
+ class Rack::Bug
2
+ autoload :FilteredBacktrace, "rack/bug/filtered_backtrace"
3
+ autoload :Options, "rack/bug/options"
4
+ autoload :Panel, "rack/bug/panel"
5
+ autoload :PanelApp, "rack/bug/panel_app"
6
+ autoload :ParamsSignature, "rack/bug/params_signature"
7
+ autoload :RackStaticBugAvoider, "rack/bug/rack_static_bug_avoider"
8
+ autoload :RedirectInterceptor, "rack/bug/redirect_interceptor"
9
+ autoload :Render, "rack/bug/render"
10
+ autoload :Toolbar, "rack/bug/toolbar"
11
+
12
+ # Panels
13
+ autoload :ActiveRecordPanel, "rack/bug/panels/active_record_panel"
14
+ autoload :CachePanel, "rack/bug/panels/cache_panel"
15
+ autoload :LogPanel, "rack/bug/panels/log_panel"
16
+ autoload :MemoryPanel, "rack/bug/panels/memory_panel"
17
+ autoload :RailsInfoPanel, "rack/bug/panels/rails_info_panel"
18
+ autoload :RedisPanel, "rack/bug/panels/redis_panel"
19
+ autoload :MongoPanel, "rack/bug/panels/mongo_panel"
20
+ autoload :RequestVariablesPanel, "rack/bug/panels/request_variables_panel"
21
+ autoload :SQLPanel, "rack/bug/panels/sql_panel"
22
+ autoload :TemplatesPanel, "rack/bug/panels/templates_panel"
23
+ autoload :TimerPanel, "rack/bug/panels/timer_panel"
24
+ autoload :SphinxPanel, "rack/bug/panels/sphinx_panel"
25
+ end
@@ -0,0 +1,38 @@
1
+ module Rack
2
+ class 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).to_s
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.to_s
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,89 @@
1
+ class Rack::Bug
2
+
3
+ module Options
4
+ class << self
5
+ private
6
+ def option_accessor(key)
7
+ define_method(key) { || read_option(key) }
8
+ define_method("#{key}=") { |value| write_option(key, value) }
9
+ define_method("#{key}?") { || !! read_option(key) }
10
+ end
11
+ end
12
+
13
+ option_accessor :secret_key
14
+ option_accessor :ip_masks
15
+ option_accessor :password
16
+ option_accessor :panel_classes
17
+ option_accessor :intercept_redirects
18
+
19
+ # The underlying options Hash. During initialization (or outside of a
20
+ # request), this is a default values Hash. During a request, this is the
21
+ # Rack environment Hash. The default values Hash is merged in underneath
22
+ # the Rack environment before each request is processed.
23
+ def options
24
+ @env || @default_options
25
+ end
26
+
27
+ # Set multiple options.
28
+ def options=(hash={})
29
+ hash.each { |key,value| write_option(key, value) }
30
+ end
31
+
32
+ # Set an option. When +option+ is a Symbol, it is set in the Rack
33
+ # Environment as "rack-cache.option". When +option+ is a String, it
34
+ # exactly as specified. The +option+ argument may also be a Hash in
35
+ # which case each key/value pair is merged into the environment as if
36
+ # the #set method were called on each.
37
+ def set(option, value=self, &block)
38
+ if block_given?
39
+ write_option option, block
40
+ elsif value == self
41
+ self.options = option.to_hash
42
+ else
43
+ write_option option, value
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def read_option(key)
50
+ options[option_name(key)]
51
+ end
52
+
53
+ def write_option(key, value)
54
+ options[option_name(key)] = value
55
+ end
56
+
57
+ def option_name(key)
58
+ case key
59
+ when Symbol ; "rack-bug.#{key}"
60
+ when String ; key
61
+ else raise ArgumentError
62
+ end
63
+ end
64
+
65
+ def initialize_options(options={})
66
+ @default_options = {
67
+ 'rack-bug.ip_masks' => [IPAddr.new("127.0.0.1")],
68
+ 'rack-bug.password' => nil,
69
+ 'rack-bug.verbose' => nil,
70
+ 'rack-bug.secret_key' => nil,
71
+ 'rack-bug.intercept_redirects' => false,
72
+ 'rack-bug.panels' => [],
73
+ 'rack-bug.panel_classes' => [
74
+ RailsInfoPanel,
75
+ TimerPanel,
76
+ RequestVariablesPanel,
77
+ SQLPanel,
78
+ ActiveRecordPanel,
79
+ CachePanel,
80
+ TemplatesPanel,
81
+ LogPanel,
82
+ MemoryPanel
83
+ ]
84
+ }
85
+ self.options = options
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,50 @@
1
+ require "erb"
2
+
3
+ module Rack
4
+ class Bug
5
+
6
+ # Panels are also Rack middleware
7
+ class Panel
8
+ include Render
9
+ include ERB::Util
10
+
11
+ attr_reader :request
12
+
13
+ def initialize(app)
14
+ if panel_app
15
+ @app = Rack::Cascade.new([panel_app, app])
16
+ else
17
+ @app = app
18
+ end
19
+ end
20
+
21
+ def call(env)
22
+ before(env)
23
+ status, headers, body = @app.call(env)
24
+ @request = Request.new(env)
25
+ after(env, status, headers, body)
26
+ env["rack-bug.panels"] << self
27
+ return [status, headers, body]
28
+ end
29
+
30
+ def panel_app
31
+ nil
32
+ end
33
+
34
+ def has_content?
35
+ true
36
+ end
37
+
38
+ def before(env)
39
+ end
40
+
41
+ def after(env, status, headers, body)
42
+ end
43
+
44
+ def render(template)
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,33 @@
1
+ module Rack
2
+ class Bug
3
+
4
+ class PanelApp
5
+ include Rack::Bug::Render
6
+
7
+ attr_reader :request
8
+
9
+ def call(env)
10
+ @request = Rack::Request.new(env)
11
+ dispatch
12
+ end
13
+
14
+ def render_template(*args)
15
+ Rack::Response.new([super]).to_a
16
+ end
17
+
18
+ def params
19
+ @request.GET
20
+ end
21
+
22
+ def not_found
23
+ [404, {}, []]
24
+ end
25
+
26
+ def validate_params
27
+ ParamsSignature.new(request).validate!
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,18 @@
1
+ if defined?(ActiveRecord)
2
+ ActiveRecord::Base.class_eval do
3
+
4
+ if instance_methods.include?("after_initialize")
5
+ def after_initialize_with_rack_bug
6
+ Rack::Bug::ActiveRecordPanel.record(self.class.base_class.name)
7
+ after_initialize_without_rack_bug
8
+ end
9
+
10
+ alias_method_chain :after_initialize, :rack_bug
11
+ else
12
+ def after_initialize
13
+ Rack::Bug::ActiveRecordPanel.record(self.class.base_class.name)
14
+ end
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,45 @@
1
+ require "rack/bug/panels/active_record_panel/activerecord_extensions"
2
+
3
+ module Rack
4
+ class Bug
5
+
6
+ class ActiveRecordPanel < Panel
7
+
8
+ def self.record(class_name)
9
+ return unless Rack::Bug.enabled?
10
+ records[class_name] += 1
11
+ end
12
+
13
+ def self.reset
14
+ Thread.current["rack.bug.active_records"] = Hash.new { 0 }
15
+ end
16
+
17
+ def self.records
18
+ Thread.current["rack.bug.active_records"] ||= Hash.new { 0 }
19
+ end
20
+
21
+ def self.total
22
+ records.inject(0) do |memo, (key, value)|
23
+ memo + value
24
+ end
25
+ end
26
+
27
+ def name
28
+ "active_record"
29
+ end
30
+
31
+ def heading
32
+ "#{self.class.total} AR Objects"
33
+ end
34
+
35
+ def content
36
+ records = self.class.records.to_a.sort_by { |key, value| value }.reverse
37
+ result = render_template "panels/active_record", :records => records
38
+ self.class.reset
39
+ result
40
+ end
41
+
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,16 @@
1
+ begin
2
+
3
+ require 'dalli'
4
+
5
+ Dalli::Client.class_eval do
6
+ def perform_with_rack_bug(op, *args)
7
+ Rack::Bug::CachePanel.record(op, args.first) do
8
+ perform_without_rack_bug(op, *args)
9
+ end
10
+ end
11
+
12
+ alias_method_chain :perform, :rack_bug
13
+ end
14
+
15
+ rescue NameError, LoadError
16
+ end