request-log-analyzer 1.10.1 → 1.11.0

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 (47) hide show
  1. data/bin/request-log-analyzer +0 -1
  2. data/lib/request_log_analyzer.rb +15 -29
  3. data/lib/request_log_analyzer/aggregator.rb +5 -5
  4. data/lib/request_log_analyzer/aggregator/database_inserter.rb +2 -1
  5. data/lib/request_log_analyzer/controller.rb +0 -3
  6. data/lib/request_log_analyzer/database.rb +6 -7
  7. data/lib/request_log_analyzer/file_format.rb +42 -13
  8. data/lib/request_log_analyzer/file_format/apache.rb +1 -1
  9. data/lib/request_log_analyzer/file_format/delayed_job2.rb +2 -2
  10. data/lib/request_log_analyzer/file_format/delayed_job21.rb +2 -2
  11. data/lib/request_log_analyzer/file_format/haproxy.rb +107 -13
  12. data/lib/request_log_analyzer/file_format/mysql.rb +5 -5
  13. data/lib/request_log_analyzer/file_format/rails3.rb +7 -0
  14. data/lib/request_log_analyzer/filter.rb +4 -5
  15. data/lib/request_log_analyzer/line_definition.rb +6 -4
  16. data/lib/request_log_analyzer/output.rb +3 -5
  17. data/lib/request_log_analyzer/source.rb +3 -4
  18. data/lib/request_log_analyzer/source/log_parser.rb +56 -4
  19. data/lib/request_log_analyzer/tracker.rb +8 -8
  20. data/request-log-analyzer.gemspec +3 -3
  21. data/spec/fixtures/mysql_slow_query.log +0 -1
  22. data/spec/integration/command_line_usage_spec.rb +0 -5
  23. data/spec/lib/helpers.rb +2 -2
  24. data/spec/lib/matchers.rb +38 -7
  25. data/spec/lib/mocks.rb +1 -5
  26. data/spec/unit/database/base_class_spec.rb +1 -0
  27. data/spec/unit/file_format/amazon_s3_format_spec.rb +58 -55
  28. data/spec/unit/file_format/apache_format_spec.rb +74 -162
  29. data/spec/unit/file_format/common_regular_expressions_spec.rb +51 -26
  30. data/spec/unit/file_format/delayed_job21_format_spec.rb +22 -31
  31. data/spec/unit/file_format/delayed_job2_format_spec.rb +27 -32
  32. data/spec/unit/file_format/delayed_job_format_spec.rb +44 -63
  33. data/spec/unit/file_format/haproxy_format_spec.rb +69 -71
  34. data/spec/unit/file_format/line_definition_spec.rb +26 -33
  35. data/spec/unit/file_format/merb_format_spec.rb +22 -37
  36. data/spec/unit/file_format/mysql_format_spec.rb +80 -123
  37. data/spec/unit/file_format/oink_format_spec.rb +29 -61
  38. data/spec/unit/file_format/postgresql_format_spec.rb +2 -4
  39. data/spec/unit/file_format/rack_format_spec.rb +49 -44
  40. data/spec/unit/file_format/rails3_format_spec.rb +17 -20
  41. data/spec/unit/file_format/rails_format_spec.rb +52 -68
  42. data/spec/unit/file_format/w3c_format_spec.rb +40 -39
  43. data/spec/unit/source/log_parser_spec.rb +1 -1
  44. metadata +4 -7
  45. data/lib/mixins/gets_memory_protection.rb +0 -80
  46. data/lib/request_log_analyzer/output/fancy_html.rb +0 -44
  47. data/lib/request_log_analyzer/source/database_loader.rb +0 -87
@@ -3,29 +3,27 @@ require 'spec_helper'
3
3
  describe RequestLogAnalyzer::FileFormat::Apache do
4
4
 
5
5
  describe '.access_line_definition' do
6
- before(:each) do
7
- @format_string = '%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i" %T'
8
- @line_definition = RequestLogAnalyzer::FileFormat::Apache.access_line_definition(@format_string)
9
- end
6
+ let(:format_string) { '%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i" %T' }
7
+ let(:line_definition) { RequestLogAnalyzer::FileFormat::Apache.access_line_definition(format_string) }
10
8
 
