wvanbergen-request-log-analyzer 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/README.rdoc +4 -3
  2. data/bin/request-log-analyzer +4 -5
  3. data/lib/cli/command_line_arguments.rb +2 -2
  4. data/lib/request_log_analyzer/aggregator/summarizer.rb +2 -3
  5. data/lib/request_log_analyzer/{aggregator/base.rb → aggregator.rb} +5 -1
  6. data/lib/request_log_analyzer/controller.rb +11 -16
  7. data/lib/request_log_analyzer/file_format/merb.rb +32 -26
  8. data/lib/request_log_analyzer/file_format/rails.rb +73 -71
  9. data/lib/request_log_analyzer/file_format/rails_development.rb +93 -95
  10. data/lib/request_log_analyzer/file_format.rb +71 -38
  11. data/lib/request_log_analyzer/filter/anonimize.rb +1 -1
  12. data/lib/request_log_analyzer/filter.rb +38 -0
  13. data/lib/request_log_analyzer/line_definition.rb +1 -1
  14. data/lib/request_log_analyzer/output/fixed_width.rb +133 -117
  15. data/lib/request_log_analyzer/output/html.rb +138 -60
  16. data/lib/request_log_analyzer/output.rb +6 -8
  17. data/lib/request_log_analyzer/request.rb +3 -1
  18. data/lib/request_log_analyzer/source/{log_file.rb → log_parser.rb} +15 -6
  19. data/lib/request_log_analyzer/{source/base.rb → source.rb} +5 -0
  20. data/lib/request_log_analyzer/tracker/category.rb +7 -8
  21. data/lib/request_log_analyzer/tracker/duration.rb +15 -12
  22. data/lib/request_log_analyzer/tracker/hourly_spread.rb +8 -8
  23. data/lib/request_log_analyzer/tracker/timespan.rb +10 -10
  24. data/lib/request_log_analyzer/tracker.rb +58 -0
  25. data/lib/request_log_analyzer.rb +28 -6
  26. data/spec/controller_spec.rb +5 -4
  27. data/spec/database_inserter_spec.rb +5 -8
  28. data/spec/file_format_spec.rb +2 -2
  29. data/spec/file_formats/spec_format.rb +2 -1
  30. data/spec/filter_spec.rb +0 -3
  31. data/spec/log_parser_spec.rb +6 -6
  32. data/spec/merb_format_spec.rb +38 -38
  33. data/spec/rails_format_spec.rb +2 -2
  34. data/spec/request_spec.rb +2 -2
  35. data/spec/spec_helper.rb +3 -37
  36. data/tasks/github-gem.rake +2 -1
  37. metadata +7 -8
  38. data/lib/request_log_analyzer/filter/base.rb +0 -32
  39. data/lib/request_log_analyzer/log_parser.rb +0 -173
  40. data/lib/request_log_analyzer/tracker/base.rb +0 -54
@@ -12,22 +12,23 @@ describe RequestLogAnalyzer::Controller do
12
12
  it "should call the aggregators when run" do
13
13
 
14
14
  mock_output = mock('output')
15
+ mock_output.stub!(:io).and_return($stdout)
15
16
  mock_output.should_receive(:header)
16
- mock_output.should_receive(:footer)
17
+ mock_output.should_receive(:footer)
17
18
 
18
19
  file_format = RequestLogAnalyzer::FileFormat.load(:rails)
19
- source = RequestLogAnalyzer::Source::LogFile.new(file_format, :source_files => log_fixture(:rails_1x))
20
+ source = RequestLogAnalyzer::Source::LogParser.new(file_format, :source_files => log_fixture(:rails_1x))
20
21
  controller = RequestLogAnalyzer::Controller.new(source, :output => mock_output)
21
22
 
22
23
  mock_aggregator = mock('aggregator')
23
24
  mock_aggregator.should_receive(:prepare).once.ordered
24
- mock_aggregator.should_receive(:aggregate).with(an_instance_of(RequestLogAnalyzer::Request)).at_least(:twice).ordered
25
+ mock_aggregator.should_receive(:aggregate).with(an_instance_of(file_format.class::Request)).at_least(:twice).ordered
25
26
  mock_aggregator.should_receive(:finalize).once.ordered
