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.
Files changed (144) hide show
  1. data/.gitignore +10 -0
  2. data/DESIGN.rdoc +41 -0
  3. data/LICENSE +4 -4
  4. data/README.rdoc +38 -0
  5. data/Rakefile +6 -3
  6. data/bin/request-log-analyzer +70 -72
  7. data/lib/cli/command_line_arguments.rb +53 -53
  8. data/lib/cli/database_console.rb +26 -0
  9. data/lib/cli/database_console_init.rb +43 -0
  10. data/lib/cli/progressbar.rb +166 -189
  11. data/lib/cli/tools.rb +49 -0
  12. data/lib/request_log_analyzer/aggregator/database_inserter.rb +83 -0
  13. data/lib/request_log_analyzer/aggregator/echo.rb +17 -12
  14. data/lib/request_log_analyzer/aggregator/summarizer.rb +101 -63
  15. data/lib/request_log_analyzer/{aggregator/base.rb → aggregator.rb} +17 -13
  16. data/lib/request_log_analyzer/controller.rb +251 -98
  17. data/lib/request_log_analyzer/database/base.rb +114 -0
  18. data/lib/request_log_analyzer/database/connection.rb +38 -0
  19. data/lib/request_log_analyzer/database/request.rb +22 -0
  20. data/lib/request_log_analyzer/database/source.rb +13 -0
  21. data/lib/request_log_analyzer/database/warning.rb +14 -0
  22. data/lib/request_log_analyzer/database.rb +102 -0
  23. data/lib/request_log_analyzer/file_format/amazon_s3.rb +74 -0
  24. data/lib/request_log_analyzer/file_format/apache.rb +147 -0
  25. data/lib/request_log_analyzer/file_format/delayed_job.rb +55 -0
  26. data/lib/request_log_analyzer/file_format/merb.rb +65 -29
  27. data/lib/request_log_analyzer/file_format/mysql.rb +101 -0
  28. data/lib/request_log_analyzer/file_format/postgresql.rb +68 -0
  29. data/lib/request_log_analyzer/file_format/rack.rb +9 -0
  30. data/lib/request_log_analyzer/file_format/rails.rb +164 -78
  31. data/lib/request_log_analyzer/file_format/rails3.rb +86 -0
  32. data/lib/request_log_analyzer/file_format/rails_development.rb +12 -0
  33. data/lib/request_log_analyzer/file_format.rb +252 -58
  34. data/lib/request_log_analyzer/filter/anonymize.rb +39 -0
  35. data/lib/request_log_analyzer/filter/field.rb +19 -13
  36. data/lib/request_log_analyzer/filter/timespan.rb +25 -12
  37. data/lib/request_log_analyzer/filter.rb +30 -0
  38. data/lib/request_log_analyzer/line_definition.rb +69 -96
  39. data/lib/request_log_analyzer/log_processor.rb +31 -53
  40. data/lib/request_log_analyzer/mailer.rb +65 -0
  41. data/lib/request_log_analyzer/output/fancy_html.rb +49 -0
  42. data/lib/request_log_analyzer/output/fixed_width.rb +220 -0
  43. data/lib/request_log_analyzer/output/html.rb +187 -0
  44. data/lib/request_log_analyzer/output.rb +117 -0
  45. data/lib/request_log_analyzer/request.rb +125 -40
  46. data/lib/request_log_analyzer/source/database_loader.rb +87 -0
  47. data/lib/request_log_analyzer/source/log_parser.rb +297 -0
  48. data/lib/request_log_analyzer/source.rb +72 -0
  49. data/lib/request_log_analyzer/tracker/duration.rb +28 -64
  50. data/lib/request_log_analyzer/tracker/frequency.rb +108 -0
  51. data/lib/request_log_analyzer/tracker/hourly_spread.rb +76 -49
  52. data/lib/request_log_analyzer/tracker/numeric_value.rb +223 -0
  53. data/lib/request_log_analyzer/tracker/timespan.rb +54 -27
  54. data/lib/request_log_analyzer/tracker/traffic.rb +40 -0
  55. data/lib/request_log_analyzer/tracker.rb +101 -0
  56. data/lib/request_log_analyzer.rb +43 -13
  57. data/request-log-analyzer.gemspec +41 -0
  58. data/spec/database.yml +23 -0
  59. data/spec/fixtures/apache_combined.log +5 -0
  60. data/spec/fixtures/apache_common.log +10 -0
  61. data/spec/fixtures/decompression.log +12 -0
  62. data/spec/fixtures/decompression.log.bz2 +0 -0
  63. data/spec/fixtures/decompression.log.gz +0 -0
  64. data/spec/fixtures/decompression.log.zip +0 -0
  65. data/spec/fixtures/decompression.tar.gz +0 -0
  66. data/spec/fixtures/decompression.tgz +0 -0
  67. data/spec/fixtures/header_and_footer.log +6 -0
  68. data/spec/fixtures/merb_prefixed.log +9 -0
  69. data/spec/fixtures/mysql_slow_query.log +110 -0
  70. data/spec/fixtures/postgresql.log +2980 -0
  71. data/spec/fixtures/rails.db +0 -0
  72. data/spec/fixtures/rails_22.log +1 -1
  73. data/spec/fixtures/sinatra.log +99 -0
  74. data/spec/integration/command_line_usage_spec.rb +84 -0
  75. data/spec/integration/mailer_spec.rb +179 -0
  76. data/spec/integration/munin_plugins_rails_spec.rb +58 -0
  77. data/spec/integration/scout_spec.rb +152 -0
  78. data/spec/lib/helpers.rb +72 -0
  79. data/spec/lib/macros.rb +18 -0
  80. data/spec/lib/matchers.rb +77 -0
  81. data/spec/lib/mocks.rb +77 -0
  82. data/spec/lib/testing_format.rb +46 -0
  83. data/spec/spec_helper.rb +16 -59
  84. data/spec/unit/aggregator/database_inserter_spec.rb +93 -0
  85. data/spec/unit/aggregator/summarizer_spec.rb +26 -0
  86. data/spec/unit/controller/controller_spec.rb +41 -0
  87. data/spec/unit/controller/log_processor_spec.rb +18 -0
  88. data/spec/unit/database/base_class_spec.rb +183 -0
  89. data/spec/unit/database/connection_spec.rb +34 -0
  90. data/spec/unit/database/database_spec.rb +133 -0
  91. data/spec/unit/file_format/amazon_s3_format_spec.rb +67 -0
  92. data/spec/unit/file_format/apache_format_spec.rb +203 -0
  93. data/spec/unit/file_format/common_regular_expressions_spec.rb +53 -0
  94. data/spec/unit/file_format/delayed_job_format_spec.rb +83 -0
  95. data/spec/unit/file_format/file_format_api_spec.rb +69 -0
  96. data/spec/unit/file_format/format_autodetection_spec.rb +40 -0
  97. data/spec/unit/file_format/line_definition_spec.rb +75 -0
  98. data/spec/unit/file_format/merb_format_spec.rb +52 -0
  99. data/spec/unit/file_format/mysql_format_spec.rb +154 -0
  100. data/spec/unit/file_format/postgresql_format_spec.rb +65 -0
  101. data/spec/unit/file_format/rack_format_spec.rb +50 -0
  102. data/spec/unit/file_format/rails3_format_spec.rb +120 -0
  103. data/spec/unit/file_format/rails_format_spec.rb +180 -0
  104. data/spec/unit/filter/anonymize_filter_spec.rb +21 -0
  105. data/spec/unit/filter/field_filter_spec.rb +66 -0
  106. data/spec/unit/filter/filter_spec.rb +17 -0
  107. data/spec/unit/filter/timespan_filter_spec.rb +58 -0
  108. data/spec/unit/mailer_spec.rb +42 -0
  109. data/spec/unit/request_spec.rb +111 -0
  110. data/spec/unit/source/log_parser_spec.rb +119 -0
  111. data/spec/unit/tracker/duration_tracker_spec.rb +49 -0
  112. data/spec/unit/tracker/frequency_tracker_spec.rb +88 -0
  113. data/spec/unit/tracker/hourly_spread_spec.rb +79 -0
  114. data/spec/unit/tracker/numeric_value_tracker_spec.rb +166 -0
  115. data/spec/unit/tracker/timespan_tracker_spec.rb +73 -0
  116. data/spec/unit/tracker/tracker_api_spec.rb +125 -0
  117. data/spec/unit/tracker/traffic_tracker_spec.rb +28 -0
  118. data/tasks/github-gem.rake +290 -139
  119. data/tasks/request_log_analyzer.rake +23 -7
  120. metadata +221 -94
  121. data/DESIGN +0 -14
  122. data/HACKING +0 -7
  123. data/README.textile +0 -36
  124. data/lib/cli/bashcolorizer.rb +0 -60
  125. data/lib/request_log_analyzer/aggregator/database.rb +0 -148
  126. data/lib/request_log_analyzer/filter/base.rb +0 -29
  127. data/lib/request_log_analyzer/log_parser.rb +0 -173
  128. data/lib/request_log_analyzer/source/base.rb +0 -42
  129. data/lib/request_log_analyzer/source/log_file.rb +0 -170
  130. data/lib/request_log_analyzer/tracker/base.rb +0 -54
  131. data/lib/request_log_analyzer/tracker/category.rb +0 -71
  132. data/spec/controller_spec.rb +0 -40
  133. data/spec/database_inserter_spec.rb +0 -101
  134. data/spec/file_format_spec.rb +0 -78
  135. data/spec/file_formats/spec_format.rb +0 -26
  136. data/spec/filter_spec.rb +0 -137
  137. data/spec/line_definition_spec.rb +0 -124
  138. data/spec/log_parser_spec.rb +0 -68
  139. data/spec/log_processor_spec.rb +0 -57
  140. data/spec/merb_format_spec.rb +0 -38
  141. data/spec/rails_format_spec.rb +0 -76
  142. data/spec/request_spec.rb +0 -72
  143. data/spec/summarizer_spec.rb +0 -9
  144. 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