11
9
  it "should create a Regexp to match the line" do
12
- @line_definition.regexp.should be_kind_of(Regexp)
10
+ line_definition.regexp.should be_kind_of(Regexp)
13
11
  end
14
12
 
15
13
  it "should create a list of captures for the values in the lines" do
16
- @line_definition.captures.should have(12).items
14
+ line_definition.captures.should have(12).items
17
15
  end
18
16
 
19
17
  it "should make it a header line" do
20
- @line_definition.should be_header
18
+ line_definition.should be_header
21
19
  end
22
20
 
23
21
  it "should make it a footer line" do
24
- @line_definition.should be_footer
22
+ line_definition.should be_footer
25
23
  end
26
24
 
27
25
  it "should capture :duration" do
28
- @line_definition.captures?(:duration).should be_true
26
+ line_definition.captures?(:duration).should be_true
29
27
  end
30
28
  end
31
29
 
@@ -47,173 +45,87 @@ describe RequestLogAnalyzer::FileFormat::Apache do
47
45
  end
48
46
 
49
47
  describe '.create' do
48
+ let(:format_string) { '%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i"' }
49
+ subject { RequestLogAnalyzer::FileFormat::Apache.create(format_string) }
50
50
 
51
- before(:each) do
52
- @format_string = '%h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-agent}i"'
53
- @format = RequestLogAnalyzer::FileFormat::Apache.create(@format_string)
54
- end
55
-
56
- it "should create the :access line definition" do
57
- @format.should have_line_definition(:access).capturing(:timestamp, :remote_host, :bytes_sent, :http_method, :path, :http_version, :http_status)
58
- end
59
-
60
- it "should be a valid file format" do
61
- @format.should be_valid
62
- end
63
-
64
- it "should setup report trackers" do
65
- @format.report_trackers.should_not be_empty
66
- end
51
+ it { should be_well_formed }
52
+ it { should have_line_definition(:access).capturing(:timestamp, :remote_host, :bytes_sent, :http_method, :path, :http_version, :http_status) }
53
+ it { should have(8).report_trackers }
67
54
  end
68
55
 
69
56
  context '"Common" access log parsing' do
70
- before(:all) do
71
- @file_format = RequestLogAnalyzer::FileFormat.load(:apache, :common)
72
- @log_parser = RequestLogAnalyzer::Source::LogParser.new(@file_format)
73
- @sample_1 = '1.129.119.13 - - [08/Sep/2009:07:54:09 -0400] "GET /profile/18543424 HTTP/1.0" 200 8223'
74
- @sample_2 = '1.82.235.29 - - [08/Sep/2009:07:54:05 -0400] "GET /gallery/fresh?page=23&per_page=16 HTTP/1.1" 200 23414'
75
- @nonsense_sample = 'addasdsasadadssadasd'
76
- end
77
-
78
- it "should have a valid language definitions" do
79
- @file_format.should be_valid
80
- end
81
-
82
- it "should not parse a valid access log line" do
83
- @file_format.should_not parse_line(@nonsense_sample)
84
- end
85
-
86
- it "should read the correct values from a valid HTTP/1.0 access log line" do
87
- @file_format.should parse_line(@sample_1).as(:access).and_capture(
88
- :remote_host => '1.129.119.13',
89
- :remote_logname => nil,
90
- :user => nil,
91
- :timestamp => 20090908075409,
92
- :http_status => 200,
93
- :http_method => 'GET',
94
- :http_version => '1.0',
95
- :bytes_sent => 8223)
96
- end
97
-
98
- it "should read the correct values from a valid 200 access log line" do
99
- @file_format.should parse_line(@sample_2).as(:access).and_capture(
100
- :remote_host => '1.82.235.29',
101
- :remote_logname => nil,
102
- :user => nil,
103
- :timestamp => 20090908075405,
104
- :http_status => 200,
105
- :http_method => 'GET',
106
- :http_version => '1.1',
107
- :bytes_sent => 23414)
57
+ subject { RequestLogAnalyzer::FileFormat.load(:apache, :common) }
58
+
59
+ it { should be_well_formed }
60
+ it { should have_line_definition(:access).capturing(:remote_host, :remote_logname, :user, :timestamp, :http_status, :http_method, :http_version, :bytes_sent) }
61
+ it { should have(6).report_trackers }
62
+
63
+ describe '#parse_line' do
64
+
65
+ let(:sample1) { '1.129.119.13 - - [08/Sep/2009:07:54:09 -0400] "GET /profile/18543424 HTTP/1.0" 200 8223' }
66
+ let(:sample2) { '1.82.235.29 - - [08/Sep/2009:07:54:05 -0400] "GET /gallery/fresh?page=23&per_page=16 HTTP/1.1" 200 23414' }
67
+
68
+ it { should parse_line(sample1, 'a sample line').and_capture(
69
+ :remote_host => '1.129.119.13', :remote_logname => nil, :user => nil,
70
+ :timestamp => 20090908075409, :http_status => 200, :http_method => 'GET',
71
+ :http_version => '1.0', :bytes_sent => 8223)
72
+ }
73
+
74
+ it { should parse_line(sample2, 'another sample line').and_capture(
75
+ :remote_host => '1.82.235.29', :remote_logname => nil, :user => nil,
76
+ :timestamp => 20090908075405, :http_status => 200, :http_method => 'GET',
77
+ :http_version => '1.1', :bytes_sent => 23414)
78
+ }
79
+
80
+ it { should_not parse_line('nonsense', 'a nonsense line')}
108
81
  end
