request-log-analyzer 1.13.1 → 1.13.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/bin/console +17 -0
- data/lib/cli/command_line_arguments.rb +29 -36
- data/lib/cli/database_console.rb +1 -3
- data/lib/cli/database_console_init.rb +11 -11
- data/lib/cli/progressbar.rb +30 -32
- data/lib/cli/tools.rb +20 -23
- data/lib/request_log_analyzer.rb +8 -8
- data/lib/request_log_analyzer/aggregator.rb +4 -7
- data/lib/request_log_analyzer/aggregator/database_inserter.rb +10 -13
- data/lib/request_log_analyzer/aggregator/echo.rb +5 -7
- data/lib/request_log_analyzer/aggregator/summarizer.rb +15 -18
- data/lib/request_log_analyzer/class_level_inheritable_attributes.rb +23 -0
- data/lib/request_log_analyzer/controller.rb +36 -42
- data/lib/request_log_analyzer/database.rb +4 -6
- data/lib/request_log_analyzer/database/base.rb +39 -41
- data/lib/request_log_analyzer/database/connection.rb +8 -10
- data/lib/request_log_analyzer/database/request.rb +1 -3
- data/lib/request_log_analyzer/database/source.rb +0 -2
- data/lib/request_log_analyzer/database/warning.rb +4 -6
- data/lib/request_log_analyzer/file_format.rb +46 -49
- data/lib/request_log_analyzer/file_format/amazon_s3.rb +15 -19
- data/lib/request_log_analyzer/file_format/apache.rb +42 -45
- data/lib/request_log_analyzer/file_format/delayed_job.rb +13 -15
- data/lib/request_log_analyzer/file_format/delayed_job2.rb +9 -11
- data/lib/request_log_analyzer/file_format/delayed_job21.rb +9 -11
- data/lib/request_log_analyzer/file_format/delayed_job3.rb +5 -8
- data/lib/request_log_analyzer/file_format/delayed_job4.rb +5 -8
- data/lib/request_log_analyzer/file_format/haproxy.rb +44 -48
- data/lib/request_log_analyzer/file_format/merb.rb +13 -17
- data/lib/request_log_analyzer/file_format/mysql.rb +21 -25
- data/lib/request_log_analyzer/file_format/nginx.rb +0 -2
- data/lib/request_log_analyzer/file_format/oink.rb +30 -31
- data/lib/request_log_analyzer/file_format/postgresql.rb +11 -15
- data/lib/request_log_analyzer/file_format/rack.rb +0 -2
- data/lib/request_log_analyzer/file_format/rails.rb +100 -104
- data/lib/request_log_analyzer/file_format/rails3.rb +19 -23
- data/lib/request_log_analyzer/file_format/rails_development.rb +0 -1
- data/lib/request_log_analyzer/file_format/w3c.rb +16 -18
- data/lib/request_log_analyzer/filter.rb +0 -2
- data/lib/request_log_analyzer/filter/anonymize.rb +4 -7
- data/lib/request_log_analyzer/filter/field.rb +3 -6
- data/lib/request_log_analyzer/filter/timespan.rb +2 -6
- data/lib/request_log_analyzer/line_definition.rb +16 -19
- data/lib/request_log_analyzer/log_processor.rb +10 -14
- data/lib/request_log_analyzer/mailer.rb +9 -12
- data/lib/request_log_analyzer/output.rb +12 -14
- data/lib/request_log_analyzer/output/fixed_width.rb +21 -28
- data/lib/request_log_analyzer/output/html.rb +11 -14
- data/lib/request_log_analyzer/request.rb +53 -33
- data/lib/request_log_analyzer/source.rb +2 -5
- data/lib/request_log_analyzer/source/log_parser.rb +9 -16
- data/lib/request_log_analyzer/tracker.rb +10 -12
- data/lib/request_log_analyzer/tracker/duration.rb +4 -6
- data/lib/request_log_analyzer/tracker/frequency.rb +9 -11
- data/lib/request_log_analyzer/tracker/hourly_spread.rb +8 -11
- data/lib/request_log_analyzer/tracker/numeric_value.rb +40 -44
- data/lib/request_log_analyzer/tracker/timespan.rb +5 -8
- data/lib/request_log_analyzer/tracker/traffic.rb +8 -10
- data/lib/request_log_analyzer/version.rb +1 -1
- data/request-log-analyzer.gemspec +6 -6
- data/spec/integration/command_line_usage_spec.rb +33 -33
- data/spec/integration/mailer_spec.rb +181 -185
- data/spec/integration/munin_plugins_rails_spec.rb +20 -20
- data/spec/integration/scout_spec.rb +40 -41
- data/spec/lib/helpers.rb +8 -9
- data/spec/lib/macros.rb +2 -4
- data/spec/lib/matchers.rb +20 -25
- data/spec/lib/mocks.rb +10 -11
- data/spec/lib/testing_format.rb +8 -10
- data/spec/spec_helper.rb +5 -1
- data/spec/unit/aggregator/database_inserter_spec.rb +23 -23
- data/spec/unit/aggregator/summarizer_spec.rb +7 -7
- data/spec/unit/controller/controller_spec.rb +14 -14
- data/spec/unit/controller/log_processor_spec.rb +3 -3
- data/spec/unit/database/base_class_spec.rb +36 -37
- data/spec/unit/database/connection_spec.rb +10 -10
- data/spec/unit/database/database_spec.rb +11 -11
- data/spec/unit/file_format/amazon_s3_format_spec.rb +66 -62
- data/spec/unit/file_format/apache_format_spec.rb +57 -52
- data/spec/unit/file_format/common_regular_expressions_spec.rb +18 -21
- data/spec/unit/file_format/delayed_job21_format_spec.rb +22 -16
- data/spec/unit/file_format/delayed_job2_format_spec.rb +22 -16
- data/spec/unit/file_format/delayed_job3_format_spec.rb +14 -10
- data/spec/unit/file_format/delayed_job4_format_spec.rb +14 -10
- data/spec/unit/file_format/delayed_job_format_spec.rb +12 -12
- data/spec/unit/file_format/file_format_api_spec.rb +19 -19
- data/spec/unit/file_format/format_autodetection_spec.rb +7 -7
- data/spec/unit/file_format/haproxy_format_spec.rb +53 -49
- data/spec/unit/file_format/inheritance_spec.rb +13 -0
- data/spec/unit/file_format/line_definition_spec.rb +35 -33
- data/spec/unit/file_format/merb_format_spec.rb +13 -11
- data/spec/unit/file_format/mysql_format_spec.rb +24 -24
- data/spec/unit/file_format/oink_format_spec.rb +29 -29
- data/spec/unit/file_format/postgresql_format_spec.rb +9 -9
- data/spec/unit/file_format/rack_format_spec.rb +36 -31
- data/spec/unit/file_format/rails3_format_spec.rb +46 -46
- data/spec/unit/file_format/rails_format_spec.rb +52 -53
- data/spec/unit/file_format/w3c_format_spec.rb +27 -24
- data/spec/unit/filter/anonymize_filter_spec.rb +7 -7
- data/spec/unit/filter/field_filter_spec.rb +26 -26
- data/spec/unit/filter/filter_spec.rb +4 -4
- data/spec/unit/filter/timespan_filter_spec.rb +22 -22
- data/spec/unit/mailer_spec.rb +21 -21
- data/spec/unit/request_spec.rb +29 -29
- data/spec/unit/source/log_parser_spec.rb +5 -5
- data/spec/unit/tracker/duration_tracker_spec.rb +23 -23
- data/spec/unit/tracker/frequency_tracker_spec.rb +29 -30
- data/spec/unit/tracker/hourly_spread_spec.rb +35 -35
- data/spec/unit/tracker/numeric_value_tracker_spec.rb +71 -72
- data/spec/unit/tracker/timespan_tracker_spec.rb +31 -31
- data/spec/unit/tracker/tracker_api_spec.rb +43 -44
- data/spec/unit/tracker/traffic_tracker_spec.rb +7 -7
- metadata +38 -35
@@ -5,108 +5,108 @@ describe RequestLogAnalyzer::FileFormat::Rails3 do
|
|
5
5
|
subject { RequestLogAnalyzer::FileFormat.load(:rails3) }
|
6
6
|
|
7
7
|
it { should be_well_formed }
|
8
|
-
it { should
|
8
|
+
it { should satisfy { |ff| ff.report_trackers.length == 11 } }
|
9
9
|
|
10
10
|
describe '#parse_line' do
|
11
11
|
|
12
|
-
it
|
12
|
+
it 'should parse :started lines correctly' do
|
13
13
|
line = 'Started GET "/queries" for 127.0.0.1 at Thu Feb 25 16:15:18 -0800 2010'
|
14
|
-
subject.should parse_line(line).as(:started).and_capture(:
|
15
|
-
:
|
14
|
+
subject.should parse_line(line).as(:started).and_capture(method: 'GET',
|
15
|
+
path: '/queries', ip: '127.0.0.1', timestamp: 20_100_225_161_518)
|
16
16
|
end
|
17
17
|
|
18
|
-
it
|
18
|
+
it 'should parse :started lines in Oct, Nov and Dec correctly' do
|
19
19
|
line = 'Started GET "/queries" for 127.0.0.1 at Thu Oct 25 16:15:18 -0800 2010'
|
20
|
-
subject.should parse_line(line).as(:started).and_capture(:
|
21
|
-
:
|
20
|
+
subject.should parse_line(line).as(:started).and_capture(method: 'GET',
|
21
|
+
path: '/queries', ip: '127.0.0.1', timestamp: 20_101_025_161_518)
|
22
22
|
end
|
23
23
|
|
24
|
-
it
|
24
|
+
it 'should parse :started lines in Ruby 1.9.2 format correctly' do
|
25
25
|
line = 'Started GET "/queries" for 127.0.0.1 at 2010-10-26 02:27:15 +0000'
|
26
|
-
subject.should parse_line(line).as(:started).and_capture(:
|
27
|
-
:
|
26
|
+
subject.should parse_line(line).as(:started).and_capture(method: 'GET',
|
27
|
+
path: '/queries', ip: '127.0.0.1', timestamp: 20_101_026_022_715)
|
28
28
|
end
|
29
29
|
|
30
|
-
it
|
30
|
+
it 'should parse :processing lines correctly' do
|
31
31
|
line = ' Processing by QueriesController#index as HTML'
|
32
32
|
subject.should parse_line(line).as(:processing).and_capture(
|
33
|
-
:
|
33
|
+
controller: 'QueriesController', action: 'index', format: 'HTML')
|
34
34
|
end
|
35
35
|
|
36
|
-
it
|
36
|
+
it 'should parse nested :processing lines correctly' do
|
37
37
|
line = ' Processing by Projects::QueriesController#index as HTML'
|
38
38
|
subject.should parse_line(line).as(:processing).and_capture(
|
39
|
-
:
|
39
|
+
controller: 'Projects::QueriesController', action: 'index', format: 'HTML')
|
40
40
|
end
|
41
41
|
|
42
|
-
it
|
42
|
+
it 'should parse :processing lines correctly with format */*' do
|
43
43
|
line = ' Processing by ProjectsController#avatar as */*'
|
44
44
|
subject.should parse_line(line).as(:processing).and_capture(
|
45
|
-
:
|
45
|
+
controller: 'ProjectsController', action: 'avatar', format: '*/*')
|
46
46
|
end
|
47
47
|
|
48
|
-
it
|
48
|
+
it 'should parse :processing lines correctly without format' do
|
49
49
|
line = ' Processing by ProjectsController#avatar as '
|
50
50
|
subject.should parse_line(line).as(:processing).and_capture(
|
51
|
-
:
|
51
|
+
controller: 'ProjectsController', action: 'avatar', format: '')
|
52
52
|
end
|
53
53
|
|
54
|
-
it
|
54
|
+
it 'should parse a :parameters line correctly' do
|
55
55
|
line = ' Parameters: {"action"=>"cached", "controller"=>"cached"}'
|
56
|
-
subject.should parse_line(line).as(:parameters).and_capture(:
|
56
|
+
subject.should parse_line(line).as(:parameters).and_capture(params: { action: 'cached', controller: 'cached' })
|
57
57
|
end
|
58
58
|
|
59
|
-
it
|
59
|
+
it 'should parse a :parameters line with no indentation correctly' do
|
60
60
|
line = 'Parameters: {"action"=>"cached", "controller"=>"cached"}'
|
61
|
-
subject.should parse_line(line).as(:parameters).and_capture(:
|
61
|
+
subject.should parse_line(line).as(:parameters).and_capture(params: { action: 'cached', controller: 'cached' })
|
62
62
|
end
|
63
63
|
|
64
|
-
it
|
64
|
+
it 'should parse :completed lines correctly' do
|
65
65
|
line = 'Completed 200 OK in 170ms (Views: 78.0ms | ActiveRecord: 48.2ms)'
|
66
66
|
subject.should parse_line(line).as(:completed).and_capture(
|
67
|
-
:
|
67
|
+
duration: 0.170, view: 0.078, db: 0.0482, status: 200)
|
68
68
|
end
|
69
69
|
|
70
|
-
it
|
70
|
+
it 'should parse :completed lines correctly when ActiveRecord is not mentioned' do
|
71
71
|
line = 'Completed 200 OK in 364ms (Views: 31.4ms)'
|
72
|
-
subject.should parse_line(line).as(:completed).and_capture(:
|
72
|
+
subject.should parse_line(line).as(:completed).and_capture(duration: 0.364, status: 200)
|
73
73
|
end
|
74
74
|
|
75
|
-
it
|
75
|
+
it 'should parse :completed lines correctly when other durations are specified' do
|
76
76
|
line = 'Completed 200 OK in 384ms (Views: 222.0ms | ActiveRecord: 121.0ms | Sphinx: 0.0ms)'
|
77
|
-
subject.should parse_line(line).as(:completed).and_capture(:
|
78
|
-
:
|
77
|
+
subject.should parse_line(line).as(:completed).and_capture(duration: 0.384, view: 0.222,
|
78
|
+
db: 0.121, status: 200)
|
79
79
|
end
|
80
80
|
|
81
|
-
it
|
81
|
+
it 'should parse :routing_error lines correctly' do
|
82
82
|
line = "ActionController::RoutingError (No route matches [GET] \"/static/faq\"):"
|
83
|
-
subject.should parse_line(line).as(:routing_errors).and_capture(:
|
84
|
-
|
83
|
+
subject.should parse_line(line).as(:routing_errors).and_capture(missing_resource_method: 'GET',
|
84
|
+
missing_resource: '/static/faq')
|
85
85
|
end
|
86
86
|
|
87
|
-
it
|
87
|
+
it 'should parse :failure lines correctly' do
|
88
88
|
line = "ActionView::Template::Error (undefined local variable or method `field' for #<Class>) on line #3 of /Users/willem/Code/warehouse/app/views/queries/execute.csv.erb:"
|
89
|
-
subject.should parse_line(line).as(:failure).and_capture(:
|
90
|
-
|
91
|
-
|
92
|
-
|
89
|
+
subject.should parse_line(line).as(:failure).and_capture(line: 3,
|
90
|
+
error: 'ActionView::Template::Error',
|
91
|
+
message: "undefined local variable or method `field' for #<Class>",
|
92
|
+
file: '/Users/willem/Code/warehouse/app/views/queries/execute.csv.erb')
|
93
93
|
end
|
94
94
|
|
95
|
-
it
|
96
|
-
line =
|
97
|
-
subject.should parse_line(line).as(:rendered).and_capture(:
|
95
|
+
it 'should parse :rendered lines as an array' do
|
96
|
+
line = ' Rendered queries/index.html.erb (0.6ms)'
|
97
|
+
subject.should parse_line(line).as(:rendered).and_capture(partial_duration: [0.0006])
|
98
98
|
end
|
99
99
|
|
100
|
-
it
|
101
|
-
line =
|
102
|
-
subject.should parse_line(line).as(:rendered).and_capture(:
|
100
|
+
it 'should parse :rendered lines with no identation as an array' do
|
101
|
+
line = 'Rendered queries/index.html.erb (0.6ms)'
|
102
|
+
subject.should parse_line(line).as(:rendered).and_capture(partial_duration: [0.0006])
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
106
|
describe '#parse_io' do
|
107
107
|
let(:log_parser) { RequestLogAnalyzer::Source::LogParser.new(subject) }
|
108
108
|
|
109
|
-
it
|
109
|
+
it 'should parse a successful request correctly' do
|
110
110
|
log = <<-EOLOG
|
111
111
|
Started GET "/" for 127.0.0.1 at Fri Mar 19 06:40:41 -0700 2010
|
112
112
|
Processing by QueriesController#index as HTML
|
@@ -121,7 +121,7 @@ describe RequestLogAnalyzer::FileFormat::Rails3 do
|
|
121
121
|
log_parser.parse_string(log)
|
122
122
|
end
|
123
123
|
|
124
|
-
it
|
124
|
+
it 'should count partials correctly' do
|
125
125
|
log = <<-EOLOG
|
126
126
|
Started GET "/stream_support" for 127.0.0.1 at 2012-11-21 15:21:31 +0100
|
127
127
|
Processing by HomeController#stream_support as */*
|
@@ -133,7 +133,7 @@ describe RequestLogAnalyzer::FileFormat::Rails3 do
|
|
133
133
|
log_parser.parse_string(log)
|
134
134
|
end
|
135
135
|
|
136
|
-
it
|
136
|
+
it 'should parse a failing request correctly' do
|
137
137
|
log = <<-EOLOG
|
138
138
|
Started POST "/queries/397638749/execute.csv" for 127.0.0.1 at Mon Mar 01 18:44:33 -0800 2010
|
139
139
|
Processing by QueriesController#execute as CSV
|
@@ -5,12 +5,12 @@ describe RequestLogAnalyzer::FileFormat::Rails do
|
|
5
5
|
describe '.create' do
|
6
6
|
|
7
7
|
context 'without providing a lines argument' do
|
8
|
-
subject { RequestLogAnalyzer::FileFormat::Rails.create }
|
8
|
+
subject { RequestLogAnalyzer::FileFormat::Rails.create }
|
9
9
|
|
10
10
|
it { should be_well_formed }
|
11
|
-
it { should
|
11
|
+
it { should satisfy { |ff| ff.report_trackers.length >= 11 } }
|
12
12
|
|
13
|
-
it
|
13
|
+
it 'should parse the lines in the production set' do
|
14
14
|
subject.line_definitions.should == RequestLogAnalyzer::FileFormat.load(:rails, 'production').line_definitions
|
15
15
|
end
|
16
16
|
end
|
@@ -19,8 +19,8 @@ describe RequestLogAnalyzer::FileFormat::Rails do
|
|
19
19
|
subject { RequestLogAnalyzer::FileFormat.load(:rails, 'minimal,failure') }
|
20
20
|
|
21
21
|
it { should be_well_formed }
|
22
|
-
it { should
|
23
|
-
|
22
|
+
it { should satisfy { |ff| ff.report_trackers.length >= 10 } }
|
23
|
+
|
24
24
|
it { should have_line_definition(:processing) }
|
25
25
|
it { should have_line_definition(:completed) }
|
26
26
|
it { should have_line_definition(:failure) }
|
@@ -32,102 +32,101 @@ describe RequestLogAnalyzer::FileFormat::Rails do
|
|
32
32
|
subject { RequestLogAnalyzer::FileFormat.load(:rails, constant) }
|
33
33
|
|
34
34
|
it { should be_well_formed }
|
35
|
-
it { should
|
35
|
+
it { should satisfy { |ff| ff.report_trackers.length >= 9 } }
|
36
36
|
|
37
37
|
it { should have_line_definition(:processing) }
|
38
38
|
it { should have_line_definition(:completed) }
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
subject { RequestLogAnalyzer::FileFormat.load(:rails, :all) }
|
44
44
|
|
45
45
|
describe '#parse_line' do
|
46
46
|
|
47
|
-
{'with prefix' => 'LINE PREFIX: ', 'without prefix' => '' }.each do |context, prefix|
|
47
|
+
{ 'with prefix' => 'LINE PREFIX: ', 'without prefix' => '' }.each do |context, prefix|
|
48
48
|
context context do
|
49
|
-
it
|
49
|
+
it 'should parse a :processing line correctly' do
|
50
50
|
line = prefix + 'Processing PeopleController#index (for 1.1.1.1 at 2008-08-14 21:16:30) [GET]'
|
51
|
-
subject.should parse_line(line).as(:processing).and_capture(:
|
51
|
+
subject.should parse_line(line).as(:processing).and_capture(controller: 'PeopleController', action: 'index', timestamp: 20_080_814_211_630, method: 'GET', ip: '1.1.1.1')
|
52
52
|
end
|
53
|
-
|
54
|
-
it
|
55
|
-
|
56
|
-
|
53
|
+
|
54
|
+
it 'should parse a :processing line correctly when it contains ipv6 localhost address' do
|
55
|
+
line = prefix + 'Processing PeopleController#index (for ::1 at 2008-08-14 21:16:30) [GET]'
|
56
|
+
subject.should parse_line(line).as(:processing).and_capture(controller: 'PeopleController', action: 'index', timestamp: 20_080_814_211_630, method: 'GET', ip: '::1')
|
57
57
|
end
|
58
58
|
|
59
|
-
it
|
60
|
-
|
61
|
-
|
59
|
+
it 'should parse a :processing line correctly when it contains ipv6 address' do
|
60
|
+
line = prefix + 'Processing PeopleController#index (for 3ffe:1900:4545:3:200:f8ff:fe21:67cf at 2008-08-14 21:16:30) [GET]'
|
61
|
+
subject.should parse_line(line).as(:processing).and_capture(controller: 'PeopleController', action: 'index', timestamp: 20_080_814_211_630, method: 'GET', ip: '3ffe:1900:4545:3:200:f8ff:fe21:67cf')
|
62
62
|
end
|
63
63
|
|
64
|
-
it
|
64
|
+
it 'should parse a Rails 2.1 style :completed line correctly' do
|
65
65
|
line = prefix + 'Completed in 0.21665 (4 reqs/sec) | Rendering: 0.00926 (4%) | DB: 0.00000 (0%) | 200 OK [http://demo.nu/employees]'
|
66
|
-
subject.should parse_line(line).as(:completed).and_capture(:
|
66
|
+
subject.should parse_line(line).as(:completed).and_capture(duration: 0.21665, db: 0.0, view: 0.00926, status: 200, url: 'http://demo.nu/employees')
|
67
67
|
end
|
68
68
|
|
69
|
-
it
|
69
|
+
it 'should parse a Rails 2.2 style :completed line correctly' do
|
70
70
|
line = prefix + 'Completed in 614ms (View: 120, DB: 31) | 200 OK [http://floorplanner.local/demo]'
|
71
|
-
subject.should parse_line(line).as(:completed).and_capture(:
|
71
|
+
subject.should parse_line(line).as(:completed).and_capture(duration: 0.614, db: 0.031, view: 0.120, status: 200, url: 'http://floorplanner.local/demo')
|
72
72
|
end
|
73
73
|
|
74
|
-
it
|
74
|
+
it 'should parse a Rails 2.2 style :completed line correctly when AR is disabled' do
|
75
75
|
line = prefix + 'Completed in 597ms (View: 298 | 200 OK [http://shapado.com]'
|
76
|
-
subject.should parse_line(line).as(:completed).and_capture(:
|
76
|
+
subject.should parse_line(line).as(:completed).and_capture(duration: 0.597, db: nil, view: 0.298, status: 200, url: 'http://shapado.com')
|
77
77
|
end
|
78
|
-
|
79
|
-
it
|
80
|
-
line = prefix +
|
81
|
-
subject.should parse_line(line).as(:completed).and_capture(:
|
78
|
+
|
79
|
+
it 'should parse a Rails 2.2 style :completed line without view' do
|
80
|
+
line = prefix + 'Completed in 148ms (DB: 0) | 302 Found [http://iwp-sod.hargray.org/login]'
|
81
|
+
subject.should parse_line(line).as(:completed).and_capture(duration: 0.148, db: 0.0, view: nil, status: 302, url: 'http://iwp-sod.hargray.org/login')
|
82
82
|
end
|
83
83
|
|
84
|
-
it
|
84
|
+
it 'should parse a :failure line with exception correctly' do
|
85
85
|
line = prefix + "NoMethodError (undefined method `update_domain_account' for nil:NilClass):"
|
86
|
-
subject.should parse_line(line).as(:failure).and_capture(:
|
86
|
+
subject.should parse_line(line).as(:failure).and_capture(error: 'NoMethodError', message: "undefined method `update_domain_account' for nil:NilClass")
|
87
87
|
end
|
88
88
|
|
89
|
-
it
|
89
|
+
it 'should parse a :cache_hit line correctly with an filter instance reference' do
|
90
90
|
line = prefix + 'Filter chain halted as [#<ActionController::Filters::AroundFilter:0x2a999ad120 @identifier=nil, @kind=:filter, @options={:only=>#<Set: {"cached"}>, :if=>:not_logged_in?, :unless=>nil}, @method=#<ActionController::Caching::Actions::ActionCacheFilter:0x2a999ad620 @check=nil, @options={:store_options=>{}, :layout=>nil, :cache_path=>#<Proc:0x0000002a999b8890@/app/controllers/cached_controller.rb:8>}>>] did_not_yield.'
|
91
91
|
subject.should parse_line(line).as(:cache_hit)
|
92
92
|
end
|
93
93
|
|
94
|
-
it
|
95
|
-
line = prefix + 'Filter chain halted as [#<ActionController::Filters::AroundFilter:0x2a9a923e38 @method=#<Proc:0x0000002a9818b3f8@/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_controller/caching/actions.rb:64>, @kind=:filter, @identifier=nil, @options={:unless=>nil, :if=>nil, :only=>#<Set: {"show"}>}>] did_not_yield.'
|
94
|
+
it 'should parse a :cache_hit line correctly with an proc instance reference' do
|
95
|
+
line = prefix + 'Filter chain halted as [#<ActionController::Filters::AroundFilter:0x2a9a923e38 @method=#<Proc:0x0000002a9818b3f8@/usr/local/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_controller/caching/actions.rb:64>, @kind=:filter, @identifier=nil, @options={:unless=>nil, :if=>nil, :only=>#<Set: {"show"}>}>] did_not_yield.'
|
96
96
|
subject.should parse_line(line).as(:cache_hit)
|
97
97
|
end
|
98
98
|
|
99
|
-
|
100
|
-
it "should parse a :parameters line correctly" do
|
99
|
+
it 'should parse a :parameters line correctly' do
|
101
100
|
line = prefix + ' Parameters: {"action"=>"cached", "controller"=>"cached"}'
|
102
|
-
subject.should parse_line(line).as(:parameters).and_capture(:
|
101
|
+
subject.should parse_line(line).as(:parameters).and_capture(params: { action: 'cached', controller: 'cached' })
|
103
102
|
end
|
104
103
|
|
105
|
-
it
|
104
|
+
it 'should parse a :rendered line correctly' do
|
106
105
|
line = prefix + 'Rendered layouts/_footer (2.9ms)'
|
107
|
-
subject.should parse_line(line).as(:rendered).and_capture(:
|
106
|
+
subject.should parse_line(line).as(:rendered).and_capture(render_file: 'layouts/_footer', render_duration: 0.0029)
|
108
107
|
end
|
109
108
|
|
110
|
-
it
|
109
|
+
it 'should parse a :query_executed line with colors' do
|
111
110
|
line = prefix + ' [4;36;1mUser Load (0.4ms)[0m [0;1mSELECT * FROM `users` WHERE (`users`.`id` = 18205844) [0m'
|
112
|
-
subject.should parse_line(line).as(:query_executed).and_capture(:
|
111
|
+
subject.should parse_line(line).as(:query_executed).and_capture(query_class: 'User', query_duration: 0.0004, query_sql: 'SELECT * FROM users WHERE (users.id = :int)')
|
113
112
|
end
|
114
113
|
|
115
|
-
it
|
114
|
+
it 'should parse a :query_executed line without colors' do
|
116
115
|
line = prefix + ' User Load (0.4ms) SELECT * FROM `users` WHERE (`users`.`id` = 18205844) '
|
117
|
-
subject.should parse_line(line).as(:query_executed).and_capture(:
|
116
|
+
subject.should parse_line(line).as(:query_executed).and_capture(query_class: 'User', query_duration: 0.0004, query_sql: 'SELECT * FROM users WHERE (users.id = :int)')
|
118
117
|
end
|
119
118
|
|
120
|
-
it
|
119
|
+
it 'should parse a :query_cached line with colors' do
|
121
120
|
line = prefix + ' [4;35;1mCACHE (0.0ms)[0m [0mSELECT * FROM `users` WHERE (`users`.`id` = 0) [0m'
|
122
|
-
subject.should parse_line(line).as(:query_cached).and_capture(:
|
121
|
+
subject.should parse_line(line).as(:query_cached).and_capture(cached_duration: 0.0, cached_sql: 'SELECT * FROM users WHERE (users.id = :int)')
|
123
122
|
end
|
124
123
|
|
125
|
-
it
|
124
|
+
it 'should parse a :query_cached line without colors' do
|
126
125
|
line = prefix + ' CACHE (0.0ms) SELECT * FROM `users` WHERE (`users`.`id` = 0) '
|
127
|
-
subject.should parse_line(line).as(:query_cached).and_capture(:
|
126
|
+
subject.should parse_line(line).as(:query_cached).and_capture(cached_duration: 0.0, cached_sql: 'SELECT * FROM users WHERE (users.id = :int)')
|
128
127
|
end
|
129
128
|
|
130
|
-
it
|
129
|
+
it 'should not parse an unsupported line' do
|
131
130
|
line = prefix + 'nonsense line that should not be parsed as anything'
|
132
131
|
subject.should_not parse_line(line)
|
133
132
|
end
|
@@ -136,27 +135,27 @@ describe RequestLogAnalyzer::FileFormat::Rails do
|
|
136
135
|
end
|
137
136
|
|
138
137
|
describe '#parse_io' do
|
139
|
-
let(:log_parser) { RequestLogAnalyzer::Source::LogParser.new(subject, :
|
138
|
+
let(:log_parser) { RequestLogAnalyzer::Source::LogParser.new(subject, parse_strategy: 'cautious') }
|
140
139
|
|
141
|
-
it
|
140
|
+
it 'should parse a Rails 2.1 style log and find valid Rails requests without warnings' do
|
142
141
|
log_parser.should_receive(:handle_request).exactly(4).times
|
143
142
|
log_parser.should_not_receive(:warn)
|
144
|
-
log_parser.parse_file(log_fixture(:rails_1x))
|
143
|
+
log_parser.parse_file(log_fixture(:rails_1x))
|
145
144
|
end
|
146
145
|
|
147
|
-
it
|
146
|
+
it 'should parse a Rails 2.2 style log and find valid Rails requests without warnings' do
|
148
147
|
log_parser.should_receive(:handle_request).once
|
149
148
|
log_parser.should_not_receive(:warn)
|
150
149
|
log_parser.parse_file(log_fixture(:rails_22))
|
151
150
|
end
|
152
151
|
|
153
|
-
it
|
152
|
+
it 'should parse a Rails SyslogLogger file with prefix and find valid requests without warnings' do
|
154
153
|
log_parser.should_receive(:handle_request).once
|
155
154
|
log_parser.should_not_receive(:warn)
|
156
155
|
log_parser.parse_file(log_fixture(:syslog_1x))
|
157
156
|
end
|
158
157
|
|
159
|
-
it
|
158
|
+
it 'should parse cached requests' do
|
160
159
|
log_parser.should_not_receive(:warn)
|
161
160
|
log_parser.parse_file(log_fixture(:rails_22_cached)) do |request|
|
162
161
|
request.should be_completed
|
@@ -164,7 +163,7 @@ describe RequestLogAnalyzer::FileFormat::Rails do
|
|
164
163
|
end
|
165
164
|
end
|
166
165
|
|
167
|
-
it
|
166
|
+
it 'should detect unordered requests in the logs' do
|
168
167
|
log_parser.should_not_receive(:handle_request)
|
169
168
|
log_parser.should_receive(:warn).with(:unclosed_request, anything).once
|
170
169
|
log_parser.should_receive(:warn).with(:no_current_request, anything).at_least(:twice)
|
@@ -5,40 +5,43 @@ describe RequestLogAnalyzer::FileFormat::W3c do
|
|
5
5
|
subject { RequestLogAnalyzer::FileFormat.load(:w3c) }
|
6
6
|
|
7
7
|
it { should be_well_formed }
|
8
|
-
it
|
9
|
-
|
8
|
+
it do
|
9
|
+
should have_line_definition(:access).capturing(:timestamp, :remote_ip, :username, :local_ip, :port,
|
10
|
+
:method, :path, :http_status, :bytes_sent, :bytes_received, :duration, :user_agent, :referer)
|
11
|
+
end
|
12
|
+
|
13
|
+
it { should satisfy { |ff| ff.report_trackers.length == 10 } }
|
10
14
|
|
11
|
-
it { should have(10).report_trackers }
|
12
|
-
|
13
15
|
let(:sample1) { '2002-05-24 20:18:01 172.224.24.114 - 206.73.118.24 80 GET /Default.htm - 200 7930 248 31 Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+2000+Server) http://64.224.24.114/' }
|
14
16
|
let(:irrelevant) { '#Software: Microsoft Internet Information Services 6.0' }
|
15
|
-
|
17
|
+
|
16
18
|
describe '#parse_line' do
|
17
|
-
it
|
18
|
-
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
31
|
-
|
32
|
-
|
19
|
+
it do
|
20
|
+
should parse_line(sample1, 'an access line').and_capture(
|
21
|
+
timestamp: 20_020_524_201_801,
|
22
|
+
remote_ip: '172.224.24.114',
|
23
|
+
username: nil,
|
24
|
+
local_ip: '206.73.118.24',
|
25
|
+
port: 80,
|
26
|
+
method: 'GET',
|
27
|
+
path: '/Default.htm',
|
28
|
+
http_status: 200,
|
29
|
+
bytes_sent: 7930,
|
30
|
+
bytes_received: 248,
|
31
|
+
duration: 0.031,
|
32
|
+
user_agent: 'Mozilla/4.0+(compatible;+MSIE+5.01;+Windows+2000+Server)',
|
33
|
+
referer: 'http://64.224.24.114/')
|
34
|
+
end
|
35
|
+
|
33
36
|
it { should_not parse_line(irrelevant, 'an irrelevant line') }
|
34
37
|
it { should_not parse_line('nonsense', 'a nonsense line') }
|
35
38
|
end
|
36
|
-
|
39
|
+
|
37
40
|
describe '#parse_io' do
|
38
41
|
let(:log_parser) { RequestLogAnalyzer::Source::LogParser.new(subject) }
|
39
42
|
let(:snippet) { log_snippet(irrelevant, sample1, sample1) }
|
40
|
-
|
41
|
-
it
|
43
|
+
|
44
|
+
it 'should parse a snippet successully without warnings' do
|
42
45
|
log_parser.should_receive(:handle_request).twice
|
43
46
|
log_parser.should_not_receive(:warn)
|
44
47
|
log_parser.parse_io(snippet)
|
@@ -6,16 +6,16 @@ describe RequestLogAnalyzer::Filter::Anonymize, 'anonymize request' do
|
|
6
6
|
@filter = RequestLogAnalyzer::Filter::Anonymize.new(testing_format)
|
7
7
|
end
|
8
8
|
|
9
|
-
it
|
10
|
-
@filter.filter(request(:
|
9
|
+
it 'should anonimize ip' do
|
10
|
+
@filter.filter(request(ip: '123.123.123.123'))[:ip].should_not eql('123.123.123.123')
|
11
11
|
end
|
12
12
|
|
13
|
-
it
|
14
|
-
@filter.filter(request(:
|
13
|
+
it 'should anonimize url' do
|
14
|
+
@filter.filter(request(url: 'https://test.mysite.com/employees'))[:url].should eql('http://example.com/employees')
|
15
15
|
end
|
16
16
|
|
17
|
-
it
|
18
|
-
@filter.filter(request(:
|
17
|
+
it 'should fuzz durations' do
|
18
|
+
@filter.filter(request(duration: 100))[:duration].should_not eql(100)
|
19
19
|
end
|
20
20
|
|
21
|
-
end
|
21
|
+
end
|