oink 0.1.2 → 0.9.1
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.
- data/README.rdoc +15 -29
- data/Rakefile +4 -6
- data/bin/oink +2 -2
- data/lib/oink.rb +1 -9
- data/lib/oink/cli.rb +71 -67
- data/lib/oink/instrumentation.rb +2 -0
- data/lib/oink/instrumentation/active_record.rb +63 -0
- data/lib/oink/instrumentation/memory_snapshot.rb +119 -0
- data/lib/oink/middleware.rb +48 -0
- data/lib/oink/rails/instance_type_counter.rb +8 -62
- data/lib/oink/rails/memory_usage_logger.rb +11 -33
- data/lib/oink/reports/active_record_instantiation_oinked_request.rb +13 -0
- data/lib/oink/reports/active_record_instantiation_report.rb +67 -0
- data/lib/oink/reports/base.rb +38 -0
- data/lib/oink/reports/memory_oinked_request.rb +13 -0
- data/lib/oink/reports/memory_usage_report.rb +71 -0
- data/lib/oink/reports/priority_queue.rb +41 -0
- data/lib/oink/reports/request.rb +20 -0
- data/lib/oink/utils/hash_utils.rb +9 -0
- data/spec/fakes/fake_application_controller.rb +30 -0
- data/spec/fakes/psuedo_output.rb +7 -0
- data/spec/helpers/database.rb +20 -0
- data/spec/{rails → oink/instrumentation}/instance_type_counter_spec.rb +11 -9
- data/spec/oink/instrumentation/memory_snapshot_spec.rb +84 -0
- data/spec/oink/middleware_spec.rb +73 -0
- data/spec/oink/rails/instance_type_counter_spec.rb +52 -0
- data/spec/oink/rails/memory_usage_logger_spec.rb +23 -0
- data/spec/oink/reports/active_record_instantiation_report_spec.rb +193 -0
- data/spec/oink/reports/memory_usage_report_spec.rb +267 -0
- data/spec/oink/reports/oinked_request_spec.rb +22 -0
- data/spec/oink/reports/priority_queue_spec.rb +74 -0
- data/spec/spec_helper.rb +10 -26
- metadata +158 -29
- data/lib/oink/active_record_instantiation_reporter.rb +0 -68
- data/lib/oink/base.rb +0 -40
- data/lib/oink/memory_usage_reporter.rb +0 -72
- data/lib/oink/oinked_request/oinked_ar_request.rb +0 -9
- data/lib/oink/oinked_request/oinked_memory_request.rb +0 -9
- data/lib/oink/oinked_request/oinked_request.rb +0 -16
- data/lib/oink/priority_queue.rb +0 -37
- data/spec/oink/active_record_instantiation_reporter_spec.rb +0 -191
- data/spec/oink/memory_usage_reporter_spec.rb +0 -265
- data/spec/oinked_request/oinked_request_spec.rb +0 -20
- data/spec/priority_queue/priority_queue_spec.rb +0 -75
- data/spec/rails/memory_usage_logger_spec.rb +0 -87
@@ -0,0 +1,20 @@
|
|
1
|
+
module Oink
|
2
|
+
module Reports
|
3
|
+
class Request
|
4
|
+
include Comparable
|
5
|
+
|
6
|
+
attr_accessor :action, :datetime, :log_lines, :oink_number
|
7
|
+
|
8
|
+
def initialize(action, datetime, log_lines, oink_number)
|
9
|
+
@action = action
|
10
|
+
@datetime = datetime
|
11
|
+
@log_lines = log_lines
|
12
|
+
@oink_number = oink_number
|
13
|
+
end
|
14
|
+
|
15
|
+
def <=>(other)
|
16
|
+
self.oink_number <=> other.oink_number
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class FakeApplicationController
|
2
|
+
|
3
|
+
def initialize(logger = Logger.new(StringIO.new))
|
4
|
+
@logger = logger
|
5
|
+
end
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :around_filters
|
9
|
+
|
10
|
+
def around_filter method
|
11
|
+
(@around_filters ||= []) << method
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def index
|
16
|
+
run_around_filters
|
17
|
+
end
|
18
|
+
|
19
|
+
def logger
|
20
|
+
@logger
|
21
|
+
end
|
22
|
+
|
23
|
+
protected
|
24
|
+
def run_around_filters
|
25
|
+
self.class.around_filters.each { |filter| self.send(filter) { perform_action } }
|
26
|
+
end
|
27
|
+
|
28
|
+
def perform_action
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
def setup_memory_database
|
4
|
+
ActiveRecord::Base.establish_connection(
|
5
|
+
:adapter => 'sqlite3',
|
6
|
+
:database => ':memory:'
|
7
|
+
)
|
8
|
+
|
9
|
+
ActiveRecord::Schema.define(:version => 1) do
|
10
|
+
create_table "pigs", :force => true do |t|
|
11
|
+
t.integer "pen_id"
|
12
|
+
t.string "name"
|
13
|
+
t.boolean "smells"
|
14
|
+
end
|
15
|
+
|
16
|
+
create_table "pens", :force => true do |t|
|
17
|
+
t.string "location"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,36 +1,38 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + "
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
2
|
|
3
|
-
describe Oink::
|
4
|
-
before
|
3
|
+
describe Oink::Instrumentation::ActiveRecord do
|
4
|
+
before do
|
5
5
|
ActiveRecord::Base.reset_instance_type_count
|
6
|
+
Pig.delete_all
|
7
|
+
Pen.delete_all
|
6
8
|
end
|
7
|
-
|
9
|
+
|
8
10
|
describe "hash" do
|
9
11
|
it "should not count objects not instantiated" do
|
10
12
|
ActiveRecord::Base.instantiated_hash["Pig"].should == nil
|
11
13
|
end
|
12
|
-
|
14
|
+
|
13
15
|
it "should include the objects instantiated" do
|
14
16
|
Pig.create(:name => "Babe")
|
15
17
|
Pig.first
|
16
18
|
ActiveRecord::Base.instantiated_hash["Pig"].should == 2
|
17
19
|
end
|
18
|
-
|
20
|
+
|
19
21
|
it "should count instantiations for multiple classes" do
|
20
22
|
Pig.create(:name => "Babe")
|
21
23
|
Pen.create(:location => "Backyard")
|
22
24
|
Pig.first
|
23
25
|
ActiveRecord::Base.instantiated_hash["Pen"].should == 1
|
24
26
|
end
|
25
|
-
|
27
|
+
|
26
28
|
it "should report the total number of objects instantiated" do
|
27
29
|
Pig.create(:name => "Babe")
|
28
30
|
Pen.create(:location => "Backyard")
|
29
31
|
Pig.first
|
30
32
|
ActiveRecord::Base.total_objects_instantiated.should == 3
|
31
|
-
end
|
33
|
+
end
|
32
34
|
end
|
33
|
-
|
35
|
+
|
34
36
|
describe "reset" do
|
35
37
|
it "should reset the total count" do
|
36
38
|
Pig.create(:name => "Babe")
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
|
+
|
3
|
+
module Oink
|
4
|
+
module Instrumentation
|
5
|
+
|
6
|
+
describe StatmMemorySnapshot do
|
7
|
+
|
8
|
+
before do
|
9
|
+
StatmMemorySnapshot.unset_statm_page_size
|
10
|
+
end
|
11
|
+
|
12
|
+
it "returns memory when pagesize is 4096" do
|
13
|
+
pages = 6271
|
14
|
+
statm_file = "#{pages} 1157 411 1 0 763 0\n"
|
15
|
+
File.should_receive(:read).with("/proc/self/statm").and_return(statm_file)
|
16
|
+
|
17
|
+
system_call = mock(SystemCall, :stdout => "4096\n", :success? => true)
|
18
|
+
SystemCall.should_receive(:execute).with('getconf PAGESIZE').and_return(system_call)
|
19
|
+
StatmMemorySnapshot.new.memory.should == (pages * 4)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "falls back to a 4096 if getconf PAGESIZE is not available" do
|
23
|
+
pages = 6271
|
24
|
+
statm_file = "#{pages} 1157 411 1 0 763 0\n"
|
25
|
+
File.should_receive(:read).with("/proc/self/statm").and_return(statm_file)
|
26
|
+
system_call = mock(SystemCall, :stdout => "", :success? => false)
|
27
|
+
SystemCall.should_receive(:execute).with('getconf PAGESIZE').and_return(system_call)
|
28
|
+
StatmMemorySnapshot.new.memory.should == (pages * 4)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe SmapsMemorySnapshot do
|
33
|
+
|
34
|
+
it "returns a sum of the sizes in the /proc/$$/smaps file" do
|
35
|
+
proc_file = <<-STR
|
36
|
+
Header
|
37
|
+
|
38
|
+
Size: 25
|
39
|
+
Size: 13 trailing
|
40
|
+
|
41
|
+
leading Size: 4
|
42
|
+
|
43
|
+
Footer
|
44
|
+
|
45
|
+
STR
|
46
|
+
File.should_receive(:new).with("/proc/#{$$}/smaps").and_return(proc_file)
|
47
|
+
SmapsMemorySnapshot.new.memory.should == 42
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe ProcessStatusMemorySnapshot do
|
53
|
+
it "returns the result of a PS command" do
|
54
|
+
system_call = mock(SystemCall, :stdout => "915")
|
55
|
+
SystemCall.should_receive(:execute).with("ps -o vsz= -p #{$$}").and_return(system_call)
|
56
|
+
ProcessStatusMemorySnapshot.new.memory.should == 915
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#available?" do
|
60
|
+
it "returns true if ps succeeds" do
|
61
|
+
system_call = mock(SystemCall, :success? => true)
|
62
|
+
SystemCall.should_receive(:execute).with("ps -o vsz= -p #{$$}").and_return(system_call)
|
63
|
+
ProcessStatusMemorySnapshot.available?.should be_true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe MemorySnapshot do
|
69
|
+
describe "#memory_snapshot_class" do
|
70
|
+
it "raises an Oink::MemoryDataUnavailableError if not strategies can be found" do
|
71
|
+
[WindowsMemorySnapshot, StatmMemorySnapshot, SmapsMemorySnapshot, ProcessStatusMemorySnapshot].each { |klass| klass.stub(:available? => false) }
|
72
|
+
|
73
|
+
lambda { MemorySnapshot.memory_snapshot_class }.should raise_error(MemoryDataUnavailableError)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "returns the first available memory snapshot strategy" do
|
77
|
+
[WindowsMemorySnapshot, SmapsMemorySnapshot, ProcessStatusMemorySnapshot].each { |klass| klass.stub(:available? => false) }
|
78
|
+
StatmMemorySnapshot.stub(:available? => true)
|
79
|
+
MemorySnapshot.memory_snapshot_class.should == StatmMemorySnapshot
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
require "oink/middleware"
|
3
|
+
require 'rack/test'
|
4
|
+
|
5
|
+
describe Oink::Middleware do
|
6
|
+
include Rack::Test::Methods
|
7
|
+
|
8
|
+
class SampleApplication
|
9
|
+
def call(env)
|
10
|
+
case env['PATH_INFO']
|
11
|
+
when "/no_pigs"
|
12
|
+
when "/two_pigs"
|
13
|
+
Pig.create(:name => "Babe")
|
14
|
+
Pig.first
|
15
|
+
when "/two_pigs_in_a_pen"
|
16
|
+
Pig.create(:name => "Babe")
|
17
|
+
Pen.create(:location => "Backyard")
|
18
|
+
Pig.first
|
19
|
+
end
|
20
|
+
[200, {}, ""]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:app) { Oink::Middleware.new(SampleApplication.new) }
|
25
|
+
|
26
|
+
before do
|
27
|
+
@log_output = StringIO.new
|
28
|
+
Hodel3000CompliantLogger.stub(:new => Hodel3000CompliantLogger.new(@log_output))
|
29
|
+
Oink::Instrumentation::MemorySnapshot.stub(:memory => 4092)
|
30
|
+
Pig.delete_all
|
31
|
+
Pen.delete_all
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
context "support legacy rails log format in transition to oink's own log format" do
|
36
|
+
it "writes rails[pid] to the log even if the app isn't a rails app (for now)" do
|
37
|
+
get "/no_pigs"
|
38
|
+
@log_output.string.should include("rails[#{$$}]")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "writes 'Completed in' after the request has completed" do
|
42
|
+
get "/no_pigs"
|
43
|
+
@log_output.string.should include("Completed in")
|
44
|
+
end
|
45
|
+
|
46
|
+
it "logs the action and controller" do
|
47
|
+
get "/no_pigs", {}, {'action_dispatch.request.parameters' => {'controller' => 'oinkoink', 'action' => 'piggie'}}
|
48
|
+
@log_output.string.should include("Processing oinkoink#piggie")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it "reports 0 totals" do
|
53
|
+
get "/no_pigs"
|
54
|
+
@log_output.string.should include("Instantiation Breakdown: Total: 0")
|
55
|
+
end
|
56
|
+
|
57
|
+
it "reports totals first even if it's a tie" do
|
58
|
+
get "/two_pigs"
|
59
|
+
@log_output.string.should include("Instantiation Breakdown: Total: 2 | Pig: 2")
|
60
|
+
end
|
61
|
+
|
62
|
+
it "reports pigs and pens instantiated" do
|
63
|
+
get "/two_pigs_in_a_pen"
|
64
|
+
@log_output.string.should include("Instantiation Breakdown: Total: 3 | Pig: 2 | Pen: 1")
|
65
|
+
end
|
66
|
+
|
67
|
+
it "logs memory usage" do
|
68
|
+
Oink::Instrumentation::MemorySnapshot.should_receive(:memory).and_return(4092)
|
69
|
+
get "/two_pigs_in_a_pen"
|
70
|
+
@log_output.string.should include("Memory usage: 4092 | PID: #{$$}")
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
|
+
|
3
|
+
class ARCountApplicationController < FakeApplicationController
|
4
|
+
include Oink::InstanceTypeCounter
|
5
|
+
|
6
|
+
def no_pigs
|
7
|
+
run_around_filters
|
8
|
+
end
|
9
|
+
|
10
|
+
def two_pigs_in_a_pen
|
11
|
+
Pig.create!
|
12
|
+
Pig.create!
|
13
|
+
Pen.create!
|
14
|
+
run_around_filters
|
15
|
+
end
|
16
|
+
|
17
|
+
def two_pigs
|
18
|
+
Pig.create!
|
19
|
+
Pig.create!
|
20
|
+
run_around_filters
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
describe Oink::InstanceTypeCounter do
|
26
|
+
|
27
|
+
before do
|
28
|
+
Pig.delete_all
|
29
|
+
Pen.delete_all
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:log_output) { StringIO.new }
|
33
|
+
let(:logger) { Logger.new(log_output) }
|
34
|
+
|
35
|
+
it "reports no AR objects instantiated" do
|
36
|
+
controller = ARCountApplicationController.new(logger)
|
37
|
+
controller.no_pigs
|
38
|
+
log_output.string.should include("Instantiation Breakdown: Total: 0")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "reports AR objects instantiated by type" do
|
42
|
+
controller = ARCountApplicationController.new(logger)
|
43
|
+
controller.two_pigs_in_a_pen
|
44
|
+
log_output.string.should include("Instantiation Breakdown: Total: 3 | Pig: 2 | Pen: 1")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "reports totals first even if its a tie" do
|
48
|
+
controller = ARCountApplicationController.new(logger)
|
49
|
+
controller.two_pigs
|
50
|
+
log_output.string.should include("Instantiation Breakdown: Total: 2 | Pig: 2")
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
|
+
|
3
|
+
class MemoryLoggerApplicationController < FakeApplicationController
|
4
|
+
include Oink::MemoryUsageLogger
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Oink::MemoryUsageLogger do
|
8
|
+
it "should return memory usage info from the snapshot" do
|
9
|
+
Oink::Instrumentation::MemorySnapshot.should_receive("memory").and_return(42)
|
10
|
+
log_output = StringIO.new
|
11
|
+
controller = MemoryLoggerApplicationController.new(Logger.new(log_output))
|
12
|
+
controller.index
|
13
|
+
log_output.string.should include("Memory usage: 42 | PID: #{$$}")
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should log an error message if cannot find a memory snapshot strategy" do
|
17
|
+
Oink::Instrumentation::MemorySnapshot.should_receive("memory").and_raise(Oink::Instrumentation::MemoryDataUnavailableError)
|
18
|
+
controller = MemoryLoggerApplicationController.new
|
19
|
+
lambda {
|
20
|
+
controller.index
|
21
|
+
}.should_not raise_error
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
2
|
+
|
3
|
+
module Oink::Reports
|
4
|
+
describe ActiveRecordInstantiationReport do
|
5
|
+
|
6
|
+
describe "short summary with frequent offenders" do
|
7
|
+
|
8
|
+
it "should report actions which exceed the threshold once" do
|
9
|
+
str = <<-STR
|
10
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
11
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 51 | User: 51
|
12
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
13
|
+
STR
|
14
|
+
|
15
|
+
io = StringIO.new(str)
|
16
|
+
output = PsuedoOutput.new
|
17
|
+
ActiveRecordInstantiationReport.new(io, 50).print(output)
|
18
|
+
output.should include("1, Users#show")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should not report actions which do not exceed the threshold" do
|
22
|
+
str = <<-STR
|
23
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
24
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 50 | User: 50
|
25
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
26
|
+
STR
|
27
|
+
|
28
|
+
io = StringIO.new(str)
|
29
|
+
output = PsuedoOutput.new
|
30
|
+
ActiveRecordInstantiationReport.new(io, 50).print(output)
|
31
|
+
output.should_not include("1, Users#show")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should report actions which exceed the threshold multiple times" do
|
35
|
+
str = <<-STR
|
36
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
37
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 51 | User: 51
|
38
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
39
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
40
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 51 | User: 51
|
41
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
42
|
+
STR
|
43
|
+
|
44
|
+
io = StringIO.new(str)
|
45
|
+
output = PsuedoOutput.new
|
46
|
+
ActiveRecordInstantiationReport.new(io, 50).print(output)
|
47
|
+
output.should include("2, Users#show")
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should order actions by most exceeded" do
|
51
|
+
str = <<-STR
|
52
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Media#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
53
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 51 | User: 51
|
54
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
55
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Media#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
56
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 51 | User: 51
|
57
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
58
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
59
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 51 | User: 51
|
60
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
61
|
+
STR
|
62
|
+
|
63
|
+
io = StringIO.new(str)
|
64
|
+
output = PsuedoOutput.new
|
65
|
+
ActiveRecordInstantiationReport.new(io, 50).print(output)
|
66
|
+
output[-2].should == "2, Media#show"
|
67
|
+
output[-1].should == "1, Users#show"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should not be bothered by incomplete requests" do
|
71
|
+
str = <<-STR
|
72
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Media#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
73
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 24 | User: 24
|
74
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
75
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Media#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
76
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
77
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 51 | User: 51
|
78
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
79
|
+
STR
|
80
|
+
|
81
|
+
io = StringIO.new(str)
|
82
|
+
output = PsuedoOutput.new
|
83
|
+
ActiveRecordInstantiationReport.new(io, 50).print(output)
|
84
|
+
output.should include("1, Users#show")
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
describe "summary with top 10 offenses" do
|
90
|
+
|
91
|
+
it "should only report requests over threshold" do
|
92
|
+
str = <<-STR
|
93
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
94
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 51 | User: 51
|
95
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
96
|
+
STR
|
97
|
+
|
98
|
+
io = StringIO.new(str)
|
99
|
+
output = PsuedoOutput.new
|
100
|
+
ActiveRecordInstantiationReport.new(io, 50).print(output)
|
101
|
+
output.should include("1. Feb 01 01:58:31, 51, Users#show")
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should not include requests which are not over threshold" do
|
105
|
+
str = <<-STR
|
106
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
107
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 50 | User: 50
|
108
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
109
|
+
STR
|
110
|
+
|
111
|
+
io = StringIO.new(str)
|
112
|
+
output = PsuedoOutput.new
|
113
|
+
ActiveRecordInstantiationReport.new(io, 50).print(output)
|
114
|
+
output.should_not include("1. Feb 01 01:58:31, 50, Users#show")
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should order offenses from biggest to smallest" do
|
118
|
+
str = <<-STR
|
119
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing DetailsController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
120
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 75 | User: 75
|
121
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
122
|
+
Feb 01 01:58:32 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
123
|
+
Feb 01 01:58:33 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 100 | User: 100
|
124
|
+
Feb 01 01:58:34 ey04-s00297 rails[4413]: Completed in
|
125
|
+
STR
|
126
|
+
|
127
|
+
io = StringIO.new(str)
|
128
|
+
output = PsuedoOutput.new
|
129
|
+
ActiveRecordInstantiationReport.new(io, 50).print(output)
|
130
|
+
output[4].should == "1. Feb 01 01:58:34, 100, MediaController#show"
|
131
|
+
output[5].should == "2. Feb 01 01:58:31, 75, DetailsController#show"
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "verbose format" do
|
137
|
+
it "should print the full lines of actions exceeding the threshold" do
|
138
|
+
str = <<-STR
|
139
|
+
Feb 01 01:58:32 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
140
|
+
Feb 01 01:58:33 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 100 | User: 100
|
141
|
+
Feb 01 01:58:34 ey04-s00297 rails[4413]: Completed in
|
142
|
+
STR
|
143
|
+
io = StringIO.new(str)
|
144
|
+
output = PsuedoOutput.new
|
145
|
+
ActiveRecordInstantiationReport.new(io, 50, :format => :verbose).print(output)
|
146
|
+
output[3..5].should == str.split("\n")[0..2].map { |o| o.strip }
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should handle actions which do not complete properly" do
|
150
|
+
str = <<-STR
|
151
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Media#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
152
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 24 | User: 24
|
153
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
154
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Media#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
155
|
+
Feb 01 01:58:29 ey04-s00297 rails[4413]: Processing Users#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
156
|
+
Feb 01 01:58:30 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 51 | User: 51
|
157
|
+
Feb 01 01:58:31 ey04-s00297 rails[4413]: Completed in
|
158
|
+
STR
|
159
|
+
|
160
|
+
io = StringIO.new(str)
|
161
|
+
output = PsuedoOutput.new
|
162
|
+
ActiveRecordInstantiationReport.new(io, 50, :format => :verbose).print(output)
|
163
|
+
output[3..5].should == str.split("\n")[4..6].map { |o| o.strip }
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe "multiple io streams" do
|
168
|
+
it "should accept multiple files" do
|
169
|
+
|
170
|
+
str1 = <<-STR
|
171
|
+
Feb 01 01:58:32 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
172
|
+
Feb 01 01:58:33 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 100 | User: 100
|
173
|
+
Feb 01 01:58:34 ey04-s00297 rails[4413]: Completed in
|
174
|
+
STR
|
175
|
+
|
176
|
+
str2 = <<-STR
|
177
|
+
Feb 01 01:58:32 ey04-s00297 rails[4413]: Processing MediaController#show (for 92.84.151.171 at 2009-02-01 01:58:29) [GET]
|
178
|
+
Feb 01 01:58:33 ey04-s00297 rails[4413]: Instantiation Breakdown: Total: 100 | User: 100
|
179
|
+
Feb 01 01:58:34 ey04-s00297 rails[4413]: Completed in
|
180
|
+
STR
|
181
|
+
|
182
|
+
io1 = StringIO.new(str1)
|
183
|
+
io2 = StringIO.new(str2)
|
184
|
+
output = PsuedoOutput.new
|
185
|
+
ActiveRecordInstantiationReport.new([io1, io2], 50).print(output)
|
186
|
+
output.should include("2, MediaController#show")
|
187
|
+
end
|
188
|
+
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|