109
-
110
- it "should parse 10 request from fixture access log without warnings" do
111
- request_counter.should_receive(:hit!).exactly(10).times
112
- @log_parser.should_not_receive(:warn)
82
+
83
+ describe '#parse_io' do
84
+ let(:log_parser) { RequestLogAnalyzer::Source::LogParser.new(subject) }
113
85
 
114
- @log_parser.parse_file(log_fixture(:apache_common)) do |request|
115
- request_counter.hit! if request.kind_of?(RequestLogAnalyzer::FileFormat::Apache::Request)
86
+ it "should parse a log snippet successfully without warnings" do
87
+ log_parser.should_receive(:handle_request).exactly(10).times
88
+ log_parser.should_not_receive(:warn)
89
+ log_parser.parse_file(log_fixture(:apache_common))
116
90
  end
117
91
  end
118
92
  end
119
93
 
120
94
  context '"Combined" access log parsing' do
121
-
122
- before(:all) do
123
- @file_format = RequestLogAnalyzer::FileFormat.load(:apache, :combined)
124
- @log_parser = RequestLogAnalyzer::Source::LogParser.new(@file_format)
125
- @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)"'
126
- @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"'
127
- @nonsense_sample = 'addasdsasadadssadasd'
128
- end
129
-
130
- it "should have a valid language definitions" do
131
- @file_format.should be_valid
132
- end
133
-
134
- it "should not parse a valid access log line" do
135
- @file_format.should_not parse_line(@nonsense_sample)
136
- end
137
-
138
- it "should read the correct values from a valid 404 access log line" do
139
- @file_format.should parse_line(@sample_1).as(:access).and_capture(
140
- :remote_host => '69.41.0.45',
141
- :remote_logname => nil,
142
- :user => nil,
143
- :timestamp => 20090902120240,
144
- :http_status => 404,
145
- :http_method => 'GET',
146
- :http_version => '1.1',
147
- :bytes_sent => 209,
148
- :referer => nil,
149
- :user_agent => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)')
150
- end
151
-
152
- it "should read the correct values from a valid 200 access log line" do
153
- @file_format.should parse_line(@sample_2).as(:access).and_capture(
154
- :remote_host => '10.0.1.1',
155
- :remote_logname => nil,
156
- :user => nil,
157
- :timestamp => 20090902050833,
158
- :http_status => 200,
159
- :http_method => 'GET',
160
- :http_version => '1.1',
161
- :bytes_sent => 30,
162
- :referer => nil,
163
- :user_agent => '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')
164
- end
165
-
166
- it "should parse 5 request from fixture access log without warnings" do
167
- request_counter.should_receive(:hit!).exactly(5).times
168
- @log_parser.should_not_receive(:warn)
95
+ subject { RequestLogAnalyzer::FileFormat.load(:apache, :combined) }
96
+
97
+ it { should be_well_formed }
98
+ it { should have_line_definition(:access).capturing(:remote_host, :remote_logname, :user, :timestamp, :http_status, :http_method, :http_version, :bytes_sent, :referer, :user_agent) }
99
+ it { should have(8).report_trackers }
100
+
101
+ describe '#parse_line' do
102
+ let(:sample1) { '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)"' }
103
+ let(:sample2) { '0:0:0:0:0:0:0: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"' }
169
104
 