26
27
  mock_aggregator.should_receive(:report).once.ordered
27
28
 
28
29
  another_mock_aggregator = mock('another aggregator')
29
30
  another_mock_aggregator.should_receive(:prepare).once.ordered
30
- another_mock_aggregator.should_receive(:aggregate).with(an_instance_of(RequestLogAnalyzer::Request)).at_least(:twice).ordered
31
+ another_mock_aggregator.should_receive(:aggregate).with(an_instance_of(file_format.class::Request)).at_least(:twice).ordered
31
32
  another_mock_aggregator.should_receive(:finalize).once.ordered
32
33
  another_mock_aggregator.should_receive(:report).once.ordered
33
34
 
@@ -8,7 +8,7 @@ describe RequestLogAnalyzer::Aggregator::Database, "schema creation" do
8
8
  include RequestLogAnalyzerSpecHelper
9
9
 
10
10
  before(:each) do
11
- log_parser = RequestLogAnalyzer::LogParser.new(spec_format)
11
+ log_parser = RequestLogAnalyzer::Source::LogParser.new(spec_format)
12
12
  @database_inserter = RequestLogAnalyzer::Aggregator::Database.new(log_parser, :database => TEST_DATABASE_FILE)
13
13
  end
14
14
 
@@ -68,16 +68,13 @@ describe RequestLogAnalyzer::Aggregator::Database, "record insertion" do
68
68
  include RequestLogAnalyzerSpecHelper
69
69
 
70
70
  before(:each) do
71
- log_parser = RequestLogAnalyzer::LogParser.new(spec_format)
71
+ log_parser = RequestLogAnalyzer::Source::LogParser.new(spec_format)
72
72
  @database_inserter = RequestLogAnalyzer::Aggregator::Database.new(log_parser, :database => TEST_DATABASE_FILE)
73
73
  @database_inserter.prepare
74
74
 
75
- @incomplete_request = RequestLogAnalyzer::Request.create(spec_format, {:line_type => :first, :request_no => 564})
76
- @completed_request = RequestLogAnalyzer::Request.create(spec_format,
77
- {:line_type => :first, :request_no => 564},
78
- {:line_type => :test, :test_capture => "awesome"},
79
- {:line_type => :test, :test_capture => "indeed"},
80
- {:line_type => :last, :request_no => 564})
75
+ @incomplete_request = spec_format.create_request( {:line_type => :first, :request_no => 564})
76
+ @completed_request = spec_format.create_request( {:line_type => :first, :request_no => 564}, {:line_type => :test, :test_capture => "awesome"},
77
+ {:line_type => :test, :test_capture => "indeed"}, {:line_type => :last, :request_no => 564})
81
78
  end
82
79
 
83
80
  after(:each) do
@@ -3,8 +3,8 @@ require File.dirname(__FILE__) + '/spec_helper'
3
3
  describe RequestLogAnalyzer::FileFormat, :format_definition do
4
4
 
5
5
  before(:each) do
6
- @first_file_format = Class.new(RequestLogAnalyzer::FileFormat)
7
- @second_file_format = Class.new(RequestLogAnalyzer::FileFormat)
6
+ @first_file_format = Class.new(RequestLogAnalyzer::FileFormat::Base)
7
+ @second_file_format = Class.new(RequestLogAnalyzer::FileFormat::Base)
8
8
  end
9
9
 
10
10
  it "should specify lines with a hash" do
@@ -1,4 +1,4 @@
1
- class SpecFormat < RequestLogAnalyzer::FileFormat
1
+ class SpecFormat < RequestLogAnalyzer::FileFormat::Base
2
2
 
3
3
  format_definition.first do |line|
4
4
  line.header = true
@@ -23,4 +23,5 @@ class SpecFormat < RequestLogAnalyzer::FileFormat
23
23
  report do |analyze|
24
24
  analyze.category :test_capture, :title => 'What is testing exactly?'
25
25
  end
26
+
26
27
  end
data/spec/filter_spec.rb CHANGED
@@ -1,7 +1,4 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
- require File.dirname(__FILE__) + '/../lib/request_log_analyzer/filter/timespan'
3
- require File.dirname(__FILE__) + '/../lib/request_log_analyzer/filter/field'
4
- require File.dirname(__FILE__) + '/../lib/request_log_analyzer/filter/anonimize'
5
2
 
