request-log-analyzer 1.0.2 → 1.6.3
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/.gitignore +10 -0
- data/DESIGN.rdoc +41 -0
- data/LICENSE +4 -4
- data/README.rdoc +38 -0
- data/Rakefile +6 -3
- data/bin/request-log-analyzer +70 -72
- data/lib/cli/command_line_arguments.rb +53 -53
- data/lib/cli/database_console.rb +26 -0
- data/lib/cli/database_console_init.rb +43 -0
- data/lib/cli/progressbar.rb +166 -189
- data/lib/cli/tools.rb +49 -0
- data/lib/request_log_analyzer/aggregator/database_inserter.rb +83 -0
- data/lib/request_log_analyzer/aggregator/echo.rb +17 -12
- data/lib/request_log_analyzer/aggregator/summarizer.rb +101 -63
- data/lib/request_log_analyzer/{aggregator/base.rb → aggregator.rb} +17 -13
- data/lib/request_log_analyzer/controller.rb +251 -98
- data/lib/request_log_analyzer/database/base.rb +114 -0
- data/lib/request_log_analyzer/database/connection.rb +38 -0
- data/lib/request_log_analyzer/database/request.rb +22 -0
- data/lib/request_log_analyzer/database/source.rb +13 -0
- data/lib/request_log_analyzer/database/warning.rb +14 -0
- data/lib/request_log_analyzer/database.rb +102 -0
- data/lib/request_log_analyzer/file_format/amazon_s3.rb +74 -0
- data/lib/request_log_analyzer/file_format/apache.rb +147 -0
- data/lib/request_log_analyzer/file_format/delayed_job.rb +55 -0
- data/lib/request_log_analyzer/file_format/merb.rb +65 -29
- data/lib/request_log_analyzer/file_format/mysql.rb +101 -0
- data/lib/request_log_analyzer/file_format/postgresql.rb +68 -0
- data/lib/request_log_analyzer/file_format/rack.rb +9 -0
- data/lib/request_log_analyzer/file_format/rails.rb +164 -78
- data/lib/request_log_analyzer/file_format/rails3.rb +86 -0
- data/lib/request_log_analyzer/file_format/rails_development.rb +12 -0
- data/lib/request_log_analyzer/file_format.rb +252 -58
- data/lib/request_log_analyzer/filter/anonymize.rb +39 -0
- data/lib/request_log_analyzer/filter/field.rb +19 -13
- data/lib/request_log_analyzer/filter/timespan.rb +25 -12
- data/lib/request_log_analyzer/filter.rb +30 -0
- data/lib/request_log_analyzer/line_definition.rb +69 -96
- data/lib/request_log_analyzer/log_processor.rb +31 -53
- data/lib/request_log_analyzer/mailer.rb +65 -0
- data/lib/request_log_analyzer/output/fancy_html.rb +49 -0
- data/lib/request_log_analyzer/output/fixed_width.rb +220 -0
- data/lib/request_log_analyzer/output/html.rb +187 -0
- data/lib/request_log_analyzer/output.rb +117 -0
- data/lib/request_log_analyzer/request.rb +125 -40
- data/lib/request_log_analyzer/source/database_loader.rb +87 -0
- data/lib/request_log_analyzer/source/log_parser.rb +297 -0
- data/lib/request_log_analyzer/source.rb +72 -0
- data/lib/request_log_analyzer/tracker/duration.rb +28 -64
- data/lib/request_log_analyzer/tracker/frequency.rb +108 -0
- data/lib/request_log_analyzer/tracker/hourly_spread.rb +76 -49
- data/lib/request_log_analyzer/tracker/numeric_value.rb +223 -0
- data/lib/request_log_analyzer/tracker/timespan.rb +54 -27
- data/lib/request_log_analyzer/tracker/traffic.rb +40 -0
- data/lib/request_log_analyzer/tracker.rb +101 -0
- data/lib/request_log_analyzer.rb +43 -13
- data/request-log-analyzer.gemspec +41 -0
- data/spec/database.yml +23 -0
- data/spec/fixtures/apache_combined.log +5 -0
- data/spec/fixtures/apache_common.log +10 -0
- data/spec/fixtures/decompression.log +12 -0
- data/spec/fixtures/decompression.log.bz2 +0 -0
- data/spec/fixtures/decompression.log.gz +0 -0
- data/spec/fixtures/decompression.log.zip +0 -0
- data/spec/fixtures/decompression.tar.gz +0 -0
- data/spec/fixtures/decompression.tgz +0 -0
- data/spec/fixtures/header_and_footer.log +6 -0
- data/spec/fixtures/merb_prefixed.log +9 -0
- data/spec/fixtures/mysql_slow_query.log +110 -0
- data/spec/fixtures/postgresql.log +2980 -0
- data/spec/fixtures/rails.db +0 -0
- data/spec/fixtures/rails_22.log +1 -1
- data/spec/fixtures/sinatra.log +99 -0
- data/spec/integration/command_line_usage_spec.rb +84 -0
- data/spec/integration/mailer_spec.rb +179 -0
- data/spec/integration/munin_plugins_rails_spec.rb +58 -0
- data/spec/integration/scout_spec.rb +152 -0
- data/spec/lib/helpers.rb +72 -0
- data/spec/lib/macros.rb +18 -0
- data/spec/lib/matchers.rb +77 -0
- data/spec/lib/mocks.rb +77 -0
- data/spec/lib/testing_format.rb +46 -0
- data/spec/spec_helper.rb +16 -59
- data/spec/unit/aggregator/database_inserter_spec.rb +93 -0
- data/spec/unit/aggregator/summarizer_spec.rb +26 -0
- data/spec/unit/controller/controller_spec.rb +41 -0
- data/spec/unit/controller/log_processor_spec.rb +18 -0
- data/spec/unit/database/base_class_spec.rb +183 -0
- data/spec/unit/database/connection_spec.rb +34 -0
- data/spec/unit/database/database_spec.rb +133 -0
- data/spec/unit/file_format/amazon_s3_format_spec.rb +67 -0
- data/spec/unit/file_format/apache_format_spec.rb +203 -0
- data/spec/unit/file_format/common_regular_expressions_spec.rb +53 -0
- data/spec/unit/file_format/delayed_job_format_spec.rb +83 -0
- data/spec/unit/file_format/file_format_api_spec.rb +69 -0
- data/spec/unit/file_format/format_autodetection_spec.rb +40 -0
- data/spec/unit/file_format/line_definition_spec.rb +75 -0
- data/spec/unit/file_format/merb_format_spec.rb +52 -0
- data/spec/unit/file_format/mysql_format_spec.rb +154 -0
- data/spec/unit/file_format/postgresql_format_spec.rb +65 -0
- data/spec/unit/file_format/rack_format_spec.rb +50 -0
- data/spec/unit/file_format/rails3_format_spec.rb +120 -0
- data/spec/unit/file_format/rails_format_spec.rb +180 -0
- data/spec/unit/filter/anonymize_filter_spec.rb +21 -0
- data/spec/unit/filter/field_filter_spec.rb +66 -0
- data/spec/unit/filter/filter_spec.rb +17 -0
- data/spec/unit/filter/timespan_filter_spec.rb +58 -0
- data/spec/unit/mailer_spec.rb +42 -0
- data/spec/unit/request_spec.rb +111 -0
- data/spec/unit/source/log_parser_spec.rb +119 -0
- data/spec/unit/tracker/duration_tracker_spec.rb +49 -0
- data/spec/unit/tracker/frequency_tracker_spec.rb +88 -0
- data/spec/unit/tracker/hourly_spread_spec.rb +79 -0
- data/spec/unit/tracker/numeric_value_tracker_spec.rb +166 -0
- data/spec/unit/tracker/timespan_tracker_spec.rb +73 -0
- data/spec/unit/tracker/tracker_api_spec.rb +125 -0
- data/spec/unit/tracker/traffic_tracker_spec.rb +28 -0
- data/tasks/github-gem.rake +290 -139
- data/tasks/request_log_analyzer.rake +23 -7
- metadata +221 -94
- data/DESIGN +0 -14
- data/HACKING +0 -7
- data/README.textile +0 -36
- data/lib/cli/bashcolorizer.rb +0 -60
- data/lib/request_log_analyzer/aggregator/database.rb +0 -148
- data/lib/request_log_analyzer/filter/base.rb +0 -29
- data/lib/request_log_analyzer/log_parser.rb +0 -173
- data/lib/request_log_analyzer/source/base.rb +0 -42
- data/lib/request_log_analyzer/source/log_file.rb +0 -170
- data/lib/request_log_analyzer/tracker/base.rb +0 -54
- data/lib/request_log_analyzer/tracker/category.rb +0 -71
- data/spec/controller_spec.rb +0 -40
- data/spec/database_inserter_spec.rb +0 -101
- data/spec/file_format_spec.rb +0 -78
- data/spec/file_formats/spec_format.rb +0 -26
- data/spec/filter_spec.rb +0 -137
- data/spec/line_definition_spec.rb +0 -124
- data/spec/log_parser_spec.rb +0 -68
- data/spec/log_processor_spec.rb +0 -57
- data/spec/merb_format_spec.rb +0 -38
- data/spec/rails_format_spec.rb +0 -76
- data/spec/request_spec.rb +0 -72
- data/spec/summarizer_spec.rb +0 -9
- data/tasks/rspec.rake +0 -6
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
|
+
|
|
3
|
+
describe RequestLogAnalyzer::Tracker::Frequency do
|
|
4
|
+
|
|
5
|
+
context 'static category' do
|
|
6
|
+
before(:each) do
|
|
7
|
+
@tracker = RequestLogAnalyzer::Tracker::Frequency.new(:category => :category)
|
|
8
|
+
@tracker.prepare
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should register a request in the right category" do
|
|
12
|
+
@tracker.update(request(:category => 'a', :blah => 0.2))
|
|
13
|
+
@tracker.categories.should include('a')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should register a request in the right category" do
|
|
17
|
+
@tracker.update(request(:category => 'a', :blah => 0.2))
|
|
18
|
+
@tracker.update(request(:category => 'b', :blah => 0.2))
|
|
19
|
+
@tracker.update(request(:category => 'b', :blah => 0.2))
|
|
20
|
+
|
|
21
|
+
@tracker.frequency('a').should == 1
|
|
22
|
+
@tracker.frequency('b').should == 2
|
|
23
|
+
@tracker.overall_frequency.should == 3
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should sort correctly by frequency" do
|
|
27
|
+
@tracker.update(request(:category => 'a', :blah => 0.2))
|
|
28
|
+
@tracker.update(request(:category => 'b', :blah => 0.2))
|
|
29
|
+
@tracker.update(request(:category => 'b', :blah => 0.2))
|
|
30
|
+
|
|
31
|
+
@tracker.sorted_by_frequency.should == [['b', 2], ['a', 1]]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
context 'dynamic category' do
|
|
37
|
+
before(:each) do
|
|
38
|
+
@categorizer = Proc.new { |request| request[:duration] > 0.2 ? 'slow' : 'fast' }
|
|
39
|
+
@tracker = RequestLogAnalyzer::Tracker::Frequency.new(:category => @categorizer)
|
|
40
|
+
@tracker.prepare
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should use the categorizer to determine the right category" do
|
|
44
|
+
@tracker.update(request(:category => 'a', :duration => 0.2))
|
|
45
|
+
@tracker.update(request(:category => 'b', :duration => 0.3))
|
|
46
|
+
@tracker.update(request(:category => 'b', :duration => 0.4))
|
|
47
|
+
|
|
48
|
+
@tracker.frequency('fast').should == 1
|
|
49
|
+
@tracker.frequency('slow').should == 2
|
|
50
|
+
@tracker.frequency('moderate').should == 0
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
describe '#report' do
|
|
55
|
+
before(:each) do
|
|
56
|
+
@tracker = RequestLogAnalyzer::Tracker::Frequency.new(:category => :category)
|
|
57
|
+
@tracker.prepare
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should generate a report without errors when one category is present" do
|
|
61
|
+
@tracker.update(request(:category => 'a', :blah => 0.2))
|
|
62
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it "should generate a report without errors when no category is present" do
|
|
66
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "should generate a report without errors when multiple categories are present" do
|
|
70
|
+
@tracker.update(request(:category => 'a', :blah => 0.2))
|
|
71
|
+
@tracker.update(request(:category => 'b', :blah => 0.2))
|
|
72
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe '#to_yaml_object' do
|
|
77
|
+
before(:each) do
|
|
78
|
+
@tracker = RequestLogAnalyzer::Tracker::Frequency.new(:category => :category)
|
|
79
|
+
@tracker.prepare
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should generate a YAML output" do
|
|
83
|
+
@tracker.update(request(:category => 'a', :blah => 0.2))
|
|
84
|
+
@tracker.update(request(:category => 'b', :blah => 0.2))
|
|
85
|
+
@tracker.to_yaml_object.should == { "a" => 1, "b" => 1 }
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
|
+
|
|
3
|
+
describe RequestLogAnalyzer::Tracker::HourlySpread do
|
|
4
|
+
|
|
5
|
+
before(:each) do
|
|
6
|
+
@tracker = RequestLogAnalyzer::Tracker::HourlySpread.new
|
|
7
|
+
@tracker.prepare
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "should store timestamps correctly" do
|
|
11
|
+
@tracker.update(request(:timestamp => 20090102000000))
|
|
12
|
+
@tracker.update(request(:timestamp => 20090101000000))
|
|
13
|
+
@tracker.update(request(:timestamp => 20090103000000))
|
|
14
|
+
|
|
15
|
+
@tracker.hour_frequencies[0].should eql(3)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should count the number of timestamps correctly" do
|
|
19
|
+
@tracker.update(request(:timestamp => 20090102000000))
|
|
20
|
+
@tracker.update(request(:timestamp => 20090101000000))
|
|
21
|
+
@tracker.update(request(:timestamp => 20090103000000))
|
|
22
|
+
@tracker.update(request(:timestamp => 20090103010000))
|
|
23
|
+
|
|
24
|
+
@tracker.total_requests.should eql(4)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should set the first request timestamp correctly" do
|
|
28
|
+
@tracker.update(request(:timestamp => 20090102000000))
|
|
29
|
+
@tracker.update(request(:timestamp => 20090101000000))
|
|
30
|
+
@tracker.update(request(:timestamp => 20090103000000))
|
|
31
|
+
|
|
32
|
+
@tracker.first_timestamp.should == DateTime.parse('Januari 1, 2009 00:00:00')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should set the last request timestamp correctly" do
|
|
36
|
+
@tracker.update(request(:timestamp => 20090102000000))
|
|
37
|
+
@tracker.update(request(:timestamp => 20090101000000))
|
|
38
|
+
@tracker.update(request(:timestamp => 20090103000000))
|
|
39
|
+
|
|
40
|
+
@tracker.last_timestamp.should == DateTime.parse('Januari 3, 2009 00:00:00')
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should return the correct timespan in days when multiple requests are given" do
|
|
44
|
+
@tracker.update(request(:timestamp => 20090102000000))
|
|
45
|
+
@tracker.update(request(:timestamp => 20090101000000))
|
|
46
|
+
@tracker.update(request(:timestamp => 20090103000000))
|
|
47
|
+
|
|
48
|
+
@tracker.timespan.should == 2
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
describe RequestLogAnalyzer::Tracker::HourlySpread, 'reporting' do
|
|
54
|
+
|
|
55
|
+
before(:each) do
|
|
56
|
+
@tracker = RequestLogAnalyzer::Tracker::HourlySpread.new
|
|
57
|
+
@tracker.prepare
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "should generate a report without errors when no request was tracked" do
|
|
61
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should generate a report without errors when multiple requests were tracked" do
|
|
65
|
+
@tracker.update(request(:timestamp => 20090102000000))
|
|
66
|
+
@tracker.update(request(:timestamp => 20090101000000))
|
|
67
|
+
@tracker.update(request(:timestamp => 20090103000000))
|
|
68
|
+
@tracker.update(request(:timestamp => 20090103010000))
|
|
69
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should generate a YAML output" do
|
|
73
|
+
@tracker.update(request(:timestamp => 20090102000000))
|
|
74
|
+
@tracker.update(request(:timestamp => 20090101000000))
|
|
75
|
+
@tracker.update(request(:timestamp => 20090103000000))
|
|
76
|
+
@tracker.update(request(:timestamp => 20090103010000))
|
|
77
|
+
@tracker.to_yaml_object.should == {"22:00 - 23:00"=>0, "9:00 - 10:00"=>0, "7:00 - 8:00"=>0, "2:00 - 3:00"=>0, "12:00 - 13:00"=>0, "11:00 - 12:00"=>0, "16:00 - 17:00"=>0, "15:00 - 16:00"=>0, "19:00 - 20:00"=>0, "3:00 - 4:00"=>0, "21:00 - 22:00"=>0, "20:00 - 21:00"=>0, "14:00 - 15:00"=>0, "13:00 - 14:00"=>0, "4:00 - 5:00"=>0, "10:00 - 11:00"=>0, "18:00 - 19:00"=>0, "17:00 - 18:00"=>0, "8:00 - 9:00"=>0, "6:00 - 7:00"=>0, "5:00 - 6:00"=>0, "1:00 - 2:00"=>1, "0:00 - 1:00"=>3, "23:00 - 24:00"=>0}
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
|
+
|
|
3
|
+
describe RequestLogAnalyzer::Tracker::NumericValue do
|
|
4
|
+
|
|
5
|
+
context 'static category' do
|
|
6
|
+
before(:each) do
|
|
7
|
+
@tracker = RequestLogAnalyzer::Tracker::NumericValue.new(:category => :category, :value => :blah)
|
|
8
|
+
@tracker.prepare
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should register a request in the right category" do
|
|
12
|
+
@tracker.update(request(:category => 'a', :blah => 2))
|
|
13
|
+
@tracker.categories.should include('a')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should register requests in the right category" do
|
|
17
|
+
@tracker.update(request(:category => 'a', :blah => 2))
|
|
18
|
+
@tracker.update(request(:category => 'b', :blah => 2))
|
|
19
|
+
@tracker.update(request(:category => 'b', :blah => 2))
|
|
20
|
+
|
|
21
|
+
@tracker.categories['a'][:sum].should == 2
|
|
22
|
+
@tracker.categories['b'][:sum].should == 4
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
context 'dynamic category' do
|
|
28
|
+
before(:each) do
|
|
29
|
+
@categorizer = Proc.new { |request| request[:duration] > 0.2 ? 'slow' : 'fast' }
|
|
30
|
+
@tracker = RequestLogAnalyzer::Tracker::NumericValue.new(:category => @categorizer, :value => :blah)
|
|
31
|
+
@tracker.prepare
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should use the categorizer to determine the right category" do
|
|
35
|
+
@tracker.update(request(:category => 'a', :duration => 0.2, :blah => 2))
|
|
36
|
+
@tracker.update(request(:category => 'b', :duration => 0.3, :blah => 2))
|
|
37
|
+
@tracker.update(request(:category => 'b', :duration => 0.4, :blah => 2))
|
|
38
|
+
|
|
39
|
+
@tracker.categories['fast'][:sum].should == 2
|
|
40
|
+
@tracker.categories['slow'][:sum].should == 4
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe '#update' do
|
|
45
|
+
|
|
46
|
+
before(:each) do
|
|
47
|
+
@tracker = RequestLogAnalyzer::Tracker::NumericValue.new(:value => :duration, :category => :category)
|
|
48
|
+
@tracker.prepare
|
|
49
|
+
|
|
50
|
+
@tracker.update(request(:category => 'a', :duration => 0.4))
|
|
51
|
+
@tracker.update(request(:category => 'a', :duration => 0.2))
|
|
52
|
+
@tracker.update(request(:category => 'a', :duration => 0.3))
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "should sum of the durations for a category correctly" do
|
|
56
|
+
@tracker.sum('a').should be_close(0.9, 0.000001)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should overall sum of the durations correctly" do
|
|
60
|
+
@tracker.sum_overall.should be_close(0.9, 0.000001)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should keep track of the minimum and maximum duration" do
|
|
64
|
+
@tracker.min('a').should == 0.2
|
|
65
|
+
@tracker.max('a').should == 0.4
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should calculate the mean duration correctly" do
|
|
69
|
+
@tracker.mean('a').should be_close(0.3, 0.000001)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should calculate the overall mean duration correctly" do
|
|
73
|
+
@tracker.mean_overall.should be_close(0.3, 0.000001)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should calculate the duration variance correctly" do
|
|
77
|
+
@tracker.variance('a').should be_close(0.01, 0.000001)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "should calculate the duration standard deviation correctly" do
|
|
81
|
+
@tracker.stddev('a').should be_close(0.1, 0.000001)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
describe '#report' do
|
|
86
|
+
before(:each) do
|
|
87
|
+
@tracker = RequestLogAnalyzer::Tracker::NumericValue.new(:category => :category, :value => :blah)
|
|
88
|
+
@tracker.prepare
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "should generate a report without errors when one category is present" do
|
|
92
|
+
@tracker.update(request(:category => 'a', :blah => 2))
|
|
93
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "should generate a report without errors when no category is present" do
|
|
97
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it "should generate a report without errors when multiple categories are present" do
|
|
101
|
+
@tracker.update(request(:category => 'a', :blah => 2))
|
|
102
|
+
@tracker.update(request(:category => 'b', :blah => 2))
|
|
103
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
describe '#to_yaml_object' do
|
|
108
|
+
before(:each) do
|
|
109
|
+
@tracker = RequestLogAnalyzer::Tracker::NumericValue.new(:category => :category, :value => :blah)
|
|
110
|
+
@tracker.prepare
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "should generate a YAML output" do
|
|
114
|
+
@tracker.update(request(:category => 'a', :blah => 2))
|
|
115
|
+
@tracker.update(request(:category => 'b', :blah => 3))
|
|
116
|
+
@tracker.to_yaml_object.should == {
|
|
117
|
+
"a" => { :min => 2, :hits => 1, :max => 2, :mean => 2.0, :sum => 2, :sum_of_squares => 0.0 },
|
|
118
|
+
"b" => { :min => 3, :hits => 1, :max => 3, :mean => 3.0, :sum => 3, :sum_of_squares => 0.0 }}
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
describe '#display_value' do
|
|
123
|
+
before(:each) do
|
|
124
|
+
@tracker = RequestLogAnalyzer::Tracker::NumericValue.new(:category => :category, :value => :blah)
|
|
125
|
+
@tracker.prepare
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "should not crash on nil" do
|
|
129
|
+
lambda { @tracker.display_value(nil) }.should_not raise_error
|
|
130
|
+
@tracker.display_value(nil).should_not be_nil
|
|
131
|
+
@tracker.display_value(nil).should_not eql("")
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "should not touch thousands" do
|
|
135
|
+
@tracker.display_value(1000).should eql('1000 ')
|
|
136
|
+
@tracker.display_value(5000).should eql('5000 ')
|
|
137
|
+
@tracker.display_value(9001).should eql('9001 ')
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "should reduce milions to thousands (k)" do
|
|
141
|
+
@tracker.display_value(1000_000).should eql('1000k')
|
|
142
|
+
@tracker.display_value(5000_000).should eql('5000k')
|
|
143
|
+
@tracker.display_value(9000_001).should eql('9000k')
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it "should reduce giga to millons (M)" do
|
|
147
|
+
@tracker.display_value(1000_000_000).should eql('1000M')
|
|
148
|
+
@tracker.display_value(5000_000_000).should eql('5000M')
|
|
149
|
+
@tracker.display_value(9000_000_001).should eql('9000M')
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "should reduce teras to gigas (G)" do
|
|
153
|
+
@tracker.display_value(1000_000_000_000).should eql('1000G')
|
|
154
|
+
@tracker.display_value(5000_000_000_000).should eql('5000G')
|
|
155
|
+
@tracker.display_value(9000_000_001_001).should eql('9000G')
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "should reduce petas to teras (T)" do
|
|
159
|
+
@tracker.display_value(1000_000_000_000_000).should eql('1000T')
|
|
160
|
+
@tracker.display_value(5000_000_000_000_000).should eql('5000T')
|
|
161
|
+
@tracker.display_value(9000_000_001_001_000).should eql('9000T')
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
|
+
|
|
3
|
+
describe RequestLogAnalyzer::Tracker::Timespan do
|
|
4
|
+
|
|
5
|
+
before(:each) do
|
|
6
|
+
@tracker = RequestLogAnalyzer::Tracker::Timespan.new
|
|
7
|
+
@tracker.prepare
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "should set the first request timestamp correctly" do
|
|
11
|
+
@tracker.update(request(:timestamp => 20090102000000))
|
|
12
|
+
@tracker.update(request(:timestamp => 20090101000000))
|
|
13
|
+
@tracker.update(request(:timestamp => 20090103000000))
|
|
14
|
+
|
|
15
|
+
@tracker.first_timestamp.should == DateTime.parse('Januari 1, 2009 00:00:00')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should set the last request timestamp correctly" do
|
|
19
|
+
@tracker.update(request(:timestamp => 20090102000000))
|
|
20
|
+
@tracker.update(request(:timestamp => 20090101000000))
|
|
21
|
+
@tracker.update(request(:timestamp => 20090103000000))
|
|
22
|
+
|
|
23
|
+
@tracker.last_timestamp.should == DateTime.parse('Januari 3, 2009 00:00:00')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should return the correct timespan in days when multiple requests are given" do
|
|
27
|
+
@tracker.update(request(:timestamp => 20090102000000))
|
|
28
|
+
@tracker.update(request(:timestamp => 20090101000000))
|
|
29
|
+
@tracker.update(request(:timestamp => 20090103000000))
|
|
30
|
+
|
|
31
|
+
@tracker.timespan.should == 2
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should return a timespan of 0 days when only one timestamp is set" do
|
|
35
|
+
@tracker.update(request(:timestamp => 20090103000000))
|
|
36
|
+
@tracker.timespan.should == 0
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should raise an error when no timestamp is set" do
|
|
40
|
+
lambda { @tracker.timespan }.should raise_error
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe RequestLogAnalyzer::Tracker::Timespan, 'reporting' do
|
|
45
|
+
|
|
46
|
+
before(:each) do
|
|
47
|
+
@tracker = RequestLogAnalyzer::Tracker::Timespan.new
|
|
48
|
+
@tracker.prepare
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should have a title" do
|
|
52
|
+
@tracker.title.should_not eql("")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "should generate a report without errors when no request was tracked" do
|
|
56
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "should generate a report without errors when multiple requests were tracked" do
|
|
60
|
+
@tracker.update(request(:category => 'a', :timestamp => 20090102000000))
|
|
61
|
+
@tracker.update(request(:category => 'a', :timestamp => 20090101000000))
|
|
62
|
+
@tracker.update(request(:category => 'a', :timestamp => 20090103000000))
|
|
63
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "should generate a YAML output" do
|
|
67
|
+
@tracker.update(request(:category => 'a', :timestamp => 20090102000000))
|
|
68
|
+
@tracker.update(request(:category => 'a', :timestamp => 20090101000000))
|
|
69
|
+
@tracker.update(request(:category => 'a', :timestamp => 20090103000000))
|
|
70
|
+
@tracker.to_yaml_object.should == { :first => DateTime.parse('20090101000000'), :last => DateTime.parse('20090103000000')}
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
|
+
|
|
3
|
+
describe RequestLogAnalyzer::Tracker::Base do
|
|
4
|
+
|
|
5
|
+
describe 'API' do
|
|
6
|
+
|
|
7
|
+
before(:each) do
|
|
8
|
+
@tracker = Class.new(RequestLogAnalyzer::Tracker::Base).new
|
|
9
|
+
|
|
10
|
+
@summarizer = RequestLogAnalyzer::Aggregator::Summarizer.new(mock_source)
|
|
11
|
+
@summarizer.trackers << @tracker
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "should receive :prepare when the summarizer is preparing" do
|
|
15
|
+
@tracker.should_receive(:prepare).once
|
|
16
|
+
@summarizer.prepare
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "should receive :update for every request for which should_update? returns true" do
|
|
20
|
+
@tracker.should_receive(:should_update?).twice.and_return(true)
|
|
21
|
+
@tracker.should_receive(:update).twice
|
|
22
|
+
|
|
23
|
+
@summarizer.aggregate(testing_format.request(:field => 'value1'))
|
|
24
|
+
@summarizer.aggregate(testing_format.request(:field => 'value2'))
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should not :update for every request for which should_update? returns false" do
|
|
28
|
+
@tracker.should_receive(:should_update?).twice.and_return(false)
|
|
29
|
+
@tracker.should_not_receive(:update)
|
|
30
|
+
|
|
31
|
+
@summarizer.aggregate(testing_format.request(:field => 'value1'))
|
|
32
|
+
@summarizer.aggregate(testing_format.request(:field => 'value2'))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should receive :report when the summary report is being built" do
|
|
36
|
+
m = mock_output
|
|
37
|
+
m.should_receive(:report_tracker).with(@tracker)
|
|
38
|
+
@summarizer.report(m)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "should receieve :finalize when the summarizer is finalizing" do
|
|
42
|
+
@tracker.should_receive(:finalize).once
|
|
43
|
+
@summarizer.finalize
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
describe '#should_update?' do
|
|
48
|
+
before(:each) do
|
|
49
|
+
@tracker_class = Class.new(RequestLogAnalyzer::Tracker::Base)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "should return true by default, when no checks are installed" do
|
|
53
|
+
tracker = @tracker_class.new
|
|
54
|
+
tracker.should_update?(testing_format.request).should be_true
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "should return false if the line type is not in the request" do
|
|
58
|
+
tracker = @tracker_class.new(:line_type => :not_there)
|
|
59
|
+
tracker.should_update?(request(:line_type => :different)).should be_false
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should return true if the line type is in the request" do
|
|
63
|
+
tracker = @tracker_class.new(:line_type => :there)
|
|
64
|
+
tracker.should_update?(request(:line_type => :there)).should be_true
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "should return true if a field name is given to :if and it is in the request" do
|
|
68
|
+
tracker = @tracker_class.new(:if => :field)
|
|
69
|
+
tracker.should_update?(request(:field => 'anything')).should be_true
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should return false if a field name is given to :if and it is not the request" do
|
|
73
|
+
tracker = @tracker_class.new(:if => :field)
|
|
74
|
+
tracker.should_update?(request(:other_field => 'anything')).should be_false
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "should return false if a field name is given to :unless and it is in the request" do
|
|
78
|
+
tracker = @tracker_class.new(:unless => :field)
|
|
79
|
+
tracker.should_update?(request(:field => 'anything')).should be_false
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should return true if a field name is given to :unless and it is not the request" do
|
|
83
|
+
tracker = @tracker_class.new(:unless => :field)
|
|
84
|
+
tracker.should_update?(request(:other_field => 'anything')).should be_true
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "should return the value of the block if one is given to the :if option" do
|
|
88
|
+
tracker = @tracker_class.new(:if => lambda { |r| false } )
|
|
89
|
+
tracker.should_update?(request(:field => 'anything')).should be_false
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "should return the inverse value of the block if one is given to the :if option" do
|
|
93
|
+
tracker = @tracker_class.new(:unless => lambda { |r| false } )
|
|
94
|
+
tracker.should_update?(request(:field => 'anything')).should be_true
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "should return false if any of the checks fail" do
|
|
98
|
+
tracker = @tracker_class.new(:if => :field, :unless => lambda { |r| false }, :line_type => :not_present )
|
|
99
|
+
tracker.should_update?(request(:line_type => :present, :field => 'anything')).should be_false
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "should return true if all of the checks succeed" do
|
|
103
|
+
tracker = @tracker_class.new(:if => :field, :unless => lambda { |r| false }, :line_type => :present )
|
|
104
|
+
tracker.should_update?(request(:line_type => :present, :field => 'anything')).should be_true
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe '#to_yaml_object' do
|
|
111
|
+
|
|
112
|
+
before(:each) do
|
|
113
|
+
@tracker = Class.new(RequestLogAnalyzer::Tracker::Base).new
|
|
114
|
+
|
|
115
|
+
@summarizer = RequestLogAnalyzer::Aggregator::Summarizer.new(mock_source)
|
|
116
|
+
@summarizer.trackers << @tracker
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should receive :to_yaml object when finalizing" do
|
|
120
|
+
@summarizer.options[:yaml] = temp_output_file(:yaml)
|
|
121
|
+
@tracker.should_receive(:to_yaml_object).once
|
|
122
|
+
@summarizer.to_yaml
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
|
+
|
|
3
|
+
describe RequestLogAnalyzer::Tracker::Traffic do
|
|
4
|
+
|
|
5
|
+
describe '#report' do
|
|
6
|
+
before(:each) do
|
|
7
|
+
@tracker = RequestLogAnalyzer::Tracker::Traffic.new(:category => :category, :traffic => :traffic)
|
|
8
|
+
@tracker.prepare
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it "should generate a report without errors when one category is present" do
|
|
12
|
+
@tracker.update(request(:category => 'a', :traffic => 2))
|
|
13
|
+
@tracker.report(mock_output)
|
|
14
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should generate a report without errors when no category is present" do
|
|
18
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should generate a report without errors when multiple categories are present" do
|
|
22
|
+
@tracker.update(request(:category => 'a', :traffic => 2))
|
|
23
|
+
@tracker.update(request(:category => 'b', :traffic => 2))
|
|
24
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|