170
- @log_parser.parse_file(log_fixture(:apache_combined)) do |request|
171
- request_counter.hit! if request.kind_of?(RequestLogAnalyzer::FileFormat::Apache::Request)
172
- end
173
- end
174
- end
175
-
176
- context '"Rack" access log parser' do
177
- before(:each) do
178
- @file_format = RequestLogAnalyzer::FileFormat.load(:rack)
179
- @log_parser = RequestLogAnalyzer::Source::LogParser.new(@file_format)
180
- @sample_1 = '127.0.0.1 - - [16/Sep/2009 07:40:08] "GET /favicon.ico HTTP/1.1" 500 63183 0.0453'
181
- @sample_2 = '127.0.0.1 - - [01/Oct/2009 07:58:10] "GET / HTTP/1.1" 200 1 0.0045'
182
- @nonsense_sample = 'addasdsasadadssadasd'
183
- end
184
-
185
- it "should create a kind of an Apache file format" do
186
- @file_format.should be_kind_of(RequestLogAnalyzer::FileFormat::Apache)
187
- end
188
-
189
- it "should have a valid language definitions" do
190
- @file_format.should be_valid
191
- end
192
-
193
- it "should parse a valid access log line with status 500" do
194
- @file_format.should parse_line(@sample_1).as(:access).and_capture(
195
- :remote_host => '127.0.0.1', :timestamp => 20090916074008, :user => nil,
196
- :http_status => 500, :http_method => 'GET', :http_version => '1.1',
197
- :duration => 0.0453, :bytes_sent => 63183, :remote_logname => nil)
198
- end
199
-
200
- it "should parse a valid access log line with status 200" do
201
- @file_format.should parse_line(@sample_2).as(:access).and_capture(
202
- :remote_host => '127.0.0.1', :timestamp => 20091001075810, :user => nil,
203
- :http_status => 200, :http_method => 'GET', :http_version => '1.1',
204
- :duration => 0.0045, :bytes_sent => 1, :remote_logname => nil)
205
- end
206
-
207
- it "should not parse an invalid access log line" do
208
- @file_format.should_not parse_line(@nonsense_sample)
105
+ it { should parse_line(sample1, 'with IPv4 address').and_capture(
106
+ :remote_host => '69.41.0.45', :remote_logname => nil, :user => nil,
107
+ :timestamp => 20090902120240, :http_status => 404, :http_method => 'GET',
108
+ :http_version => '1.1', :bytes_sent => 209, :referer => nil,
109
+ :user_agent => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows 98)')
110
+ }
111
+
112
+ it { should parse_line(sample2, 'with IPv6 address').and_capture(
113
+ :remote_host => '0:0:0:0:0:0:0:1', :remote_logname => nil, :user => nil,
114
+ :timestamp => 20090902050833, :http_status => 200, :http_method => 'GET',
115
+ :http_version => '1.1', :bytes_sent => 30, :referer => nil,
116
+ :user_agent => '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')
117
+ }
118
+
119
+ it { should_not parse_line('nonsense', 'a nonsense line')}
209
120
  end