6
3
  describe RequestLogAnalyzer::Filter::Timespan, 'both before and after' do
7
4
  include RequestLogAnalyzerSpecHelper
@@ -1,10 +1,10 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- describe RequestLogAnalyzer::LogParser, :requests do
3
+ describe RequestLogAnalyzer::Source::LogParser, :requests do
4
4
  include RequestLogAnalyzerSpecHelper
5
5
 
6
6
  before(:each) do
7
- @log_parser = RequestLogAnalyzer::LogParser.new(spec_format)
7
+ @log_parser = RequestLogAnalyzer::Source::LogParser.new(spec_format)
8
8
  end
9
9
 
10
10
  it "should have multiple line definitions" do
@@ -16,13 +16,13 @@ describe RequestLogAnalyzer::LogParser, :requests do
16
16
  end
17
17
 
18
18
  it "should parse more lines than requests" do
19
- @log_parser.should_receive(:handle_request).with(an_instance_of(RequestLogAnalyzer::Request)).twice
19
+ @log_parser.should_receive(:handle_request).with(an_instance_of(SpecFormat::Request)).twice
20
20
  @log_parser.parse_file(log_fixture(:test_language_combined))
21
21
  @log_parser.parsed_lines.should > 2
22
22
  end
23
23
 
24
24
  it "should parse requests spanned over multiple files" do
25
- @log_parser.should_receive(:handle_request).with(an_instance_of(RequestLogAnalyzer::Request)).once
25
+ @log_parser.should_receive(:handle_request).with(an_instance_of(SpecFormat::Request)).once
26
26
  @log_parser.parse_files([log_fixture(:multiple_files_1), log_fixture(:multiple_files_2)])
27
27
  end
28
28
 
@@ -47,11 +47,11 @@ describe RequestLogAnalyzer::LogParser, :requests do
47
47
 
48
48
  end
49
49
 
50
- describe RequestLogAnalyzer::LogParser, :warnings do
50
+ describe RequestLogAnalyzer::Source::LogParser, :warnings do
51
51
  include RequestLogAnalyzerSpecHelper
52
52
 
53
53
  before(:each) do
54
- @log_parser = RequestLogAnalyzer::LogParser.new(spec_format)
54
+ @log_parser = RequestLogAnalyzer::Source::LogParser.new(spec_format)
55
55
  end
56
56
 
57
57
  it "should warn about teaser matching problems" do
@@ -1,38 +1,38 @@
1
- # require File.dirname(__FILE__) + '/spec_helper'
2
- #
3
- # describe RequestLogAnalyzer::LogParser, "Merb" do
4
- # include RequestLogAnalyzerSpecHelper
5
- #
6
- # before(:each) do
7
- # @log_parser = RequestLogAnalyzer::LogParser.new(:merb)
8
- # end
9
- #
10
- # it "should have a valid language definitions" do
11
- # @log_parser.file_format.should be_valid
12
- # end
13
- #
14
- # it "should parse a stream and find valid requests" do
15
- # File.open(log_fixture(:merb), 'r') do |io|
16
- # @log_parser.parse_io(io) do |request|
17
- # request.should be_kind_of(RequestLogAnalyzer::Request)
18
- # end
19
- # end
20
- # end
21
- #
22
- # it "should find 11 completed requests" do
23
- # @log_parser.should_receive(:handle_request).exactly(11).times
24
- # @log_parser.parse_file(log_fixture(:merb))
25
- # end
26
- #
27
- # it "should parse all details from a request correctly" do
28
- # request = nil
29
- # @log_parser.parse_file(log_fixture(:merb)) { |found_request| request ||= found_request }
30
- #
31
- # request.should be_completed
32
- # request[:timestamp].should == DateTime.parse('Fri Aug 29 11:10:23 +0200 2008')
33
- # request[:dispatch_time].should == 0.243424
34
- # request[:after_filters_time].should == 6.9e-05
35
- # request[:before_filters_time].should == 0.213213
36
- # request[:action_time].should == 0.241652
37
- # end
38
- # end
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe RequestLogAnalyzer::Source::LogParser, :merb do
4
+ include RequestLogAnalyzerSpecHelper
5
+
6
+ before(:each) do
7
+ @log_parser = RequestLogAnalyzer::Source::LogParser.new(RequestLogAnalyzer::FileFormat.load(:merb))
8
+ end
9
+
10
+ it "should have a valid language definitions" do
11
+ @log_parser.file_format.should be_valid
12
+ end
13
+
14
+ it "should parse a stream and find valid requests" do
15
+ File.open(log_fixture(:merb), 'r') do |io|
16
+ @log_parser.parse_io(io) do |request|
17
+ request.should be_kind_of(RequestLogAnalyzer::Request)
18
+ end
19
+ end
20
+ end
21
+
22
+ it "should find 11 completed requests" do
23
+ @log_parser.should_receive(:handle_request).exactly(11).times
24
+ @log_parser.parse_file(log_fixture(:merb))
25
+ end
26
+
27
+ it "should parse all details from a request correctly" do
28
+ request = nil
29
+ @log_parser.parse_file(log_fixture(:merb)) { |found_request| request ||= found_request }
30
+
31
+ request.should be_completed
32
+ #request[:timestamp].should == DateTime.parse('Fri Aug 29 11:10:23 +0200 2008') # FIX ME
33
+ request[:dispatch_time].should == 0.243424
34
+ request[:after_filters_time].should == 6.9e-05
35
+ request[:before_filters_time].should == 0.213213
36
+ request[:action_time].should == 0.241652
37
+ end
38
+ end
@@ -1,10 +1,10 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper'
2
2
 
