rack-insight 0.5.26 → 0.5.27
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.
- checksums.yaml +7 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -5
- data/CHANGELOG +26 -4
- data/Gemfile.lock +25 -33
- data/README.md +8 -9
- data/lib/rack/insight/config.rb +27 -2
- data/lib/rack/insight/database.rb +20 -7
- data/lib/rack/insight/instrumentation.rb +1 -0
- data/lib/rack/insight/instrumentation/eigen_client.rb +16 -0
- data/lib/rack/insight/logging.rb +11 -13
- data/lib/rack/insight/panel.rb +14 -7
- data/lib/rack/insight/panels/log_panel.rb +2 -1
- data/lib/rack/insight/panels/redis_panel.rb +0 -20
- data/lib/rack/insight/panels/redis_panel/stats.rb +1 -0
- data/lib/rack/insight/panels/speedtracer_panel.rb +3 -0
- data/lib/rack/insight/params_signature.rb +8 -6
- data/lib/rack/insight/rspec_matchers.rb +16 -0
- data/lib/rack/insight/toolbar.rb +1 -0
- data/lib/rack/insight/version.rb +1 -1
- data/rack-insight.gemspec +13 -10
- data/spec/insight_spec.rb +21 -18
- data/spec/instrumentation_spec.rb +45 -2
- data/spec/rack/insight/panels/active_record_panel_spec.rb +7 -7
- data/spec/rack/insight/panels/active_resource_panel_spec.rb +4 -4
- data/spec/rack/insight/panels/cache_panel_spec.rb +6 -6
- data/spec/rack/insight/panels/log_panel_spec.rb +9 -11
- data/spec/rack/insight/panels/memory_panel_spec.rb +1 -1
- data/spec/rack/insight/panels/rails_info_panel_spec.rb +5 -5
- data/spec/rack/insight/panels/redis_panel_spec.rb +17 -3
- data/spec/rack/insight/panels/speedtracer_panel_spec.rb +87 -86
- data/spec/rack/insight/panels/sql_panel_spec.rb +11 -8
- data/spec/rack/insight/panels/templates_panel_spec.rb +8 -7
- data/spec/rack/insight/panels/timer_panel_spec.rb +4 -4
- data/spec/spec_helper.rb +6 -4
- metadata +47 -100
@@ -1,8 +1,9 @@
|
|
1
1
|
module Rack::Insight
|
2
2
|
class LogPanel < Panel
|
3
3
|
class LogEntry
|
4
|
+
# TODO: Update this to the Rack::Insight panel format
|
4
5
|
attr_reader :level, :time, :message
|
5
|
-
LEVELS = ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL']
|
6
|
+
LEVELS = ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL'] unless defined?(LEVELS)
|
6
7
|
|
7
8
|
def initialize(level, time, message)
|
8
9
|
@level = LEVELS[level]
|
@@ -2,26 +2,6 @@ module Rack::Insight
|
|
2
2
|
class RedisPanel < Panel
|
3
3
|
require "rack/insight/panels/redis_panel/stats"
|
4
4
|
|
5
|
-
def initialize(app)
|
6
|
-
super
|
7
|
-
|
8
|
-
unless is_probing?
|
9
|
-
probe(self) do
|
10
|
-
if defined?(Redis::Client)
|
11
|
-
# Redis >= 3.0.0
|
12
|
-
instrument "Redis::Client" do
|
13
|
-
instance_probe :call
|
14
|
-
end
|
15
|
-
elsif defined?(Redis)
|
16
|
-
# Redis < 3.0.0
|
17
|
-
instrument "Redis" do
|
18
|
-
instance_probe :call_command
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
5
|
def request_start(env, start)
|
26
6
|
@stats = Stats.new
|
27
7
|
end
|
@@ -9,6 +9,9 @@ require 'rack/insight/panels/speedtracer_panel/tracer'
|
|
9
9
|
|
10
10
|
module Rack::Insight
|
11
11
|
module SpeedTracer
|
12
|
+
# TODO Refactor this class name...
|
13
|
+
# TODO: Fix indentation of this class.
|
14
|
+
# TODO: Update this class to Rack::Insight pattern.
|
12
15
|
class Panel < ::Rack::Insight::Panel
|
13
16
|
|
14
17
|
def initialize(app)
|
@@ -6,14 +6,15 @@ module Rack::Insight
|
|
6
6
|
extend ERB::Util
|
7
7
|
|
8
8
|
def self.sign(request, hash)
|
9
|
+
#puts "ParamsSignature#sign called!: #{caller.first}"
|
9
10
|
parts = []
|
10
11
|
|
11
12
|
hash.keys.sort.each do |key|
|
12
13
|
parts << "#{key}=#{u(hash[key])}"
|
13
14
|
end
|
14
15
|
|
15
|
-
|
16
|
-
parts << "hash=#{u(
|
16
|
+
hancock = new(request).signature(hash)
|
17
|
+
parts << "hash=#{u(hancock)}"
|
17
18
|
|
18
19
|
parts.join("&")
|
19
20
|
end
|
@@ -36,6 +37,7 @@ module Rack::Insight
|
|
36
37
|
if secret_key_blank?
|
37
38
|
raise SecurityError.new("Missing secret key")
|
38
39
|
elsif request.params["hash"] != signature(request.params)
|
40
|
+
#puts "request params hash: #{request.params}\nsignature: #{signature(request.params)}"
|
39
41
|
raise SecurityError.new("Invalid query hash.")
|
40
42
|
end
|
41
43
|
end
|
@@ -45,15 +47,15 @@ module Rack::Insight
|
|
45
47
|
end
|
46
48
|
|
47
49
|
def signature_base(params)
|
48
|
-
|
49
|
-
|
50
|
+
hancock = []
|
51
|
+
hancock << secret_key
|
50
52
|
|
51
53
|
params.keys.sort.each do |key|
|
52
54
|
next if key == "hash"
|
53
|
-
|
55
|
+
hancock << params[key].to_s
|
54
56
|
end
|
55
57
|
|
56
|
-
|
58
|
+
hancock.join(":")
|
57
59
|
end
|
58
60
|
|
59
61
|
end
|
@@ -17,6 +17,22 @@ module Rack::Insight
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
+
RSpec::Matchers.define :have_li do |container, key, value|
|
21
|
+
match do |response|
|
22
|
+
if value
|
23
|
+
response.should have_selector("#{container} li", :content => key) do |row|
|
24
|
+
row.should contain(value)
|
25
|
+
end
|
26
|
+
else
|
27
|
+
response.should have_selector("#{container} li", :content => key)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
failure_message_for_should do |response|
|
32
|
+
"Expected: \n#{response.body}\nto have a li matching #{key}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
20
36
|
RSpec::Matchers.define :have_heading do |text|
|
21
37
|
match do |response|
|
22
38
|
response.should have_selector("#rack-insight_toolbar li") do |heading|
|
data/lib/rack/insight/toolbar.rb
CHANGED
@@ -26,6 +26,7 @@ module Rack::Insight
|
|
26
26
|
|
27
27
|
def okay_to_modify?(env, response)
|
28
28
|
req = Rack::Request.new(env)
|
29
|
+
return false unless response.content_type.respond_to?(:split)
|
29
30
|
content_type, charset = response.content_type.split(";")
|
30
31
|
|
31
32
|
response.ok? && MIME_TYPES.include?(content_type) && !req.xhr?
|
data/lib/rack/insight/version.rb
CHANGED
data/rack-insight.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.version = Rack::Insight::VERSION
|
7
7
|
|
8
8
|
s.authors = ["Peter Boling", "Evan Dorn", "Judson Lester", "Bryan Helmkamp"]
|
9
|
-
s.email = %w{peter.boling@gmail.com
|
9
|
+
s.email = %w{peter.boling@gmail.com}
|
10
10
|
s.extra_rdoc_files = [
|
11
11
|
"README.md",
|
12
12
|
"LICENSE",
|
@@ -18,6 +18,9 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
+
s.licenses = ["MIT"]
|
22
|
+
s.platform = Gem::Platform::RUBY
|
23
|
+
|
21
24
|
s.homepage = "https://github.com/pboling/rack-insight"
|
22
25
|
s.summary = %q{Debugging toolbar for Rack applications implemented as
|
23
26
|
middleware.}
|
@@ -27,13 +30,13 @@ Gem::Specification.new do |s|
|
|
27
30
|
s.add_runtime_dependency("rack")
|
28
31
|
s.add_runtime_dependency("uuidtools", ">= 2.1.2") # incurs far fewer dependencies that the uuid gem, and no shell forking
|
29
32
|
s.add_runtime_dependency("sqlite3", ">= 1.3.3")
|
30
|
-
s.add_development_dependency "redcarpet"
|
31
|
-
s.add_development_dependency(%q<reek>, [">= 1.2.
|
32
|
-
s.add_development_dependency(%q<roodi>, [">= 2.
|
33
|
-
s.add_development_dependency(%q<rake>, [">= 0"])
|
34
|
-
s.add_development_dependency "rspec", ">= 2.
|
35
|
-
s.add_development_dependency "sinatra"
|
36
|
-
s.add_development_dependency "webrat"
|
37
|
-
s.add_development_dependency "debugger", ">= 1.
|
38
|
-
s.add_development_dependency "gem-release", ">= 0.
|
33
|
+
#s.add_development_dependency "redcarpet", ">= 3.0.0"
|
34
|
+
s.add_development_dependency(%q<reek>, [">= 1.2.13"])
|
35
|
+
s.add_development_dependency(%q<roodi>, [">= 2.2.0"])
|
36
|
+
s.add_development_dependency(%q<rake>, [">= 10.1.0"])
|
37
|
+
s.add_development_dependency "rspec", ">= 2.14.1"
|
38
|
+
s.add_development_dependency "sinatra", ">= 1.4.3"
|
39
|
+
s.add_development_dependency "webrat", ">= 0.7.3"
|
40
|
+
#s.add_development_dependency "debugger", ">= 1.6.1"
|
41
|
+
s.add_development_dependency "gem-release", ">= 0.6.0"
|
39
42
|
end
|
data/spec/insight_spec.rb
CHANGED
@@ -142,22 +142,25 @@ describe Rack::Insight do
|
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
145
|
+
# These specs are no longer applicable, since reset_insight no longer clears the sqlite database.
|
146
|
+
# Clearing of the database is now accomplished in a *config.after :suite do* block
|
147
|
+
|
148
|
+
#context "configured with a SQLite database file path" do
|
149
|
+
# before do
|
150
|
+
# # We need to pass the SQLite database file path to the gem
|
151
|
+
# require 'fileutils'
|
152
|
+
# FileUtils.rm_rf("my_custom_db_path.sqlite") #because it doesn't count if it's already there
|
153
|
+
# reset_insight :database_path => 'my_custom_db_path.sqlite'
|
154
|
+
# end
|
155
|
+
#
|
156
|
+
# it "should create a database at the path specified in the options" do
|
157
|
+
# File.exist?('my_custom_db_path.sqlite').should be_true
|
158
|
+
# end
|
159
|
+
#
|
160
|
+
# after do
|
161
|
+
# FileUtils.rm_rf("my_custom_db_path.sqlite")
|
162
|
+
# reset_insight :database_path => nil
|
163
|
+
# end
|
164
|
+
#
|
165
|
+
#end
|
163
166
|
end
|
@@ -35,14 +35,57 @@ class Two < One
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
class Probeable
|
39
|
+
include Rack::Insight::Instrumentation::Client
|
40
|
+
class << self
|
41
|
+
include Rack::Insight::Instrumentation::EigenClient
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module MyEigenClient;
|
46
|
+
def self.included(base)
|
47
|
+
base.send(:attr_accessor, :is_probed)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
module MyClient; def probe; "anal probe is #{self.class.is_probed}"; end; end
|
51
|
+
class MyPanel; include MyClient; class << self; include MyEigenClient; end; end
|
52
|
+
class MyPanel2; include MyClient; class << self; include MyEigenClient; end; end
|
53
|
+
|
54
|
+
describe "Validate Client Design" do
|
55
|
+
it "MyPanel instance should respond to probe" do
|
56
|
+
MyPanel.new.respond_to?(:probe).should be_true
|
57
|
+
end
|
58
|
+
it "MyPanel#probe should return 'anal_probe is '" do
|
59
|
+
MyPanel.new.probe.should == 'anal probe is '
|
60
|
+
end
|
61
|
+
it "MyPanel class should respond to is_probed" do
|
62
|
+
MyPanel.respond_to?(:is_probed).should be_true
|
63
|
+
end
|
64
|
+
it "MyPanel.is_probed should default to nil" do
|
65
|
+
MyPanel.is_probed.should == nil
|
66
|
+
end
|
67
|
+
it "MyPanel.is_probed should be settable" do
|
68
|
+
MyPanel.is_probed = 'fat mojo'
|
69
|
+
MyPanel.is_probed.should == 'fat mojo'
|
70
|
+
MyPanel.new.probe.should == 'anal probe is fat mojo'
|
71
|
+
end
|
72
|
+
it "MyPanel2.is_probed should not interfere with MyPanel.is_probed" do
|
73
|
+
MyPanel.is_probed = 'fat mojo'
|
74
|
+
MyPanel2.is_probed = 'nice banana'
|
75
|
+
MyPanel.is_probed.should == 'fat mojo'
|
76
|
+
MyPanel2.is_probed.should == 'nice banana'
|
77
|
+
MyPanel.new.probe.should == 'anal probe is fat mojo'
|
78
|
+
MyPanel2.new.probe.should == 'anal probe is nice banana'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
38
82
|
describe "Setting up probes" do
|
39
83
|
let :method_calls do [] end
|
40
84
|
let :method_subject do [] end
|
41
85
|
let :recording_list do [] end
|
42
86
|
|
43
87
|
let :test_collector do
|
44
|
-
collector =
|
45
|
-
collector.extend Rack::Insight::Instrumentation::Client
|
88
|
+
collector = Probeable.new
|
46
89
|
collector.instance_variable_set("@calls", method_calls)
|
47
90
|
def collector.after_detect(method_call, timing, arguments, results)
|
48
91
|
@calls << [method_call, timing, arguments, results]
|
@@ -5,14 +5,14 @@ module Rack::Insight
|
|
5
5
|
describe "ActiveRecordPanel" do
|
6
6
|
before do
|
7
7
|
mock_constant("ActiveRecord::Base")
|
8
|
-
reset_insight :
|
8
|
+
reset_insight :panel_classes => [Rack::Insight::ActiveRecordPanel]
|
9
9
|
end
|
10
10
|
|
11
11
|
def mock_model(name)
|
12
|
-
model =
|
13
|
-
model.stub
|
14
|
-
obj =
|
15
|
-
obj.stub
|
12
|
+
model = double("model")
|
13
|
+
model.stub(:name => name)
|
14
|
+
obj = double(name)
|
15
|
+
obj.stub(:base_class => model)
|
16
16
|
obj
|
17
17
|
end
|
18
18
|
|
@@ -36,8 +36,8 @@ module Rack::Insight
|
|
36
36
|
mock_method_call("ActiveRecord::Base", "allocate", [], :class, mock_model("Group"))
|
37
37
|
end
|
38
38
|
response = get_via_rack "/"
|
39
|
-
response.should have_row("#
|
40
|
-
response.should have_row("#
|
39
|
+
response.should have_row("#ActiveRecordPanel", "User", "2")
|
40
|
+
response.should have_row("#ActiveRecordPanel", "Group", "1")
|
41
41
|
end
|
42
42
|
end
|
43
43
|
end
|
@@ -8,10 +8,10 @@ module Rack::Insight
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def mock_model(name)
|
11
|
-
model =
|
12
|
-
model.stub
|
13
|
-
obj =
|
14
|
-
obj.stub
|
11
|
+
model = double("model")
|
12
|
+
model.stub(:name => name)
|
13
|
+
obj = double(name)
|
14
|
+
obj.stub(:base_class => model)
|
15
15
|
obj
|
16
16
|
end
|
17
17
|
|
@@ -122,7 +122,7 @@ module Rack::Insight
|
|
122
122
|
|
123
123
|
describe "expire_all" do
|
124
124
|
it "expires the cache keys" do
|
125
|
-
Rails.stub
|
125
|
+
Rails.stub(:cache => double("cache"))
|
126
126
|
Rails.cache.should_receive(:delete).with("user:1")
|
127
127
|
Rails.cache.should_receive(:delete).with("user:2")
|
128
128
|
Rails.cache.should_receive(:delete).with("user:3")
|
@@ -134,7 +134,7 @@ module Rack::Insight
|
|
134
134
|
end
|
135
135
|
|
136
136
|
it "returns OK" do
|
137
|
-
Rails.stub
|
137
|
+
Rails.stub(:cache => double("cache", :delete => nil))
|
138
138
|
response = get_via_rack "/__insight__/delete_cache_list",
|
139
139
|
:keys_1 => "user:1", :keys_2 => "user:2", :keys_3 => "user:3", :keys_4 => "user:4",
|
140
140
|
:hash => Digest::SHA1.hexdigest("abc:user:1:user:2:user:3:user:4")
|
@@ -144,14 +144,14 @@ module Rack::Insight
|
|
144
144
|
|
145
145
|
describe "expire" do
|
146
146
|
it "expires the cache key" do
|
147
|
-
Rails.stub
|
147
|
+
Rails.stub(:cache => double("cache"))
|
148
148
|
Rails.cache.should_receive(:delete).with("user:1")
|
149
149
|
get_via_rack "/__insight__/delete_cache", :key => "user:1",
|
150
150
|
:hash => Digest::SHA1.hexdigest("abc:user:1")
|
151
151
|
end
|
152
152
|
|
153
153
|
it "returns OK" do
|
154
|
-
Rails.stub
|
154
|
+
Rails.stub(:cache => double("cache", :delete => nil))
|
155
155
|
response = get_via_rack "/__insight__/delete_cache", :key => "user:1",
|
156
156
|
:hash => Digest::SHA1.hexdigest("abc:user:1")
|
157
157
|
response.should contain("OK")
|
@@ -160,14 +160,14 @@ module Rack::Insight
|
|
160
160
|
|
161
161
|
describe "view_cache" do
|
162
162
|
it "renders the cache key" do
|
163
|
-
Rails.stub
|
163
|
+
Rails.stub(:cache => double("cache", :read => "cache body"))
|
164
164
|
response = get_via_rack "/__insight__/view_cache", :key => "user:1",
|
165
165
|
:hash => Digest::SHA1.hexdigest("abc:user:1")
|
166
166
|
response.should contain("cache body")
|
167
167
|
end
|
168
168
|
|
169
169
|
it "renders non-String cache values properly" do
|
170
|
-
Rails.stub
|
170
|
+
Rails.stub(:cache => double("cache", :read => [1, 2]))
|
171
171
|
response = get_via_rack "/__insight__/view_cache", :key => "user:1",
|
172
172
|
:hash => Digest::SHA1.hexdigest("abc:user:1")
|
173
173
|
response.should contain("[1, 2]")
|
@@ -14,21 +14,19 @@ module Rack::Insight
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
describe "content" do
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
17
|
+
#describe "content" do
|
18
|
+
# it "displays recorded log lines" do
|
19
|
+
# Rack::Insight::Config.logger.fatal("This is a logged message")
|
20
|
+
# response = get_via_rack "/"
|
21
|
+
# response.should contain("This is a logged message")
|
22
|
+
# response.should contain("DEBUG")
|
23
|
+
# end
|
24
|
+
#end
|
27
25
|
|
28
26
|
describe "Extended Logger" do
|
29
27
|
it "does still return true/false for #add if class Logger" do
|
30
28
|
#AS::BufferedLogger returns the added string, Logger returns true/false
|
31
|
-
LOGGER.add(0, "foo").should
|
29
|
+
LOGGER.add(0, "foo").should == true
|
32
30
|
end
|
33
31
|
end
|
34
32
|
|
@@ -7,12 +7,12 @@ module Rack::Insight
|
|
7
7
|
mock_constant("Rails::Info")
|
8
8
|
reset_insight :panel_classes => [Rack::Insight::RailsInfoPanel]
|
9
9
|
|
10
|
-
Rails::Info.stub
|
10
|
+
Rails::Info.stub(:properties => [])
|
11
11
|
end
|
12
12
|
|
13
13
|
describe "heading" do
|
14
14
|
it "displays the Rails version" do
|
15
|
-
Rails.stub
|
15
|
+
Rails.stub(:version => "v2.3.0")
|
16
16
|
response = get_via_rack "/"
|
17
17
|
response.should have_heading("Rails v2.3.0")
|
18
18
|
end
|
@@ -20,10 +20,10 @@ module Rack::Insight
|
|
20
20
|
|
21
21
|
describe "content" do
|
22
22
|
it "displays the Rails::Info properties" do
|
23
|
-
Rails.stub
|
24
|
-
Rails::Info.stub
|
23
|
+
Rails.stub(:version => "v2.3.0")
|
24
|
+
Rails::Info.stub(:properties => [["CaptainKirkIs", "ClimbingTheMountain"]])
|
25
25
|
response = get_via_rack "/"
|
26
|
-
response.should have_row("#
|
26
|
+
response.should have_row("#RailsInfoPanel", "CaptainKirkIs", "ClimbingTheMountain")
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|