210
-
211
- it "should parse 2 Apache requests from a sample without warnings" do
212
- request_counter.should_receive(:hit!).twice
213
- @log_parser.should_not_receive(:warn)
121
+
122
+ describe '#parse_io' do
123
+ let(:log_parser) { RequestLogAnalyzer::Source::LogParser.new(subject) }
214
124
 
215
- @log_parser.parse_io(log_stream(@sample_1, @nonsense_sample, @sample_2)) do |request|
216
- request_counter.hit! if request.kind_of?(RequestLogAnalyzer::FileFormat::Apache::Request)
125
+ it "should parse a log snippet successfully without warnings" do
126
+ log_parser.should_receive(:handle_request).exactly(5).times
127
+ log_parser.should_not_receive(:warn)
128
+ log_parser.parse_file(log_fixture(:apache_combined))
217
129
  end
218
130
  end
219
131
  end
@@ -3,51 +3,76 @@ require 'spec_helper'
3
3
  describe RequestLogAnalyzer::FileFormat::CommonRegularExpressions do
4
4
 
5
5
  include RequestLogAnalyzer::FileFormat::CommonRegularExpressions
6
-
6
+
7
7
  describe '.timestamp' do
8
-
9
8
  it "should parse timestamps with a given format" do
10
- timestamp('%Y-%m-%dT%H:%M:%S%z').should =~ '2009-12-03T00:12:37+0100'
11
- timestamp('%Y-%m-%dT%H:%M:%S%z').should_not =~ '2009-12-03 00:12:37+0100'
12
- timestamp('%Y-%m-%dT%H:%M:%S%z').should_not =~ '2009-12-03T00:12:37'
9
+ anchored(timestamp('%Y-%m-%dT%H:%M:%S%z')).should =~ '2009-12-03T00:12:37+0100'
10
+ anchored(timestamp('%Y-%m-%dT%H:%M:%S%z')).should_not =~ '2009-12-03 00:12:37+0100'
11
+ anchored(timestamp('%Y-%m-%dT%H:%M:%S%z')).should_not =~ '2009-12-03T00:12:37'
13
12
  end
14
13
  end
14
+
15
15
 
16
- describe '.ip_address' do
16
+ describe '.hostname' do
17
+ it "should parse hostnames successfully" do
18
+ anchored(hostname).should =~ 'railsdoctors.com'
19
+ anchored(hostname).should =~ 'www.rails-doctors.com'
20
+ anchored(hostname).should =~ 'hostname.co.uk'
21
+ anchored(hostname).should =~ 'localhost'
17
22
 
23
+ anchored(hostname).should_not =~ '192.168.0.1'
24
+ anchored(hostname).should_not =~ '3ffe:1900:4545:3:200:f8ff:fe21:67cf'
25
+ anchored(hostname).should_not =~ 'railsdoctors.'
26
+ end
27
+ end
28
+
29
+ describe '.ip_address' do
18
30
  it "should parse IPv4 addresses" do
19
- ip_address.should =~ '127.0.0.1'
20
- ip_address.should =~ '255.255.255.255'
31
+ anchored(ip_address).should =~ '127.0.0.1'
32
+ anchored(ip_address).should =~ '255.255.255.255'
21
33
 
22
- ip_address.should_not =~ '2552.2552.2552.2552'
23
- ip_address.should_not =~ '127001'
24
- ip_address.should_not =~ ''
25
- ip_address.should_not =~ '-'
26
- ip_address.should_not =~ 'sub-host.domain.tld'
34
+ anchored(ip_address).should_not =~ '2552.2552.2552.2552'
35
+ anchored(ip_address).should_not =~ '127001'
36
+ anchored(ip_address).should_not =~ ''
37
+ anchored(ip_address).should_not =~ '-'
38
+ anchored(ip_address).should_not =~ 'sub-host.domain.tld'
27
39
  end
28
40
 
29
41
  it "should pase IPv6 addresses" do