3
- describe RequestLogAnalyzer::LogParser, "Rails" do
3
+ describe RequestLogAnalyzer::Source::LogParser, "Rails" do
4
4
  include RequestLogAnalyzerSpecHelper
5
5
 
6
6
  before(:each) do
7
- @log_parser = RequestLogAnalyzer::LogParser.new(RequestLogAnalyzer::FileFormat.load(:rails))
7
+ @log_parser = RequestLogAnalyzer::Source::LogParser.new(RequestLogAnalyzer::FileFormat.load(:rails))
8
8
  end
9
9
 
10
10
  it "should have a valid language definitions" do
data/spec/request_spec.rb CHANGED
@@ -5,7 +5,7 @@ describe RequestLogAnalyzer::Request, :incomplete_request do
5
5
  include RequestLogAnalyzerSpecHelper
6
6
 
7
7
  before(:each) do
8
- @incomplete_request = RequestLogAnalyzer::Request.new(spec_format)
8
+ @incomplete_request = spec_format.create_request
9
9
  @incomplete_request << { :line_type => :test, :lineno => 1, :test_capture => 'awesome!' }
10
10
  end
11
11
 
@@ -37,7 +37,7 @@ describe RequestLogAnalyzer::Request, :completed_request do
37
37
  include RequestLogAnalyzerSpecHelper
38
38
 
39
39
  before(:each) do
40
- @completed_request = RequestLogAnalyzer::Request.new(spec_format)
40
+ @completed_request = spec_format.create_request
41
41
  @completed_request << { :line_type => :first, :lineno => 1, :name => 'first line!' }
42
42
  @completed_request << { :line_type => :test, :lineno => 4, :test_capture => 'testing' }
43
43
  @completed_request << { :line_type => :test, :lineno => 7, :test_capture => 'testing some more' }
data/spec/spec_helper.rb CHANGED
@@ -21,47 +21,13 @@ module RequestLogAnalyzerSpecHelper
21
21
  File.dirname(__FILE__) + "/fixtures/#{name}.log"
22
22
  end
23
23
 
24
- def request(fields, format = TestFileFormat)
24
+ def request(fields, format = spec_format)
25
25
  if fields.kind_of?(Array)
26
- RequestLogAnalyzer::Request.create(format, *fields)
26
+ format.create_request(*fields)
27
27
  else
28
- RequestLogAnalyzer::Request.create(format, fields)
28
+ format.create_request(fields)
29
29
  end
30
30
  end
31
31
 
32
32
  end
33
33
 
