request-log-analyzer 1.2.9 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/request-log-analyzer +33 -19
- data/lib/cli/database_console.rb +26 -0
- data/lib/cli/database_console_init.rb +42 -0
- data/lib/cli/tools.rb +1 -1
- data/lib/request_log_analyzer/aggregator/database_inserter.rb +81 -0
- data/lib/request_log_analyzer/aggregator/summarizer.rb +2 -2
- data/lib/request_log_analyzer/aggregator.rb +4 -0
- data/lib/request_log_analyzer/controller.rb +23 -7
- 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.rb +177 -0
- data/lib/request_log_analyzer/file_format.rb +6 -3
- data/lib/request_log_analyzer/mailer.rb +46 -0
- data/lib/request_log_analyzer/request.rb +2 -1
- data/lib/request_log_analyzer/source/{database.rb → database_loader.rb} +1 -1
- data/lib/request_log_analyzer/source/log_parser.rb +28 -15
- data/lib/request_log_analyzer/source.rb +7 -2
- data/lib/request_log_analyzer.rb +5 -8
- data/request-log-analyzer.gemspec +8 -8
- data/spec/database.yml +17 -0
- data/spec/fixtures/rails.db +0 -0
- data/spec/integration/command_line_usage_spec.rb +14 -9
- data/spec/lib/macros.rb +16 -0
- data/spec/lib/mocks.rb +18 -6
- data/spec/unit/aggregator/database_inserter_spec.rb +93 -0
- data/spec/unit/database/base_class_spec.rb +190 -0
- data/spec/unit/database/connection_spec.rb +34 -0
- data/spec/unit/database/database_spec.rb +138 -0
- data/spec/unit/source/log_parser_spec.rb +12 -0
- metadata +29 -16
- data/lib/request_log_analyzer/aggregator/database.rb +0 -220
- data/spec/spec.opts +0 -3
- data/spec/unit/aggregator/database_spec.rb +0 -245
@@ -0,0 +1,93 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe RequestLogAnalyzer::Aggregator::DatabaseInserter do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
@log_parser = RequestLogAnalyzer::Source::LogParser.new(testing_format)
|
7
|
+
end
|
8
|
+
|
9
|
+
# The prepare method is called before the parsing starts. It should establish a connection
|
10
|
+
# to a database that is suitable for inserting requests later on.
|
11
|
+
describe '#prepare' do
|
12
|
+
|
13
|
+
before(:each) do
|
14
|
+
@database = mock_database(:create_database_schema!, :drop_database_schema!, :file_format=)
|
15
|
+
@database_inserter = RequestLogAnalyzer::Aggregator::DatabaseInserter.new(@log_parser)
|
16
|
+
RequestLogAnalyzer::Database.stub!(:new).and_return(@database)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should establish the database connection' do
|
20
|
+
RequestLogAnalyzer::Database.should_receive(:new).and_return(@database)
|
21
|
+
@database_inserter.prepare
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should set the file_format" do
|
25
|
+
@database.should_receive(:file_format=).with(testing_format)
|
26
|
+
@database_inserter.prepare
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should create the database schema during preparation' do
|
30
|
+
@database.should_receive(:create_database_schema!)
|
31
|
+
@database_inserter.prepare
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should not drop the database schema during preparation if not requested' do
|
35
|
+
@database.should_not_receive(:drop_database_schema!)
|
36
|
+
@database_inserter.prepare
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should drop the database schema during preparation if requested' do
|
40
|
+
@database_inserter.options[:reset_database] = true
|
41
|
+
@database.should_receive(:drop_database_schema!)
|
42
|
+
@database_inserter.prepare
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
test_databases.each do |name, connection|
|
47
|
+
|
48
|
+
context "using a #{name} database" do
|
49
|
+
|
50
|
+
before(:each) do
|
51
|
+
@database_inserter = RequestLogAnalyzer::Aggregator::DatabaseInserter.new(@log_parser, :database => connection, :reset_database => true)
|
52
|
+
@database_inserter.prepare
|
53
|
+
|
54
|
+
@incomplete_request = testing_format.request( {:line_type => :first, :request_no => 564})
|
55
|
+
@completed_request = testing_format.request( {:line_type => :first, :request_no => 564},
|
56
|
+
{:line_type => :test, :test_capture => "awesome"},
|
57
|
+
{:line_type => :test, :test_capture => "indeed"},
|
58
|
+
{:line_type => :eval, :evaluated => { :greating => 'howdy'}, :greating => 'howdy' },
|
59
|
+
{:line_type => :last, :request_no => 564})
|
60
|
+
end
|
61
|
+
|
62
|
+
after(:each) do
|
63
|
+
@database_inserter.database.send :remove_orm_classes!
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should insert a record in the request table" do
|
67
|
+
lambda {
|
68
|
+
@database_inserter.aggregate(@incomplete_request)
|
69
|
+
}.should change(@database_inserter.database.request_class, :count).from(0).to(1)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should insert a record in the first_lines table" do
|
73
|
+
lambda {
|
74
|
+
@database_inserter.aggregate(@incomplete_request)
|
75
|
+
}.should change(@database_inserter.database.get_class(:first), :count).from(0).to(1)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should insert records in all relevant line tables" do
|
79
|
+
@database_inserter.aggregate(@completed_request)
|
80
|
+
request = @database_inserter.database.request_class.first
|
81
|
+
request.should have(2).test_lines
|
82
|
+
request.should have(1).first_lines
|
83
|
+
request.should have(1).eval_lines
|
84
|
+
request.should have(1).last_lines
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should log a warning in the warnings table" do
|
88
|
+
@database_inserter.database.warning_class.should_receive(:create!).with(hash_including(:warning_type => 'test_warning'))
|
89
|
+
@database_inserter.warning(:test_warning, "Testing the warning system", 12)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,190 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe RequestLogAnalyzer::Database::Base do
|
4
|
+
|
5
|
+
describe '.subclass_from_line_definition' do
|
6
|
+
before(:all) do
|
7
|
+
@line_definition = RequestLogAnalyzer::LineDefinition.new(:test, { :regexp => /Testing (\w+), tries\: (\d+)/,
|
8
|
+
:captures => [{ :name => :what, :type => :string }, { :name => :tries, :type => :integer },
|
9
|
+
{ :name => :evaluated, :type => :hash, :provides => {:evaluated_field => :duration} }]})
|
10
|
+
end
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
@orm_class = mock('Line ActiveRecord::Base class')
|
14
|
+
@orm_class.stub!(:set_table_name)
|
15
|
+
@orm_class.stub!(:belongs_to)
|
16
|
+
@orm_class.stub!(:serialize)
|
17
|
+
@orm_class.stub!(:line_definition=)
|
18
|
+
Class.stub!(:new).with(RequestLogAnalyzer::Database::Base).and_return(@orm_class)
|
19
|
+
|
20
|
+
@request_class = mock('Request ActiveRecord::Base class')
|
21
|
+
@request_class.stub!(:has_many)
|
22
|
+
@source_class = mock('Source ActiveRecord::Base class')
|
23
|
+
@source_class.stub!(:has_many)
|
24
|
+
|
25
|
+
@database = mock_database
|
26
|
+
@database.stub!(:request_class).and_return(@request_class)
|
27
|
+
@database.stub!(:source_class).and_return(@source_class)
|
28
|
+
RequestLogAnalyzer::Database::Base.stub!(:database).and_return(@database)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should create a new subclass using the Base class as parent" do
|
32
|
+
Class.should_receive(:new).with(RequestLogAnalyzer::Database::Base).and_return(@orm_class)
|
33
|
+
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should store the LineDefinition" do
|
37
|
+
@orm_class.should_receive(:line_definition=).with(@line_definition)
|
38
|
+
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should set the table name for the subclass" do
|
42
|
+
@orm_class.should_receive(:set_table_name).with('test_lines')
|
43
|
+
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should set the :belongs_to relationship with the Request class" do
|
47
|
+
@orm_class.should_receive(:belongs_to).with(:request)
|
48
|
+
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should set a :has_many relationship in the request class" do
|
52
|
+
@request_class.should_receive(:has_many).with(:test_lines)
|
53
|
+
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should set a :has_many relationship in the source class" do
|
57
|
+
@source_class.should_receive(:has_many).with(:test_lines)
|
58
|
+
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should set the :belongs_to relationship with the Source class" do
|
62
|
+
@orm_class.should_receive(:belongs_to).with(:source)
|
63
|
+
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should serialize a complex field" do
|
67
|
+
@orm_class.should_receive(:serialize).with(:evaluated, Hash)
|
68
|
+
RequestLogAnalyzer::Database::Base.subclass_from_line_definition(@line_definition)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '.subclass_from_table' do
|
74
|
+
before(:each) do
|
75
|
+
|
76
|
+
@request_class = mock('Request ActiveRecord::Base class')
|
77
|
+
@request_class.stub!(:has_many)
|
78
|
+
@source_class = mock('Source ActiveRecord::Base class')
|
79
|
+
@source_class.stub!(:has_many)
|
80
|
+
|
81
|
+
@database = mock_database
|
82
|
+
@database.stub!(:request_class).and_return(@request_class)
|
83
|
+
@database.stub!(:source_class).and_return(@source_class)
|
84
|
+
@database.connection.stub!(:table_exists?).and_return(true)
|
85
|
+
RequestLogAnalyzer::Database::Base.stub!(:database).and_return(@database)
|
86
|
+
|
87
|
+
@klass = mock('ActiveRecord ORM class')
|
88
|
+
@klass.stub!(:column_names).and_return(['id', 'request_id', 'source_id', 'lineno', 'duration'])
|
89
|
+
@klass.stub!(:set_table_name)
|
90
|
+
@klass.stub!(:belongs_to)
|
91
|
+
Class.stub!(:new).with(RequestLogAnalyzer::Database::Base).and_return(@klass)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should create a new subclass using the Base class as parent" do
|
95
|
+
Class.should_receive(:new).with(RequestLogAnalyzer::Database::Base).and_return(@klass)
|
96
|
+
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should set the table name" do
|
100
|
+
@klass.should_receive(:set_table_name).with('completed_lines')
|
101
|
+
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should create the :belongs_to relation to the request class" do
|
105
|
+
@klass.should_receive(:belongs_to).with(:request)
|
106
|
+
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should create the :has_many relation in the request class" do
|
110
|
+
@request_class.should_receive(:has_many).with(:completed_lines)
|
111
|
+
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should create the :belongs_to relation to the source class" do
|
115
|
+
@klass.should_receive(:belongs_to).with(:source)
|
116
|
+
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should create the :has_many relation in the request class" do
|
120
|
+
@source_class.should_receive(:has_many).with(:completed_lines)
|
121
|
+
RequestLogAnalyzer::Database::Base.subclass_from_table('completed_lines')
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '#create_table' do
|
127
|
+
|
128
|
+
before(:all) do
|
129
|
+
@line_definition = RequestLogAnalyzer::LineDefinition.new(:test, { :regexp => /Testing (\w+), tries\: (\d+)/,
|
130
|
+
:captures => [{ :name => :what, :type => :string }, { :name => :tries, :type => :integer },
|
131
|
+
{ :name => :evaluated, :type => :hash, :provides => {:evaluated_field => :duration} }]})
|
132
|
+
end
|
133
|
+
|
134
|
+
before(:each) do
|
135
|
+
@database = RequestLogAnalyzer::Database.new
|
136
|
+
@database.stub!(:connection).and_return(mock_connection)
|
137
|
+
@klass = @database.load_activerecord_class(@line_definition)
|
138
|
+
@klass.stub!(:table_exists?).and_return(false)
|
139
|
+
end
|
140
|
+
|
141
|
+
after(:each) do
|
142
|
+
@klass.drop_table!
|
143
|
+
@database.remove_orm_classes!
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should call create_table with the correct table name" do
|
147
|
+
@database.connection.should_receive(:create_table).with(:test_lines)
|
148
|
+
@klass.create_table!
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should not create a table based on the line type name if it already exists" do
|
152
|
+
@klass.stub!(:table_exists?).and_return(true)
|
153
|
+
@database.connection.should_not_receive(:create_table).with(:test_lines)
|
154
|
+
@klass.create_table!
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should create an index on the request_id field" do
|
158
|
+
@database.connection.should_receive(:add_index).with(:test_lines, [:request_id])
|
159
|
+
@klass.create_table!
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should create an index on the source_id field" do
|
163
|
+
@database.connection.should_receive(:add_index).with(:test_lines, [:source_id])
|
164
|
+
@klass.create_table!
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should create a request_id field to link the requests together" do
|
168
|
+
@database.connection.table_creator.should_receive(:column).with(:request_id, :integer)
|
169
|
+
@klass.create_table!
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should create a lineno field to save the location of the line in the original file" do
|
173
|
+
@database.connection.table_creator.should_receive(:column).with(:lineno, :integer)
|
174
|
+
@klass.create_table!
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should create a field of the correct type for every defined capture field" do
|
178
|
+
@database.connection.table_creator.should_receive(:column).with(:what, :string)
|
179
|
+
@database.connection.table_creator.should_receive(:column).with(:tries, :integer)
|
180
|
+
@database.connection.table_creator.should_receive(:column).with(:evaluated, :text)
|
181
|
+
@klass.create_table!
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should create a field of the correct type for every provided field" do
|
185
|
+
@database.connection.table_creator.should_receive(:column).with(:evaluated_field, :double)
|
186
|
+
@klass.create_table!
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe RequestLogAnalyzer::Database::Connection do
|
4
|
+
describe '.from_string' do
|
5
|
+
|
6
|
+
it "should parse a name-value based string" do
|
7
|
+
string = 'adapter=sqlite3;database=filename.db'
|
8
|
+
RequestLogAnalyzer::Database::Connection.from_string(string).should == {:adapter => 'sqlite3', :database => 'filename.db'}
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should parse an URI-based string for SQLite3" do
|
12
|
+
string = 'sqlite3://filename.db'
|
13
|
+
RequestLogAnalyzer::Database::Connection.from_string(string).should == {:adapter => 'sqlite3', :database => 'filename.db'}
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should parse an URI-based string for MySQL" do
|
17
|
+
string = 'mysql://localhost.local/database'
|
18
|
+
RequestLogAnalyzer::Database::Connection.from_string(string).should ==
|
19
|
+
{ :adapter => 'mysql', :database => 'database', :host => 'localhost.local' }
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should parse an URI-based string for MySQL with only username" do
|
23
|
+
string = 'mysql://username@localhost.local/database'
|
24
|
+
RequestLogAnalyzer::Database::Connection.from_string(string).should ==
|
25
|
+
{ :adapter => 'mysql', :database => 'database', :host => 'localhost.local', :username => 'username' }
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should parse an URI-based string for MySQL with username and password" do
|
29
|
+
string = 'mysql://username:password@localhost.local/database'
|
30
|
+
RequestLogAnalyzer::Database::Connection.from_string(string).should ==
|
31
|
+
{ :adapter => 'mysql', :database => 'database', :host => 'localhost.local', :username => 'username', :password => 'password' }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe RequestLogAnalyzer::Database do
|
4
|
+
|
5
|
+
describe '#load_database_schema!' do
|
6
|
+
|
7
|
+
context 'for a Rails request database' do
|
8
|
+
before(:each) do
|
9
|
+
@database = RequestLogAnalyzer::Database.new(log_fixture(:rails, :db))
|
10
|
+
@database.load_database_schema!
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:each) { @database.remove_orm_classes! }
|
14
|
+
|
15
|
+
# FileFormat-agnostic classes
|
16
|
+
default_orm_class_names.each do |const|
|
17
|
+
it "should create the default #{const} constant" do
|
18
|
+
Object.const_defined?(const).should be_true
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should create the default #{const} class inheriting from ActiveRecord::Base and RequestLogAnalyzer::Database::Base" do
|
22
|
+
Object.const_get(const).ancestors.should include(ActiveRecord::Base, RequestLogAnalyzer::Database::Base)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Some Fileformat-specific classes
|
27
|
+
['CompletedLine', 'ProcessingLine'].each do |const|
|
28
|
+
it "should create the #{const} constant" do
|
29
|
+
Object.const_defined?(const).should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should create the #{const} class inheriting from ActiveRecord::Base and RequestLogAnalyzer::Database::Base" do
|
33
|
+
Object.const_get(const).ancestors.should include(ActiveRecord::Base, RequestLogAnalyzer::Database::Base)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should create a :belongs_to relation from the #{const} class to Request and Source" do
|
37
|
+
Object.const_get(const).send(:reflections).should include(:request, :source)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should create a :has_many relation from the Request and Source class to the #{const} class" do
|
41
|
+
@database.request_class.send(:reflections).should include(const.underscore.pluralize.to_sym)
|
42
|
+
@database.source_class.send(:reflections).should include(const.underscore.pluralize.to_sym)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#create_database_schema!' do
|
49
|
+
|
50
|
+
before(:each) do
|
51
|
+
@database = RequestLogAnalyzer::Database.new
|
52
|
+
@database.file_format = testing_format
|
53
|
+
@database.stub!(:connection).and_return(mock_connection)
|
54
|
+
|
55
|
+
# Stub the expected method calls for the preparation, these will be tested separately
|
56
|
+
@mock_class = Class.new(RequestLogAnalyzer::Database::Base)
|
57
|
+
@mock_class.stub!(:create_table!)
|
58
|
+
end
|
59
|
+
|
60
|
+
after(:each) { @database.remove_orm_classes! }
|
61
|
+
|
62
|
+
default_orm_class_names.each do |klass|
|
63
|
+
it "should create a table for the default #{klass} class" do
|
64
|
+
@database.connection.should_receive(:create_table).with(klass.underscore.pluralize.to_sym)
|
65
|
+
@database.send :create_database_schema!
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should create a #{klass} class inheriting from ActiveRecord and the base class of the ORM module" do
|
69
|
+
@database.send :create_database_schema!
|
70
|
+
@database.send("#{klass.underscore}_class".to_sym).ancestors.should include(ActiveRecord::Base, RequestLogAnalyzer::Database::Base)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
testing_format.line_definitions.each do |name, definition|
|
75
|
+
|
76
|
+
it "should create the #{(name.to_s + '_line').camelize} class for #{name.inspect} lines" do
|
77
|
+
@database.send :create_database_schema!
|
78
|
+
Object.const_defined?("#{name}_line".camelize).should be_true
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should create the #{name.to_s + '_lines'} table for the parsed #{name.inspect} lines" do
|
82
|
+
@database.connection.should_receive(:create_table).with("#{name}_lines".to_sym)
|
83
|
+
@database.send :create_database_schema!
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#load_activerecord_class' do
|
89
|
+
|
90
|
+
before(:each) do
|
91
|
+
@database = RequestLogAnalyzer::Database.new
|
92
|
+
@connection = mock_connection
|
93
|
+
@database.stub!(:connection).and_return(@connection)
|
94
|
+
|
95
|
+
# Mock the request ORM class
|
96
|
+
@request_class = mock('Request ActiveRecord::Base class')
|
97
|
+
@request_class.stub!(:has_many)
|
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)
|
104
|
+
|
105
|
+
@mock_class = Class.new(RequestLogAnalyzer::Database::Base)
|
106
|
+
|
107
|
+
RequestLogAnalyzer::Database::Base.stub!(:subclass_from_table).and_return(@mock_class)
|
108
|
+
RequestLogAnalyzer::Database::Base.stub!(:subclass_from_line_definition).and_return(@mock_class)
|
109
|
+
end
|
110
|
+
|
111
|
+
after(:each) { @database.remove_orm_classes! }
|
112
|
+
|
113
|
+
it "should call :subclass_from_table when a table name is given as string" do
|
114
|
+
RequestLogAnalyzer::Database::Base.should_receive(:subclass_from_table).and_return(@mock_class)
|
115
|
+
@database.load_activerecord_class('test_lines')
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should call :subclass_from_table when a table name is given as symbol" do
|
119
|
+
RequestLogAnalyzer::Database::Base.should_receive(:subclass_from_table).and_return(@mock_class)
|
120
|
+
@database.load_activerecord_class(:test_lines)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should call :subclass_from_table when a LineDefinition is given" do
|
124
|
+
RequestLogAnalyzer::Database::Base.should_receive(:subclass_from_line_definition).and_return(@mock_class)
|
125
|
+
@database.load_activerecord_class(RequestLogAnalyzer::LineDefinition.new(:test))
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should define the class in the ORM module" do
|
129
|
+
@database.load_activerecord_class(:test_lines)
|
130
|
+
Object.const_defined?('TestLine').should be_true
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should add the class to the line_classes array of the database" do
|
134
|
+
@database.load_activerecord_class(:test_lines)
|
135
|
+
@database.line_classes.should include(TestLine)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -14,6 +14,18 @@ describe RequestLogAnalyzer::Source::LogParser, :requests do
|
|
14
14
|
@log_parser.file_format.should be_valid
|
15
15
|
end
|
16
16
|
|
17
|
+
it "should set the :source for every parsed line" do
|
18
|
+
@log_parser.parse_file(log_fixture(:rails_22)) do |request|
|
19
|
+
request.lines.all? { |line| line[:source] == log_fixture(:rails_22) }.should be_true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should set the :lineno for every parsed line" do
|
24
|
+
@log_parser.parse_file(log_fixture(:rails_22)) do |request|
|
25
|
+
request.lines.all? { |line| line.has_key?(:lineno) }.should be_true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
17
29
|
it "should parse more lines than requests" do
|
18
30
|
@log_parser.should_receive(:handle_request).with(an_instance_of(TestingFormat::Request)).twice
|
19
31
|
@log_parser.parse_file(log_fixture(:test_language_combined))
|
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.
|
4
|
+
version: 1.3.0
|
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-12 00:00:00 +02:00
|
14
14
|
default_executable: request-log-analyzer
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: 1.1.0
|
35
35
|
version:
|
36
|
-
description: " Request log analyzer's purpose is to find ot how your web application is being used and to focus your optimization efforts.\n This tool will parse all requests in the application's log file and aggregate the information. Once it is finished parsing \n the log file(s), it will show the requests that take op most server time using various metrics. It can also insert all \n parsed request information into a database so you can roll your own analysis. It supports Rails- and Merb-based applications \n out of the box, but file formats of other applications can easily be supported by supplying an easy to write log file format
|
36
|
+
description: " Request log analyzer's purpose is to find ot how your web application is being used and to focus your optimization efforts.\n This tool will parse all requests in the application's log file and aggregate the information. Once it is finished parsing \n the log file(s), it will show the requests that take op most server time using various metrics. It can also insert all \n parsed request information into a database so you can roll your own analysis. It supports Rails- and Merb-based applications \n and Apache access log files out of the box, but file formats of other applications can easily be supported by supplying an \n easy to write log file format definition.\n"
|
37
37
|
email:
|
38
38
|
- willem@railsdoctors.com
|
39
39
|
- bart@railsdoctors.com
|
@@ -49,8 +49,8 @@ files:
|
|
49
49
|
- lib/request_log_analyzer/output/html.rb
|
50
50
|
- lib/request_log_analyzer/controller.rb
|
51
51
|
- spec/fixtures/rails_22_cached.log
|
52
|
-
- lib/request_log_analyzer/file_format/rails_development.rb
|
53
52
|
- spec/lib/macros.rb
|
53
|
+
- lib/request_log_analyzer/file_format/rails_development.rb
|
54
54
|
- spec/fixtures/apache_combined.log
|
55
55
|
- spec/fixtures/apache_common.log
|
56
56
|
- spec/fixtures/merb_prefixed.log
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- spec/unit/file_format/file_format_api_spec.rb
|
59
59
|
- spec/unit/file_format/apache_format_spec.rb
|
60
60
|
- spec/integration/command_line_usage_spec.rb
|
61
|
+
- lib/request_log_analyzer/database.rb
|
61
62
|
- spec/fixtures/decompression.log.bz2
|
62
63
|
- lib/request_log_analyzer/log_processor.rb
|
63
64
|
- lib/request_log_analyzer/tracker.rb
|
@@ -67,18 +68,22 @@ files:
|
|
67
68
|
- request-log-analyzer.gemspec
|
68
69
|
- DESIGN.rdoc
|
69
70
|
- spec/unit/filter/timespan_filter_spec.rb
|
71
|
+
- spec/unit/aggregator/database_inserter_spec.rb
|
72
|
+
- spec/lib/matchers.rb
|
70
73
|
- lib/request_log_analyzer/filter/field.rb
|
71
74
|
- lib/request_log_analyzer/tracker/frequency.rb
|
72
75
|
- spec/fixtures/decompression.log.gz
|
73
76
|
- spec/fixtures/decompression.log
|
74
|
-
- spec/lib/
|
77
|
+
- spec/lib/testing_format.rb
|
75
78
|
- spec/fixtures/test_order.log
|
79
|
+
- spec/fixtures/rails.db
|
76
80
|
- lib/request_log_analyzer/output/fixed_width.rb
|
77
81
|
- lib/request_log_analyzer/filter/anonymize.rb
|
78
|
-
- spec/lib/testing_format.rb
|
79
82
|
- lib/request_log_analyzer/tracker/timespan.rb
|
83
|
+
- lib/request_log_analyzer/database/base.rb
|
80
84
|
- lib/request_log_analyzer/aggregator.rb
|
81
85
|
- lib/cli/progressbar.rb
|
86
|
+
- lib/request_log_analyzer/mailer.rb
|
82
87
|
- README.rdoc
|
83
88
|
- spec/fixtures/merb.log
|
84
89
|
- lib/request_log_analyzer/tracker/hourly_spread.rb
|
@@ -89,15 +94,17 @@ files:
|
|
89
94
|
- spec/unit/controller/log_processor_spec.rb
|
90
95
|
- spec/spec_helper.rb
|
91
96
|
- lib/request_log_analyzer.rb
|
97
|
+
- spec/database.yml
|
92
98
|
- Rakefile
|
99
|
+
- lib/request_log_analyzer/database/connection.rb
|
93
100
|
- spec/unit/filter/filter_spec.rb
|
101
|
+
- spec/fixtures/test_language_combined.log
|
102
|
+
- lib/request_log_analyzer/aggregator/database_inserter.rb
|
94
103
|
- lib/request_log_analyzer/aggregator/summarizer.rb
|
95
104
|
- lib/request_log_analyzer/file_format/rails.rb
|
96
|
-
- spec/fixtures/test_language_combined.log
|
97
105
|
- spec/fixtures/decompression.tar.gz
|
98
106
|
- spec/unit/filter/field_filter_spec.rb
|
99
|
-
- spec/
|
100
|
-
- lib/request_log_analyzer/aggregator/database.rb
|
107
|
+
- spec/unit/database/base_class_spec.rb
|
101
108
|
- lib/request_log_analyzer/filter/timespan.rb
|
102
109
|
- lib/request_log_analyzer/source/log_parser.rb
|
103
110
|
- spec/fixtures/decompression.tgz
|
@@ -111,19 +118,21 @@ files:
|
|
111
118
|
- spec/unit/file_format/line_definition_spec.rb
|
112
119
|
- lib/request_log_analyzer/source.rb
|
113
120
|
- lib/request_log_analyzer/request.rb
|
121
|
+
- lib/cli/database_console.rb
|
122
|
+
- spec/unit/database/connection_spec.rb
|
114
123
|
- spec/unit/controller/controller_spec.rb
|
124
|
+
- spec/lib/mocks.rb
|
125
|
+
- spec/lib/helpers.rb
|
126
|
+
- lib/cli/database_console_init.rb
|
115
127
|
- lib/request_log_analyzer/output.rb
|
116
128
|
- lib/request_log_analyzer/file_format/apache.rb
|
117
|
-
- spec/lib/helpers.rb
|
118
129
|
- spec/fixtures/rails_1x.log
|
119
|
-
- spec/lib/mocks.rb
|
120
130
|
- spec/fixtures/decompression.log.zip
|
121
131
|
- spec/unit/source/request_spec.rb
|
122
132
|
- spec/unit/source/log_parser_spec.rb
|
123
|
-
- spec/unit/aggregator/database_spec.rb
|
124
133
|
- spec/fixtures/test_file_format.log
|
125
|
-
- lib/request_log_analyzer/source/database.rb
|
126
134
|
- tasks/github-gem.rake
|
135
|
+
- spec/unit/database/database_spec.rb
|
127
136
|
- lib/request_log_analyzer/tracker/duration.rb
|
128
137
|
- lib/request_log_analyzer/file_format.rb
|
129
138
|
- spec/unit/aggregator/summarizer_spec.rb
|
@@ -131,6 +140,7 @@ files:
|
|
131
140
|
- spec/fixtures/multiple_files_2.log
|
132
141
|
- spec/fixtures/syslog_1x.log
|
133
142
|
- LICENSE
|
143
|
+
- lib/request_log_analyzer/source/database_loader.rb
|
134
144
|
- spec/unit/tracker/frequency_tracker_spec.rb
|
135
145
|
- spec/unit/file_format/rails_format_spec.rb
|
136
146
|
- lib/cli/command_line_arguments.rb
|
@@ -163,29 +173,32 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
173
|
requirements:
|
164
174
|
- To use the database inserter, ActiveRecord and an appropriate database adapter are required.
|
165
175
|
rubyforge_project: r-l-a
|
166
|
-
rubygems_version: 1.3.
|
176
|
+
rubygems_version: 1.3.5
|
167
177
|
signing_key:
|
168
178
|
specification_version: 3
|
169
|
-
summary: A command line tool to analyze request logs for Rails, Merb and other application servers
|
179
|
+
summary: A command line tool to analyze request logs for Apache, Rails, Merb and other application servers
|
170
180
|
test_files:
|
171
181
|
- spec/unit/filter/anonymize_filter_spec.rb
|
172
182
|
- spec/unit/file_format/file_format_api_spec.rb
|
173
183
|
- spec/unit/file_format/apache_format_spec.rb
|
174
184
|
- spec/integration/command_line_usage_spec.rb
|
175
185
|
- spec/unit/filter/timespan_filter_spec.rb
|
186
|
+
- spec/unit/aggregator/database_inserter_spec.rb
|
176
187
|
- spec/unit/tracker/tracker_api_spec.rb
|
177
188
|
- spec/unit/tracker/duration_tracker_spec.rb
|
178
189
|
- spec/unit/controller/log_processor_spec.rb
|
179
190
|
- spec/unit/filter/filter_spec.rb
|
180
191
|
- spec/unit/filter/field_filter_spec.rb
|
192
|
+
- spec/unit/database/base_class_spec.rb
|
181
193
|
- spec/unit/tracker/timespan_tracker_spec.rb
|
182
194
|
- spec/unit/tracker/hourly_spread_spec.rb
|
183
195
|
- spec/unit/file_format/merb_format_spec.rb
|
184
196
|
- spec/unit/file_format/line_definition_spec.rb
|
197
|
+
- spec/unit/database/connection_spec.rb
|
185
198
|
- spec/unit/controller/controller_spec.rb
|
186
199
|
- spec/unit/source/request_spec.rb
|
187
200
|
- spec/unit/source/log_parser_spec.rb
|
188
|
-
- spec/unit/
|
201
|
+
- spec/unit/database/database_spec.rb
|
189
202
|
- spec/unit/aggregator/summarizer_spec.rb
|
190
203
|
- spec/unit/tracker/frequency_tracker_spec.rb
|
191
204
|
- spec/unit/file_format/rails_format_spec.rb
|