30
- ip_address.should =~ '::1'
31
- ip_address.should =~ '3ffe:1900:4545:3:200:f8ff:fe21:67cf'
32
- ip_address.should =~ '3ffe:1900:4545:3:200:f8ff:127.0.0.1'
33
- ip_address.should =~ '::3:200:f8ff:127.0.0.1'
42
+ anchored(ip_address).should =~ '::1'
43
+ anchored(ip_address).should =~ '3ffe:1900:4545:3:200:f8ff:fe21:67cf'
44
+ anchored(ip_address).should =~ '3ffe:1900:4545:3:200:f8ff:127.0.0.1'
45
+ anchored(ip_address).should =~ '::3:200:f8ff:127.0.0.1'
46
+ anchored(ip_address).should =~ '0:0:0:0:0:0:0:1'
34
47
 
35
- ip_address.should_not =~ 'qqqq:wwww:eeee:3q:200:wf8ff:fe21:67cf'
36
- ip_address.should_not =~ '3ffe44:1900f:454545:3:200:f8ff:ffff:5432'
48
+ anchored(ip_address).should_not =~ 'qqqq:wwww:eeee:3q:200:wf8ff:fe21:67cf'
49
+ anchored(ip_address).should_not =~ '3ffe44:1900f:454545:3:200:f8ff:ffff:5432'
37
50
  end
38
51
 
39
52
  it "should allow blank if true is given as parameter" do
40
- /^#{ip_address(true)}$/.should =~ ''
41
- /^#{ip_address(true)}$/.should_not =~ ' '
53
+ anchored(ip_address(true)).should =~ ''
54
+ anchored(ip_address(true)).should_not =~ ' '
42
55
  end
43
56
 
44
57
  it "should allow a nil substitute if a string is given as parameter" do
45
- /^#{ip_address('-')}$/.should =~ '-'
46
- /^#{ip_address('-')}$/.should_not =~ ' -'
47
- /^#{ip_address('-')}$/.should_not =~ '--'
48
- /^#{ip_address('-')}$/.should_not =~ ''
58
+ anchored(ip_address('-')).should =~ '-'
59
+ anchored(ip_address('-')).should_not =~ ' -'
60
+ anchored(ip_address('-')).should_not =~ '--'
61
+ anchored(ip_address('-')).should_not =~ ''
49
62
  end
50
-
51
63
  end
64
+
65
+
66
+ describe '.hostname_or_ip_address' do
67
+ it "should parse either hostnames or ip addresses" do
68
+ anchored(hostname_or_ip_address).should =~ 'railsdoctors.com'
69
+ anchored(hostname_or_ip_address).should =~ 'hostname.co.uk'
70
+ anchored(hostname_or_ip_address).should =~ 'localhost'
71
+ anchored(hostname_or_ip_address).should =~ '192.168.0.1'
72
+ anchored(hostname_or_ip_address).should =~ '3ffe:1900:4545:3:200:f8ff:fe21:67cf'
73
+
74
+ anchored(hostname_or_ip_address).should_not =~ 'railsdoctors.'
75
+ end
76
+ end
52
77
  end
53
78
 
@@ -2,42 +2,36 @@ require 'spec_helper'
2
2
 
3
3
  describe RequestLogAnalyzer::FileFormat::DelayedJob do
4
4
 
5
- it "should be a valid file format" do
6
- RequestLogAnalyzer::FileFormat.load(:delayed_job).should be_valid
7
- end
5
+ subject { RequestLogAnalyzer::FileFormat.load(:delayed_job21) }
6
+
7
+ it { should be_well_formed }
8
+ it { should have_line_definition(:job_lock).capturing(:timestamp, :job, :host, :pid) }
9
+ it { should have_line_definition(:job_completed).capturing(:timestamp, :duration, :host, :pid) }
10
+ it { should have(4).report_trackers }
8
11
 
9
12
  describe '#parse_line' do
10
13
 
11
- before(:each) do
12
- @file_format = RequestLogAnalyzer::FileFormat.load(:delayed_job21)
13
- end
14
+ let(:job_lock_sample1) { "2010-05-17T17:37:34+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] acquired lock on S3FileJob" }
15
+ let(:job_lock_sample2) { "2010-05-17T17:37:34+0000: [Worker(delayed_job.0 host:hostname.co.uk pid:11888)] acquired lock on S3FileJob" }
16
+ let(:job_completed_sample1) { '2010-05-17T17:37:35+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] S3FileJob completed after 1.0676' }
14
17
 