34
- module TestFileFormat
35
-
36
- module Summarizer
37
- def self.included(base)
38
- # monkey patching for summarizer here :-)
39
- end
40
- end
41
-
42
- module LogParser
43
- def self.included(base)
44
- # monkey patching for log parser here :-)
45
- end
46
- end
47
-
48
- LINE_DEFINITIONS = {
49
- :first => {
50
- :header => true,
51
- :teaser => /processing /,
52
- :regexp => /processing request (\d+)/,
53
- :captures => [{ :name => :request_no, :type => :integer, :anonymize => :slightly }]
54
- },
55
- :test => {
56
- :teaser => /testing /,
57
- :regexp => /testing is (\w+)/,
58
- :captures => [{ :name => :test_capture, :type => :string, :anonymize => true}]
59
- },
60
- :last => {
61
- :footer => true,
62
- :teaser => /finishing /,
63
- :regexp => /finishing request (\d+)/,
64
- :captures => [{ :name => :request_no, :type => :integer}]
65
- }
66
- }
67
- end
@@ -241,7 +241,8 @@ module Rake
241
241
 
242
242
  def release_task
243
243
  puts
244
- puts "Released #{@name} - version#{@specification.version}"
244
+ puts '------------------------------------------------------------'
245
+ puts "Released #{@name} - version #{@specification.version}"
245
246
  end
246
247
  end
247
248
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wvanbergen-request-log-analyzer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
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-01-18 00:00:00 -08:00
13
+ date: 2009-01-21 00:00:00 -08:00
14
14
  default_executable: request-log-analyzer
15
15
  dependencies: []
16
16
 
@@ -37,7 +37,7 @@ files:
37
37
  - lib/request_log_analyzer
38
38
  - lib/request_log_analyzer.rb
39
39
  - lib/request_log_analyzer/aggregator
40
- - lib/request_log_analyzer/aggregator/base.rb
40
+ - lib/request_log_analyzer/aggregator.rb
41
41
  - lib/request_log_analyzer/aggregator/database.rb
42
42
  - lib/request_log_analyzer/aggregator/echo.rb
43
43
  - lib/request_log_analyzer/aggregator/summarizer.rb
@@ -48,12 +48,11 @@ files:
48
48
  - lib/request_log_analyzer/file_format/rails.rb
49
49
  - lib/request_log_analyzer/file_format/rails_development.rb
50
50
  - lib/request_log_analyzer/filter
51
+ - lib/request_log_analyzer/filter.rb
51
52
  - lib/request_log_analyzer/filter/anonimize.rb
52
- - lib/request_log_analyzer/filter/base.rb
53
53
  - lib/request_log_analyzer/filter/field.rb
54
54
  - lib/request_log_analyzer/filter/timespan.rb
55
55
  - lib/request_log_analyzer/line_definition.rb
56
- - lib/request_log_analyzer/log_parser.rb
57
56
  - lib/request_log_analyzer/log_processor.rb
58
57
  - lib/request_log_analyzer/output
59
58
  - lib/request_log_analyzer/output.rb
@@ -61,10 +60,10 @@ files:
61
60
  - lib/request_log_analyzer/output/html.rb
62
61
  - lib/request_log_analyzer/request.rb
63
62
  - lib/request_log_analyzer/source
64
- - lib/request_log_analyzer/source/base.rb
65
- - lib/request_log_analyzer/source/log_file.rb
63
+ - lib/request_log_analyzer/source.rb
64
+ - lib/request_log_analyzer/source/log_parser.rb
66
65
  - lib/request_log_analyzer/tracker
67
- - lib/request_log_analyzer/tracker/base.rb
66
+ - lib/request_log_analyzer/tracker.rb
68
67
  - lib/request_log_analyzer/tracker/category.rb
69
68
  - lib/request_log_analyzer/tracker/duration.rb
70
69
  - lib/request_log_analyzer/tracker/hourly_spread.rb
