wvanbergen-request-log-analyzer 1.1.0 → 1.1.1

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 (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