request-log-analyzer 1.3.4 → 1.3.6
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/lib/cli/database_console_init.rb +2 -1
- data/lib/request_log_analyzer/aggregator/database_inserter.rb +10 -8
- data/lib/request_log_analyzer/aggregator.rb +1 -5
- data/lib/request_log_analyzer/controller.rb +10 -21
- data/lib/request_log_analyzer/database/base.rb +7 -6
- 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 +16 -91
- data/lib/request_log_analyzer/file_format/amazon_s3.rb +6 -6
- data/lib/request_log_analyzer/file_format/apache.rb +21 -15
- data/lib/request_log_analyzer/file_format/merb.rb +21 -5
- data/lib/request_log_analyzer/file_format/rack.rb +11 -0
- data/lib/request_log_analyzer/file_format/rails.rb +8 -14
- data/lib/request_log_analyzer/file_format.rb +1 -13
- data/lib/request_log_analyzer/filter/anonymize.rb +2 -1
- data/lib/request_log_analyzer/filter.rb +6 -10
- data/lib/request_log_analyzer/log_processor.rb +6 -8
- data/lib/request_log_analyzer/output/fixed_width.rb +8 -7
- data/lib/request_log_analyzer/request.rb +61 -37
- data/lib/request_log_analyzer/source/database_loader.rb +3 -7
- data/lib/request_log_analyzer/source/log_parser.rb +3 -6
- data/lib/request_log_analyzer/source.rb +4 -6
- data/lib/request_log_analyzer/tracker/duration.rb +3 -3
- data/lib/request_log_analyzer/tracker/hourly_spread.rb +1 -2
- data/lib/request_log_analyzer/tracker/traffic.rb +186 -0
- data/lib/request_log_analyzer/tracker.rb +12 -19
- data/lib/request_log_analyzer.rb +3 -3
- data/request-log-analyzer.gemspec +4 -4
- data/spec/database.yml +6 -0
- data/spec/lib/mocks.rb +5 -2
- data/spec/unit/aggregator/database_inserter_spec.rb +3 -3
- data/spec/unit/database/base_class_spec.rb +9 -16
- data/spec/unit/database/database_spec.rb +9 -14
- data/spec/unit/file_format/apache_format_spec.rb +38 -1
- data/spec/unit/tracker/tracker_api_spec.rb +111 -36
- data/spec/unit/tracker/traffic_tracker_spec.rb +105 -0
- metadata +13 -6
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = "request-log-analyzer"
|
|
3
|
-
s.version = "1.3.
|
|
4
|
-
s.date = "2009-09-
|
|
3
|
+
s.version = "1.3.6"
|
|
4
|
+
s.date = "2009-09-20"
|
|
5
5
|
|
|
6
6
|
s.rubyforge_project = 'r-l-a'
|
|
7
7
|
|
|
@@ -31,6 +31,6 @@ Gem::Specification.new do |s|
|
|
|
31
31
|
s.email = ['willem@railsdoctors.com', 'bart@railsdoctors.com']
|
|
32
32
|
s.homepage = 'http://railsdoctors.com'
|
|
33
33
|
|
|
34
|
-
s.files = %w(spec/unit/filter/anonymize_filter_spec.rb lib/request_log_analyzer/line_definition.rb lib/request_log_analyzer/output/html.rb lib/request_log_analyzer/controller.rb spec/
|
|
35
|
-
s.test_files = %w(spec/unit/filter/anonymize_filter_spec.rb spec/unit/file_format/file_format_api_spec.rb spec/unit/file_format/apache_format_spec.rb spec/integration/command_line_usage_spec.rb spec/unit/filter/timespan_filter_spec.rb spec/unit/aggregator/database_inserter_spec.rb spec/unit/tracker/tracker_api_spec.rb spec/unit/tracker/duration_tracker_spec.rb spec/unit/file_format/amazon_s3_format_spec.rb spec/unit/controller/log_processor_spec.rb spec/unit/filter/filter_spec.rb spec/unit/filter/field_filter_spec.rb spec/unit/database/base_class_spec.rb spec/unit/tracker/timespan_tracker_spec.rb spec/unit/tracker/hourly_spread_spec.rb spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/line_definition_spec.rb spec/unit/database/connection_spec.rb spec/unit/controller/controller_spec.rb spec/unit/source/request_spec.rb spec/unit/source/log_parser_spec.rb spec/unit/database/database_spec.rb spec/unit/aggregator/summarizer_spec.rb spec/unit/tracker/frequency_tracker_spec.rb spec/unit/file_format/rails_format_spec.rb)
|
|
34
|
+
s.files = %w(spec/unit/filter/anonymize_filter_spec.rb spec/fixtures/rails_22_cached.log lib/request_log_analyzer/line_definition.rb lib/request_log_analyzer/output/html.rb lib/request_log_analyzer/controller.rb spec/lib/macros.rb lib/request_log_analyzer/file_format/rails_development.rb spec/fixtures/apache_combined.log spec/fixtures/apache_common.log spec/fixtures/merb_prefixed.log lib/request_log_analyzer/file_format/amazon_s3.rb tasks/request_log_analyzer.rake spec/unit/file_format/file_format_api_spec.rb spec/unit/file_format/apache_format_spec.rb spec/integration/command_line_usage_spec.rb lib/request_log_analyzer/database.rb spec/fixtures/decompression.log.bz2 spec/fixtures/rails_unordered.log lib/request_log_analyzer/log_processor.rb lib/request_log_analyzer/tracker.rb lib/request_log_analyzer/filter.rb bin/request-log-analyzer request-log-analyzer.gemspec DESIGN.rdoc spec/unit/filter/timespan_filter_spec.rb spec/unit/aggregator/database_inserter_spec.rb spec/lib/matchers.rb lib/request_log_analyzer/filter/field.rb lib/request_log_analyzer/tracker/frequency.rb spec/fixtures/decompression.log.gz spec/fixtures/decompression.log spec/lib/testing_format.rb spec/fixtures/test_order.log spec/fixtures/rails.db lib/request_log_analyzer/output/fixed_width.rb lib/request_log_analyzer/filter/anonymize.rb lib/request_log_analyzer/tracker/timespan.rb lib/request_log_analyzer/database/base.rb lib/request_log_analyzer/aggregator.rb lib/cli/progressbar.rb lib/request_log_analyzer/mailer.rb README.rdoc lib/request_log_analyzer/database/warning.rb spec/fixtures/merb.log lib/request_log_analyzer/tracker/hourly_spread.rb .gitignore spec/unit/tracker/tracker_api_spec.rb spec/unit/tracker/duration_tracker_spec.rb spec/unit/file_format/amazon_s3_format_spec.rb lib/request_log_analyzer/aggregator/echo.rb spec/unit/controller/log_processor_spec.rb spec/spec_helper.rb lib/request_log_analyzer.rb spec/database.yml Rakefile lib/request_log_analyzer/database/connection.rb spec/unit/filter/filter_spec.rb spec/fixtures/test_language_combined.log lib/request_log_analyzer/aggregator/database_inserter.rb lib/request_log_analyzer/aggregator/summarizer.rb lib/request_log_analyzer/file_format/rack.rb lib/request_log_analyzer/database/source.rb lib/request_log_analyzer/file_format/rails.rb spec/fixtures/decompression.tar.gz spec/unit/tracker/traffic_tracker_spec.rb spec/unit/filter/field_filter_spec.rb spec/unit/database/base_class_spec.rb lib/request_log_analyzer/filter/timespan.rb lib/request_log_analyzer/source/log_parser.rb spec/fixtures/decompression.tgz spec/unit/tracker/timespan_tracker_spec.rb spec/unit/tracker/hourly_spread_spec.rb spec/fixtures/header_and_footer.log lib/cli/tools.rb lib/request_log_analyzer/file_format/merb.rb spec/fixtures/multiple_files_1.log spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/line_definition_spec.rb lib/request_log_analyzer/source.rb lib/request_log_analyzer/request.rb lib/cli/database_console.rb spec/unit/database/connection_spec.rb spec/unit/controller/controller_spec.rb spec/lib/mocks.rb spec/lib/helpers.rb spec/fixtures/rails_1x.log lib/cli/database_console_init.rb lib/request_log_analyzer/output.rb lib/request_log_analyzer/file_format/apache.rb spec/fixtures/decompression.log.zip spec/unit/source/request_spec.rb spec/unit/source/log_parser_spec.rb spec/fixtures/test_file_format.log tasks/github-gem.rake spec/unit/database/database_spec.rb lib/request_log_analyzer/tracker/duration.rb lib/request_log_analyzer/tracker/traffic.rb lib/request_log_analyzer/file_format.rb spec/unit/aggregator/summarizer_spec.rb spec/fixtures/syslog_1x.log spec/fixtures/rails_22.log lib/request_log_analyzer/database/request.rb spec/fixtures/multiple_files_2.log LICENSE lib/request_log_analyzer/source/database_loader.rb spec/unit/tracker/frequency_tracker_spec.rb spec/unit/file_format/rails_format_spec.rb lib/cli/command_line_arguments.rb)
|
|
35
|
+
s.test_files = %w(spec/unit/filter/anonymize_filter_spec.rb spec/unit/file_format/file_format_api_spec.rb spec/unit/file_format/apache_format_spec.rb spec/integration/command_line_usage_spec.rb spec/unit/filter/timespan_filter_spec.rb spec/unit/aggregator/database_inserter_spec.rb spec/unit/tracker/tracker_api_spec.rb spec/unit/tracker/duration_tracker_spec.rb spec/unit/file_format/amazon_s3_format_spec.rb spec/unit/controller/log_processor_spec.rb spec/unit/filter/filter_spec.rb spec/unit/tracker/traffic_tracker_spec.rb spec/unit/filter/field_filter_spec.rb spec/unit/database/base_class_spec.rb spec/unit/tracker/timespan_tracker_spec.rb spec/unit/tracker/hourly_spread_spec.rb spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/line_definition_spec.rb spec/unit/database/connection_spec.rb spec/unit/controller/controller_spec.rb spec/unit/source/request_spec.rb spec/unit/source/log_parser_spec.rb spec/unit/database/database_spec.rb spec/unit/aggregator/summarizer_spec.rb spec/unit/tracker/frequency_tracker_spec.rb spec/unit/file_format/rails_format_spec.rb)
|
|
36
36
|
end
|
data/spec/database.yml
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
# This file determines what databases are used to test the database
|
|
2
|
+
# functionality of request-log-analyzer. By default, only an SQLite3
|
|
3
|
+
# memory database is enabled.
|
|
4
|
+
#
|
|
5
|
+
# The syntax of this file is exactly the same as Rails's database.yml.
|
|
6
|
+
|
|
1
7
|
sqlite3:
|
|
2
8
|
adapter: "sqlite3"
|
|
3
9
|
database: ":memory:"
|
data/spec/lib/mocks.rb
CHANGED
|
@@ -25,7 +25,7 @@ module RequestLogAnalyzer::Spec::Mocks
|
|
|
25
25
|
def mock_io
|
|
26
26
|
mio = mock('IO')
|
|
27
27
|
mio.stub!(:print)
|
|
28
|
-
mio.stub!(:puts)
|
|
28
|
+
mio.stub!(:puts)
|
|
29
29
|
mio.stub!(:write)
|
|
30
30
|
return mio
|
|
31
31
|
end
|
|
@@ -35,12 +35,15 @@ module RequestLogAnalyzer::Spec::Mocks
|
|
|
35
35
|
output.stub!(:header)
|
|
36
36
|
output.stub!(:footer)
|
|
37
37
|
output.stub!(:puts)
|
|
38
|
-
output.stub!(:<<)
|
|
38
|
+
output.stub!(:<<)
|
|
39
|
+
output.stub!(:colorize).and_return("Fancy text")
|
|
40
|
+
output.stub!(:link)
|
|
39
41
|
output.stub!(:title)
|
|
40
42
|
output.stub!(:line)
|
|
41
43
|
output.stub!(:with_style)
|
|
42
44
|
output.stub!(:table).and_yield([])
|
|
43
45
|
output.stub!(:io).and_return(mock_io)
|
|
46
|
+
|
|
44
47
|
return output
|
|
45
48
|
end
|
|
46
49
|
|
|
@@ -66,7 +66,7 @@ describe RequestLogAnalyzer::Aggregator::DatabaseInserter do
|
|
|
66
66
|
it "should insert a record in the request table" do
|
|
67
67
|
lambda {
|
|
68
68
|
@database_inserter.aggregate(@incomplete_request)
|
|
69
|
-
}.should change(
|
|
69
|
+
}.should change(RequestLogAnalyzer::Database::Request, :count).from(0).to(1)
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
it "should insert a record in the first_lines table" do
|
|
@@ -77,7 +77,7 @@ describe RequestLogAnalyzer::Aggregator::DatabaseInserter do
|
|
|
77
77
|
|
|
78
78
|
it "should insert records in all relevant line tables" do
|
|
79
79
|
@database_inserter.aggregate(@completed_request)
|
|
80
|
-
request =
|
|
80
|
+
request = RequestLogAnalyzer::Database::Request.first
|
|
81
81
|
request.should have(2).test_lines
|
|
82
82
|
request.should have(1).first_lines
|
|
83
83
|
request.should have(1).eval_lines
|
|
@@ -85,7 +85,7 @@ describe RequestLogAnalyzer::Aggregator::DatabaseInserter do
|
|
|
85
85
|
end
|
|
86
86
|
|
|
87
87
|
it "should log a warning in the warnings table" do
|
|
88
|
-
|
|
88
|
+
RequestLogAnalyzer::Database::Warning.should_receive(:create!).with(hash_including(:warning_type => 'test_warning'))
|
|
89
89
|
@database_inserter.warning(:test_warning, "Testing the warning system", 12)
|
|
90
90
|
end
|
|
91
91
|
end
|
|
@@ -15,16 +15,13 @@ describe RequestLogAnalyzer::Database::Base do
|
|
|
15
15
|
@orm_class.stub!(:belongs_to)
|
|
16
16
|
@orm_class.stub!(:serialize)
|
|
17
17
|
@orm_class.stub!(:line_definition=)
|
|
18
|
+
|
|
18
19
|
Class.stub!(:new).with(RequestLogAnalyzer::Database::Base).and_return(@orm_class)
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
@source_class = mock('Source ActiveRecord::Base class')
|
|
23
|
-
@source_class.stub!(:has_many)
|
|
21
|
+
RequestLogAnalyzer::Database::Request.stub!(:has_many)
|
|
22
|
+
RequestLogAnalyzer::Database::Source.stub!(:has_many)
|
|
24
23
|
|
|
25
24
|
@database = mock_database
|
|
26
|
-
@database.stub!(:request_class).and_return(@request_class)
|
|
27
|
-
@database.stub!(:source_class).and_return(@source_class)
|
|
28
25
|
RequestLogAnalyzer::Database::Base.stub!(:database).and_return(@database)
|
|
29
26
|
end
|
|
30
27
|
|
|
@@ -49,12 +46,12 @@ describe RequestLogAnalyzer::Database::Base do
|
|
|
49
46
|
end
|
|
50
47
|
|
|
51
48
|
it "should set a :has_many relationship in the request class" do
|
|
52
|
-
|
|
49
|
+
RequestLogAnalyzer::Database::Request.should_receive(:has_many).with(:test_lines)
|
|
53
50
|
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
|
54
51
|
end
|
|
55
52
|
|
|
56
53
|
it "should set a :has_many relationship in the source class" do
|
|
57
|
-
|
|
54
|
+
RequestLogAnalyzer::Database::Source.should_receive(:has_many).with(:test_lines)
|
|
58
55
|
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
|
59
56
|
end
|
|
60
57
|
|
|
@@ -73,14 +70,10 @@ describe RequestLogAnalyzer::Database::Base do
|
|
|
73
70
|
describe '.subclass_from_table' do
|
|
74
71
|
before(:each) do
|
|
75
72
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
@source_class = mock('Source ActiveRecord::Base class')
|
|
79
|
-
@source_class.stub!(:has_many)
|
|
73
|
+
RequestLogAnalyzer::Database::Request.stub!(:has_many)
|
|
74
|
+
RequestLogAnalyzer::Database::Source.stub!(:has_many)
|
|
80
75
|
|
|
81
76
|
@database = mock_database
|
|
82
|
-
@database.stub!(:request_class).and_return(@request_class)
|
|
83
|
-
@database.stub!(:source_class).and_return(@source_class)
|
|
84
77
|
@database.connection.stub!(:table_exists?).and_return(true)
|
|
85
78
|
RequestLogAnalyzer::Database::Base.stub!(:database).and_return(@database)
|
|
86
79
|
|
|
@@ -107,7 +100,7 @@ describe RequestLogAnalyzer::Database::Base do
|
|
|
107
100
|
end
|
|
108
101
|
|
|
109
102
|
it "should create the :has_many relation in the request class" do
|
|
110
|
-
|
|
103
|
+
RequestLogAnalyzer::Database::Request.should_receive(:has_many).with(:completed_lines)
|
|
111
104
|
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
|
112
105
|
end
|
|
113
106
|
|
|
@@ -117,7 +110,7 @@ describe RequestLogAnalyzer::Database::Base do
|
|
|
117
110
|
end
|
|
118
111
|
|
|
119
112
|
it "should create the :has_many relation in the request class" do
|
|
120
|
-
|
|
113
|
+
RequestLogAnalyzer::Database::Source.should_receive(:has_many).with(:completed_lines)
|
|
121
114
|
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
|
122
115
|
end
|
|
123
116
|
|
|
@@ -15,11 +15,11 @@ describe RequestLogAnalyzer::Database do
|
|
|
15
15
|
# FileFormat-agnostic classes
|
|
16
16
|
default_orm_class_names.each do |const|
|
|
17
17
|
it "should create the default #{const} constant" do
|
|
18
|
-
|
|
18
|
+
RequestLogAnalyzer::Database.const_defined?(const).should be_true
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
it "should create the default #{const} class inheriting from ActiveRecord::Base and RequestLogAnalyzer::Database::Base" do
|
|
22
|
-
|
|
22
|
+
RequestLogAnalyzer::Database.const_get(const).ancestors.should include(ActiveRecord::Base, RequestLogAnalyzer::Database::Base)
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -38,8 +38,8 @@ describe RequestLogAnalyzer::Database do
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it "should create a :has_many relation from the Request and Source class to the #{const} class" do
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
RequestLogAnalyzer::Database::Request.send(:reflections).should include(const.underscore.pluralize.to_sym)
|
|
42
|
+
RequestLogAnalyzer::Database::Source.send(:reflections).should include(const.underscore.pluralize.to_sym)
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
end
|
|
@@ -60,6 +60,7 @@ describe RequestLogAnalyzer::Database do
|
|
|
60
60
|
after(:each) { @database.remove_orm_classes! }
|
|
61
61
|
|
|
62
62
|
default_orm_class_names.each do |klass|
|
|
63
|
+
|
|
63
64
|
it "should create a table for the default #{klass} class" do
|
|
64
65
|
@database.connection.should_receive(:create_table).with(klass.underscore.pluralize.to_sym)
|
|
65
66
|
@database.send :create_database_schema!
|
|
@@ -67,7 +68,7 @@ describe RequestLogAnalyzer::Database do
|
|
|
67
68
|
|
|
68
69
|
it "should create a #{klass} class inheriting from ActiveRecord and the base class of the ORM module" do
|
|
69
70
|
@database.send :create_database_schema!
|
|
70
|
-
|
|
71
|
+
RequestLogAnalyzer::Database.const_get(klass).ancestors.should include(ActiveRecord::Base, RequestLogAnalyzer::Database::Base)
|
|
71
72
|
end
|
|
72
73
|
end
|
|
73
74
|
|
|
@@ -92,15 +93,9 @@ describe RequestLogAnalyzer::Database do
|
|
|
92
93
|
@connection = mock_connection
|
|
93
94
|
@database.stub!(:connection).and_return(@connection)
|
|
94
95
|
|
|
95
|
-
# Mock the
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
@source_class = mock('Source ActiveRecord::Base class')
|
|
100
|
-
@source_class.stub!(:has_many)
|
|
101
|
-
|
|
102
|
-
@database.stub!(:request_class).and_return(@request_class)
|
|
103
|
-
@database.stub!(:source_class).and_return(@source_class)
|
|
96
|
+
# Mock the has_many method of the defaukt ORM classes
|
|
97
|
+
RequestLogAnalyzer::Database::Request.stub!(:has_many)
|
|
98
|
+
RequestLogAnalyzer::Database::Source.stub!(:has_many)
|
|
104
99
|
|
|
105
100
|
@mock_class = Class.new(RequestLogAnalyzer::Database::Base)
|
|
106
101
|
|
|
@@ -99,12 +99,49 @@ describe RequestLogAnalyzer::FileFormat::Apache do
|
|
|
99
99
|
@log_parser.parse_file(log_fixture(:apache_common)) { counter.hit! }
|
|
100
100
|
end
|
|
101
101
|
end
|
|
102
|
+
|
|
103
|
+
context '"Rack" access log parser' do
|
|
104
|
+
before(:each) do
|
|
105
|
+
@file_format = RequestLogAnalyzer::FileFormat.load(:rack)
|
|
106
|
+
@log_parser = RequestLogAnalyzer::Source::LogParser.new(@file_format)
|
|
107
|
+
@sample_1 = '127.0.0.1 - - [16/Sep/2009 06:40:08] "GET /favicon.ico HTTP/1.1" 500 63183 0.0453'
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "should create a kind of an Apache file format" do
|
|
111
|
+
@file_format.should be_kind_of(RequestLogAnalyzer::FileFormat::Apache)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "should have a valid language definitions" do
|
|
115
|
+
@file_format.should be_valid
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "should parse a valid access log line" do
|
|
119
|
+
@file_format.line_definitions[:access].matches(@sample_1).should be_kind_of(Hash)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
it "should not parse a valid access log line" do
|
|
123
|
+
@file_format.line_definitions[:access].matches('addasdsasadadssadasd').should be_false
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "should read the correct values from a valid 404 access log line" do
|
|
127
|
+
@log_parser.parse_io(StringIO.new(@sample_1)) do |request|
|
|
128
|
+
request[:remote_host].should == '127.0.0.1'
|
|
129
|
+
request[:timestamp].should == 20090916064008
|
|
130
|
+
request[:http_status].should == 500
|
|
131
|
+
request[:http_method].should == 'GET'
|
|
132
|
+
request[:http_version].should == '1.1'
|
|
133
|
+
request[:bytes_sent].should == 63183
|
|
134
|
+
request[:user].should == nil
|
|
135
|
+
request[:duration].should == 0.0453
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
102
139
|
|
|
103
140
|
context '"Combined" access log parsing' do
|
|
104
141
|
|
|
105
142
|
before(:all) do
|
|
106
143
|
@file_format = RequestLogAnalyzer::FileFormat.load(:apache, :combined)
|
|
107
|
-
@log_parser
|
|
144
|
+
@log_parser = RequestLogAnalyzer::Source::LogParser.new(@file_format)
|
|
108
145
|
@sample_1 = '69.41.0.45 - - [02/Sep/2009:12:02:40 +0200] "GET //phpMyAdmin/ HTTP/1.1" 404 209 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)"'
|
|
109
146
|
@sample_2 = '10.0.1.1 - - [02/Sep/2009:05:08:33 +0200] "GET / HTTP/1.1" 200 30 "-" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9"'
|
|
110
147
|
end
|
|
@@ -1,49 +1,124 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
2
|
|
|
3
|
-
describe RequestLogAnalyzer::Tracker::Base
|
|
3
|
+
describe RequestLogAnalyzer::Tracker::Base do
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
@tracker = Class.new(RequestLogAnalyzer::Tracker::Base).new
|
|
5
|
+
describe 'API' do
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
+
@tracker.should_receive(:report).with(anything).once
|
|
37
|
+
@summarizer.report(mock_output)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should receieve :finalize when the summarizer is finalizing" do
|
|
41
|
+
@tracker.should_receive(:finalize).once
|
|
42
|
+
@summarizer.finalize
|
|
43
|
+
end
|
|
20
44
|
end
|
|
21
45
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
46
|
+
describe '#should_update?' do
|
|
47
|
+
before(:each) do
|
|
48
|
+
@tracker_class = Class.new(RequestLogAnalyzer::Tracker::Base)
|
|
49
|
+
end
|
|
25
50
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
it "should not :update for every request for which should_update? returns false" do
|
|
31
|
-
@tracker.should_receive(:should_update?).twice.and_return(false)
|
|
32
|
-
@tracker.should_not_receive(:update)
|
|
51
|
+
it "should return true by default, when no checks are installed" do
|
|
52
|
+
tracker = @tracker_class.new
|
|
53
|
+
tracker.should_update?(testing_format.request).should be_true
|
|
54
|
+
end
|
|
33
55
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
56
|
+
it "should return false if the line type is not in the request" do
|
|
57
|
+
tracker = @tracker_class.new(:line_type => :not_there)
|
|
58
|
+
tracker.should_update?(request(:line_type => :different)).should be_false
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "should return true if the line type is in the request" do
|
|
62
|
+
tracker = @tracker_class.new(:line_type => :there)
|
|
63
|
+
tracker.should_update?(request(:line_type => :there)).should be_true
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "should return true if a field name is given to :if and it is in the request" do
|
|
67
|
+
tracker = @tracker_class.new(:if => :field)
|
|
68
|
+
tracker.should_update?(request(:field => 'anything')).should be_true
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should return false if a field name is given to :if and it is not the request" do
|
|
72
|
+
tracker = @tracker_class.new(:if => :field)
|
|
73
|
+
tracker.should_update?(request(:other_field => 'anything')).should be_false
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should return false if a field name is given to :unless and it is in the request" do
|
|
77
|
+
tracker = @tracker_class.new(:unless => :field)
|
|
78
|
+
tracker.should_update?(request(:field => 'anything')).should be_false
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "should return true if a field name is given to :unless and it is not the request" do
|
|
82
|
+
tracker = @tracker_class.new(:unless => :field)
|
|
83
|
+
tracker.should_update?(request(:other_field => 'anything')).should be_true
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "should return the value of the block if one is given to the :if option" do
|
|
87
|
+
tracker = @tracker_class.new(:if => lambda { false } )
|
|
88
|
+
tracker.should_update?(request(:field => 'anything')).should be_false
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "should return the inverse value of the block if one is given to the :if option" do
|
|
92
|
+
tracker = @tracker_class.new(:unless => lambda { false } )
|
|
93
|
+
tracker.should_update?(request(:field => 'anything')).should be_true
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "should return false if any of the checks fail" do
|
|
97
|
+
tracker = @tracker_class.new(:if => :field, :unless => lambda { false }, :line_type => :not_present )
|
|
98
|
+
tracker.should_update?(request(:line_type => :present, :field => 'anything')).should be_false
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
it "should return true if all of the checks succeed" do
|
|
102
|
+
tracker = @tracker_class.new(:if => :field, :unless => lambda { false }, :line_type => :present )
|
|
103
|
+
tracker.should_update?(request(:line_type => :present, :field => 'anything')).should be_true
|
|
104
|
+
end
|
|
105
|
+
|
|
37
106
|
|
|
38
|
-
it "should receive :report when the summary report is being built" do
|
|
39
|
-
@tracker.should_receive(:report).with(anything).once
|
|
40
|
-
@summarizer.report(mock_output)
|
|
41
107
|
end
|
|
42
108
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
109
|
+
describe '#to_yaml_object' do
|
|
110
|
+
|
|
111
|
+
before(:each) do
|
|
112
|
+
@tracker = Class.new(RequestLogAnalyzer::Tracker::Base).new
|
|
113
|
+
|
|
114
|
+
@summarizer = RequestLogAnalyzer::Aggregator::Summarizer.new(mock_source)
|
|
115
|
+
@summarizer.trackers << @tracker
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "should receive :to_yaml object when finalizing" do
|
|
119
|
+
@summarizer.options[:dump] = temp_output_file(:dump)
|
|
120
|
+
@tracker.should_receive(:to_yaml_object).once
|
|
121
|
+
@summarizer.to_yaml
|
|
122
|
+
end
|
|
47
123
|
end
|
|
48
|
-
|
|
49
124
|
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
|
2
|
+
|
|
3
|
+
describe RequestLogAnalyzer::Tracker::Traffic do
|
|
4
|
+
|
|
5
|
+
describe '#update' do
|
|
6
|
+
|
|
7
|
+
context 'using a field-based category' do
|
|
8
|
+
before(:each) do
|
|
9
|
+
@tracker = RequestLogAnalyzer::Tracker::Traffic.new(:traffic => :traffic, :category => :category)
|
|
10
|
+
@tracker.prepare
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should register a request in the right category" do
|
|
14
|
+
@tracker.update(request(:category => 'a', :traffic => 200))
|
|
15
|
+
@tracker.categories.should include('a')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should register a hit in the right category" do
|
|
19
|
+
@tracker.update(request(:category => 'a', :traffic => 1))
|
|
20
|
+
@tracker.update(request(:category => 'b', :traffic => 2))
|
|
21
|
+
@tracker.update(request(:category => 'b', :traffic => 3))
|
|
22
|
+
|
|
23
|
+
@tracker.hits('a').should == 1
|
|
24
|
+
@tracker.hits('b').should == 2
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should sum the traffics of the same category as cumulative traffic" do
|
|
28
|
+
@tracker.update(request(:category => 'a', :traffic => 1))
|
|
29
|
+
@tracker.update(request(:category => 'b', :traffic => 2))
|
|
30
|
+
@tracker.update(request(:category => 'b', :traffic => 3))
|
|
31
|
+
|
|
32
|
+
@tracker.cumulative_traffic('a').should == 1
|
|
33
|
+
@tracker.cumulative_traffic('b').should == 5
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "should calculate the average traffic correctly" do
|
|
37
|
+
@tracker.update(request(:category => 'a', :traffic => 1))
|
|
38
|
+
@tracker.update(request(:category => 'b', :traffic => 2))
|
|
39
|
+
@tracker.update(request(:category => 'b', :traffic => 3))
|
|
40
|
+
|
|
41
|
+
@tracker.average_traffic('a').should == 1.0
|
|
42
|
+
@tracker.average_traffic('b').should == 2.5
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "should set min and max traffic correctly" do
|
|
46
|
+
@tracker.update(request(:category => 'a', :traffic => 1))
|
|
47
|
+
@tracker.update(request(:category => 'b', :traffic => 2))
|
|
48
|
+
@tracker.update(request(:category => 'b', :traffic => 3))
|
|
49
|
+
|
|
50
|
+
@tracker.min_traffic('b').should == 2
|
|
51
|
+
@tracker.max_traffic('b').should == 3
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context 'using a dynamic category' do
|
|
57
|
+
before(:each) do
|
|
58
|
+
@categorizer = Proc.new { |request| request[:traffic] < 2 ? 'few' : 'lots' }
|
|
59
|
+
@tracker = RequestLogAnalyzer::Tracker::Traffic.new(:traffic => :traffic, :category => @categorizer)
|
|
60
|
+
@tracker.prepare
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "should use the categorizer to determine the right category" do
|
|
64
|
+
@tracker.update(request(:category => 'a', :traffic => 1))
|
|
65
|
+
@tracker.update(request(:category => 'b', :traffic => 2))
|
|
66
|
+
@tracker.update(request(:category => 'b', :traffic => 3))
|
|
67
|
+
|
|
68
|
+
@tracker.categories.should include('few', 'lots')
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should use the categorizer to aggregate the values correctly" do
|
|
72
|
+
@tracker.update(request(:category => 'a', :traffic => 1))
|
|
73
|
+
@tracker.update(request(:category => 'b', :traffic => 2))
|
|
74
|
+
@tracker.update(request(:category => 'b', :traffic => 3))
|
|
75
|
+
|
|
76
|
+
@tracker.max_traffic('few').should == 1
|
|
77
|
+
@tracker.min_traffic('lots').should == 2
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
describe '#report' do
|
|
83
|
+
before(:each) do
|
|
84
|
+
@tracker = RequestLogAnalyzer::Tracker::Traffic.new(:category => :category, :traffic => :traffic)
|
|
85
|
+
@tracker.prepare
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "should generate a report without errors when one category is present" do
|
|
89
|
+
@tracker.update(request(:category => 'a', :traffic => 2))
|
|
90
|
+
@tracker.report(mock_output)
|
|
91
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
it "should generate a report without errors when no category is present" do
|
|
95
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "should generate a report without errors when multiple categories are present" do
|
|
99
|
+
@tracker.update(request(:category => 'a', :traffic => 2))
|
|
100
|
+
@tracker.update(request(:category => 'b', :traffic => 2))
|
|
101
|
+
lambda { @tracker.report(mock_output) }.should_not raise_error
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: request-log-analyzer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Willem van Bergen
|
|
@@ -10,7 +10,7 @@ autorequire:
|
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
12
|
|
|
13
|
-
date: 2009-09-
|
|
13
|
+
date: 2009-09-20 00:00:00 +02:00
|
|
14
14
|
default_executable: request-log-analyzer
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
@@ -45,10 +45,10 @@ extra_rdoc_files:
|
|
|
45
45
|
- README.rdoc
|
|
46
46
|
files:
|
|
47
47
|
- spec/unit/filter/anonymize_filter_spec.rb
|
|
48
|
+
- spec/fixtures/rails_22_cached.log
|
|
48
49
|
- lib/request_log_analyzer/line_definition.rb
|
|
49
50
|
- lib/request_log_analyzer/output/html.rb
|
|
50
51
|
- lib/request_log_analyzer/controller.rb
|
|
51
|
-
- spec/fixtures/rails_22_cached.log
|
|
52
52
|
- spec/lib/macros.rb
|
|
53
53
|
- lib/request_log_analyzer/file_format/rails_development.rb
|
|
54
54
|
- spec/fixtures/apache_combined.log
|
|
@@ -61,10 +61,10 @@ files:
|
|
|
61
61
|
- spec/integration/command_line_usage_spec.rb
|
|
62
62
|
- lib/request_log_analyzer/database.rb
|
|
63
63
|
- spec/fixtures/decompression.log.bz2
|
|
64
|
+
- spec/fixtures/rails_unordered.log
|
|
64
65
|
- lib/request_log_analyzer/log_processor.rb
|
|
65
66
|
- lib/request_log_analyzer/tracker.rb
|
|
66
67
|
- lib/request_log_analyzer/filter.rb
|
|
67
|
-
- spec/fixtures/rails_unordered.log
|
|
68
68
|
- bin/request-log-analyzer
|
|
69
69
|
- request-log-analyzer.gemspec
|
|
70
70
|
- DESIGN.rdoc
|
|
@@ -86,6 +86,7 @@ files:
|
|
|
86
86
|
- lib/cli/progressbar.rb
|
|
87
87
|
- lib/request_log_analyzer/mailer.rb
|
|
88
88
|
- README.rdoc
|
|
89
|
+
- lib/request_log_analyzer/database/warning.rb
|
|
89
90
|
- spec/fixtures/merb.log
|
|
90
91
|
- lib/request_log_analyzer/tracker/hourly_spread.rb
|
|
91
92
|
- .gitignore
|
|
@@ -103,8 +104,11 @@ files:
|
|
|
103
104
|
- spec/fixtures/test_language_combined.log
|
|
104
105
|
- lib/request_log_analyzer/aggregator/database_inserter.rb
|
|
105
106
|
- lib/request_log_analyzer/aggregator/summarizer.rb
|
|
107
|
+
- lib/request_log_analyzer/file_format/rack.rb
|
|
108
|
+
- lib/request_log_analyzer/database/source.rb
|
|
106
109
|
- lib/request_log_analyzer/file_format/rails.rb
|
|
107
110
|
- spec/fixtures/decompression.tar.gz
|
|
111
|
+
- spec/unit/tracker/traffic_tracker_spec.rb
|
|
108
112
|
- spec/unit/filter/field_filter_spec.rb
|
|
109
113
|
- spec/unit/database/base_class_spec.rb
|
|
110
114
|
- lib/request_log_analyzer/filter/timespan.rb
|
|
@@ -125,10 +129,10 @@ files:
|
|
|
125
129
|
- spec/unit/controller/controller_spec.rb
|
|
126
130
|
- spec/lib/mocks.rb
|
|
127
131
|
- spec/lib/helpers.rb
|
|
132
|
+
- spec/fixtures/rails_1x.log
|
|
128
133
|
- lib/cli/database_console_init.rb
|
|
129
134
|
- lib/request_log_analyzer/output.rb
|
|
130
135
|
- lib/request_log_analyzer/file_format/apache.rb
|
|
131
|
-
- spec/fixtures/rails_1x.log
|
|
132
136
|
- spec/fixtures/decompression.log.zip
|
|
133
137
|
- spec/unit/source/request_spec.rb
|
|
134
138
|
- spec/unit/source/log_parser_spec.rb
|
|
@@ -136,11 +140,13 @@ files:
|
|
|
136
140
|
- tasks/github-gem.rake
|
|
137
141
|
- spec/unit/database/database_spec.rb
|
|
138
142
|
- lib/request_log_analyzer/tracker/duration.rb
|
|
143
|
+
- lib/request_log_analyzer/tracker/traffic.rb
|
|
139
144
|
- lib/request_log_analyzer/file_format.rb
|
|
140
145
|
- spec/unit/aggregator/summarizer_spec.rb
|
|
146
|
+
- spec/fixtures/syslog_1x.log
|
|
141
147
|
- spec/fixtures/rails_22.log
|
|
148
|
+
- lib/request_log_analyzer/database/request.rb
|
|
142
149
|
- spec/fixtures/multiple_files_2.log
|
|
143
|
-
- spec/fixtures/syslog_1x.log
|
|
144
150
|
- LICENSE
|
|
145
151
|
- lib/request_log_analyzer/source/database_loader.rb
|
|
146
152
|
- spec/unit/tracker/frequency_tracker_spec.rb
|
|
@@ -191,6 +197,7 @@ test_files:
|
|
|
191
197
|
- spec/unit/file_format/amazon_s3_format_spec.rb
|
|
192
198
|
- spec/unit/controller/log_processor_spec.rb
|
|
193
199
|
- spec/unit/filter/filter_spec.rb
|
|
200
|
+
- spec/unit/tracker/traffic_tracker_spec.rb
|
|
194
201
|
- spec/unit/filter/field_filter_spec.rb
|
|
195
202
|
- spec/unit/database/base_class_spec.rb
|
|
196
203
|
- spec/unit/tracker/timespan_tracker_spec.rb
|