@@ -1,32 +0,0 @@
1
- module RequestLogAnalyzer
2
- module Filter
3
- # Base filter class used to filter input requests.
4
- # All filters should interit from this base.
5
- class Base
6
-
7
- include RequestLogAnalyzer::FileFormat::Awareness
8
-
9
- attr_reader :log_parser
10
- attr_reader :options
11
-
12
- # Initializer
13
- # <tt>format</tt> The file format
14
- # <tt>options</tt> Are passed to the filters.
15
- def initialize(format, options = {})
16
- @options = options
17
- register_file_format(format)
18
- end
19
-
20
- # Initialize the filter
21
- def prepare
22
- end
23
-
24
- # Return the request if the request should be kept.
25
- # Return nil otherwise.
26
- def filter(request)
27
- return nil unless request
28
- return request
29
- end
30
- end
31
- end
32
- end
@@ -1,173 +0,0 @@
1
- module RequestLogAnalyzer
2
-
3
- # The LogParser class reads log data from a given source and uses a file format definition
4
- # to parse all relevent information about requests from the file. A FileFormat module should
5
- # be provided that contains the definitions of the lines that occur in the log data.
6
- #
7
- # De order in which lines occur is used to combine lines to a single request. If these lines
8
- # are mixed, requests cannot be combined properly. This can be the case if data is written to
9
- # the log file simultaneously by different mongrel processes. This problem is detected by the
10
- # parser, but the requests that are mixed up cannot be parsed. It will emit warnings when this
11
- # occurs.
12
- class LogParser
13
-
14
- include RequestLogAnalyzer::FileFormat::Awareness
15
-
16
- # A hash of options
17
- attr_reader :options
18
-
19
- # The current Request object that is being parsed
20
- attr_reader :current_request
21
-
22
- # The total number of parsed lines
23
- attr_reader :parsed_lines
24
-
25
- # The total number of parsed requests.
26
- attr_reader :parsed_requests
27
-
28
- # The number of skipped requests because of date constraints
29
- attr_reader :skipped_requests
30
-
31
- # Initializes the parser instance.
32
- # It will apply the language specific FileFormat module to this instance. It will use the line
33
- # definitions in this module to parse any input.
34
- def initialize(format, options = {})
35
- @line_definitions = {}
36
- @options = options
37
- @parsed_lines = 0
38
- @parsed_requests = 0
39
- @skipped_requests = 0
40
-
41
- @current_io = nil
42
-
43
- # install the file format module (see RequestLogAnalyzer::FileFormat)
44
- # and register all the line definitions to the parser
45
- self.register_file_format(format)
46
- end
47
-
48
- # Parses a list of consequent files of the same format
49
- def parse_files(files, options = {}, &block)
50
- files.each { |file| parse_file(file, options, &block) }
51
- end
52
-
53
- # Parses a file.
54
- # Creates an IO stream for the provided file, and sends it to parse_io for further handling
55
- def parse_file(file, options = {}, &block)
56
- @progress_handler.call(:started, file) if @progress_handler
57
- File.open(file, 'r') { |f| parse_io(f, options, &block) }
58
- @progress_handler.call(:finished, file) if @progress_handler
59
- end
60
-
61
- def parse_stream(stream, options = {}, &block)
62
- parse_io(stream, options, &block)
63
- end
64
-
65
- # Finds a log line and then parses the information in the line.
66
- # Yields a hash containing the information found.
67
- # <tt>*line_types</tt> The log line types to look for (defaults to LOG_LINES.keys).
68
- # Yeilds a Hash when it encounters a chunk of information.
69
- def parse_io(io, options = {}, &block)
70
-
71
- # parse every line type by default
72
- line_types = options[:line_types] || file_format.line_definitions.keys
73
-
74
- # check whether all provided line types are valid
75
- unknown = line_types.reject { |line_type| file_format.line_definitions.has_key?(line_type) }
76
- raise "Unknown line types: #{unknown.join(', ')}" unless unknown.empty?
77
-
78
- @current_io = io
79
- @current_io.each_line do |line|
80
-
81
- @progress_handler.call(:progress, @current_io.pos) if @progress_handler && @current_io.kind_of?(File)
82
-
83
- request_data = nil
84
- line_types.each do |line_type|
85
- line_type_definition = file_format.line_definitions[line_type]
86
- break if request_data = line_type_definition.matches(line, @current_io.lineno, self)
87
- end
88
-
89
- if request_data
90
- @parsed_lines += 1
91
- update_current_request(request_data, &block)
92
- end
93
- end
94
-
95
- warn(:unfinished_request_on_eof, "End of file reached, but last request was not completed!") unless @current_request.nil?
96
-
97
- @current_io = nil
98
- end
99
-
100
- # Add a block to this method to install a progress handler while parsing
101
- def progress=(proc)
102
- @progress_handler = proc
103
- end
104
-
105
- # Add a block to this method to install a warning handler while parsing
106
- def warning=(proc)
107
- @warning_handler = proc
108
- end
109
-
110
- # This method is called by the parser if it encounteres any problems.
111
- # It will call the warning handler. The default controller will pass all warnings to every
112
- # aggregator that is registered and running
113
- def warn(type, message)
114
- @warning_handler.call(type, message, @current_io.lineno) if @warning_handler
115
- end
116
-
117
- protected
118
-
119
- # Combines the different lines of a request into a single Request object. It will start a
120
- # new request when a header line is encountered en will emit the request when a footer line
121
- # is encountered.
122
- #
123
- # - Every line that is parsed before a header line is ignored as it cannot be included in
124
- # any request. It will emit a :no_current_request warning.
125
- # - A header line that is parsed before a request is closed by a footer line, is a sign of
126
- # an unprpertly ordered file. All data that is gathered for the request until then is
127
- # discarded, the next request is ignored as well and a :unclosed_request warning is
128
- # emitted.
129
- def update_current_request(request_data, &block)
130
- if header_line?(request_data)
131
- unless @current_request.nil?
132
- if options[:assume_correct_order]
133
- handle_request(@current_request, &block)
134
- @current_request = RequestLogAnalyzer::Request.create(@file_format, request_data)
135
- else
136
- warn(:unclosed_request, "Encountered header line, but previous request was not closed!")
137
- @current_request = nil # remove all data that was parsed, skip next request as well.
138
- end
139
- else
140
- @current_request = RequestLogAnalyzer::Request.create(@file_format, request_data)
141
- end
142
- else
143
- unless @current_request.nil?
144
- @current_request << request_data
145
- if footer_line?(request_data)
146
- handle_request(@current_request, &block)
147
- @current_request = nil
148
- end
149
- else
150
- warn(:no_current_request, "Parsebale line found outside of a request!")
151
- end
152
- end
153
- end
154
-
155
- # Handles the parsed request by calling the request handler.
156
- # The default controller will send the request to every running aggegator.
157
- def handle_request(request, &block)
158
- @parsed_requests += 1
159
- accepted = block_given? ? yield(request) : true
160
- @skipped_requests += 1 if !accepted
161
- end
162
-
163
- # Checks whether a given line hash is a header line.
164
- def header_line?(hash)
165
- file_format.line_definitions[hash[:line_type]].header
166
- end
167
-
168
- # Checks whether a given line hash is a footer line.
169
- def footer_line?(hash)
170
- file_format.line_definitions[hash[:line_type]].footer
171
- end
172
- end
173
- end
@@ -1,54 +0,0 @@
1
- module RequestLogAnalyzer
2
- module Tracker
3
-
4
- # Base tracker. All other trackers inherit from this class
5
- #
6
- # Accepts the following options:
7
- # * <tt>:line_type</tt> The line type that contains the duration field (determined by the category proc).
8
- # * <tt>:if</tt> Proc that has to return !nil for a request to be passed to the tracker.
9
- # * <tt>:output</tt> Direct output here (defaults to STDOUT)
10
- #
11
- # For example :if => lambda { |request| request[:duration] && request[:duration] > 1.0 }
12
- class Base
13
-
14
- attr_reader :options
15
-
16
- def initialize(options ={})
17
- @options = options
18
- end
19
-
20
- def prepare
21
- end
22
-
23
- def update(request)
24
- end
25
-
26
- def finalize
27
- end
28
-
29
- def should_update?(request)
30
- return false if options[:line_type] && !request.has_line_type?(options[:line_type])
31
-
32
- if options[:if].kind_of?(Symbol)
33
- return false unless request[options[:if]]
34
- elsif options[:if].respond_to?(:call)
35
- return false unless options[:if].call(request)
36
- end
37
-
38
- if options[:unless].kind_of?(Symbol)
39
- return false if request[options[:unless]]
40
- elsif options[:unless].respond_to?(:call)
41
- return false if options[:unless].call(request)
42
- end
43
-
44
- return true
45
- end
46
-
47
- def report(output)
48
- output << self.inspect
49
- output << "\n"
50
- end
51
-
52
- end
53
- end
54
- end