15
- it "should parse a :job_lock line correctly" do
16
- line = "2010-05-17T17:37:34+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] acquired lock on S3FileJob"
17
- @file_format.should parse_line(line).as(:job_lock).and_capture(:timestamp => 20100517173734,
18
- :job => 'S3FileJob', :host => 'hostname.co.uk', :pid => 11888)
19
- end
18
+ it { should parse_line(job_lock_sample1, 'with a single worker').as(:job_lock).and_capture(
19
+ :timestamp => 20100517173734, :job => 'S3FileJob', :host => 'hostname.co.uk', :pid => 11888) }
20
20
 
21
- it "should parse a :job_lock line correctly when the worker is one of many" do
22
- line = "2010-05-17T17:37:34+0000: [Worker(delayed_job.0 host:hostname.co.uk pid:11888)] acquired lock on S3FileJob"
23
- @file_format.should parse_line(line).as(:job_lock).and_capture(:timestamp => 20100517173734,
24
- :job => 'S3FileJob', :host => 'hostname.co.uk', :pid => 11888)
25
- end
21
+ it { should parse_line(job_lock_sample2, 'with multiple workers').as(:job_lock).and_capture(
22
+ :timestamp => 20100517173734, :job => 'S3FileJob', :host => 'hostname.co.uk', :pid => 11888) }
26
23
 
27
- it "should parse a :job_completed line correctly" do
28
- line = '2010-05-17T17:37:35+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] S3FileJob completed after 1.0676'
29
- @file_format.should parse_line(line).as(:job_completed).and_capture(:timestamp => 20100517173735,
30
- :duration => 1.0676, :host => 'hostname.co.uk', :pid => 11888, :job => 'S3FileJob')
31
- end
24
+ it { should parse_line(job_completed_sample1).as(:job_completed).and_capture(
25
+ :timestamp => 20100517173735, :duration => 1.0676, :host => 'hostname.co.uk', :pid => 11888, :job => 'S3FileJob') }
26
+
27
+ it { should_not parse_line('nonsense', 'a nonsense line') }
32
28
  end
33
29
 
34
30
  describe '#parse_io' do
35
- before(:each) do
36
- @log_parser = RequestLogAnalyzer::Source::LogParser.new(RequestLogAnalyzer::FileFormat.load(:delayed_job21))
37
- end
31
+ let(:log_parser) { RequestLogAnalyzer::Source::LogParser.new(subject) }
38
32
 
39
33
  it "should parse a batch of completed jobs without warnings" do
40
- fragment = <<-EOLOG
34
+ fragment = log_snippet(<<-EOLOG)
41
35
  2010-05-17T17:36:44+0000: *** Starting job worker delayed_job host:hostname.co.uk pid:11888
42
36
  2010-05-17T17:37:34+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] acquired lock on S3FileJob
43
37
  2010-05-17T17:37:35+0000: [Worker(delayed_job host:hostname.co.uk pid:11888)] S3FileJob completed after 1.0676
@@ -49,12 +43,9 @@ describe RequestLogAnalyzer::FileFormat::DelayedJob do
49
43
  2010-05-19T11:47:26+0000: Exiting...
50
44
  EOLOG
51
45
 
52
- request_counter.should_receive(:hit!).exactly(3).times
53
- @log_parser.should_not_receive(:warn)
54
-
55
- @log_parser.parse_io(StringIO.new(fragment)) do |request|
56
- request_counter.hit! if request.kind_of?(RequestLogAnalyzer::FileFormat::DelayedJob21::Request)
57
- end
46
+ log_parser.should_receive(:handle_request).exactly(3).times
47
+ log_parser.should_not_receive(:warn)
48
+ log_parser.parse_io(fragment)
58
49
  end
59
50
  end
60
51
  end