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.rb +28 -6
  5. data/lib/request_log_analyzer/{aggregator/base.rb → aggregator.rb} +5 -1
  6. data/lib/request_log_analyzer/aggregator/summarizer.rb +2 -3
  7. data/lib/request_log_analyzer/controller.rb +11 -16
  8. data/lib/request_log_analyzer/file_format.rb +71 -38
  9. data/lib/request_log_analyzer/file_format/merb.rb +32 -26
  10. data/lib/request_log_analyzer/file_format/rails.rb +73 -71
  11. data/lib/request_log_analyzer/file_format/rails_development.rb +93 -95
  12. data/lib/request_log_analyzer/filter.rb +38 -0
  13. data/lib/request_log_analyzer/filter/anonimize.rb +1 -1
  14. data/lib/request_log_analyzer/line_definition.rb +1 -1
  15. data/lib/request_log_analyzer/output.rb +6 -8
  16. data/lib/request_log_analyzer/output/fixed_width.rb +133 -117
  17. data/lib/request_log_analyzer/output/html.rb +138 -60
  18. data/lib/request_log_analyzer/request.rb +3 -1
  19. data/lib/request_log_analyzer/{source/base.rb → source.rb} +5 -0
  20. data/lib/request_log_analyzer/source/{log_file.rb → log_parser.rb} +15 -6
  21. data/lib/request_log_analyzer/tracker.rb +58 -0
  22. data/lib/request_log_analyzer/tracker/category.rb +7 -8
  23. data/lib/request_log_analyzer/tracker/duration.rb +15 -12
  24. data/lib/request_log_analyzer/tracker/hourly_spread.rb +8 -8
  25. data/lib/request_log_analyzer/tracker/timespan.rb +10 -10
  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
@@ -1,5 +1,5 @@
1
1
  module RequestLogAnalyzer::Tracker
2
-
2
+
3
3
  # Determines the average hourly spread of the parsed requests.
4
4
  # This spread is shown in a graph form.
5
5
  #
@@ -26,15 +26,15 @@ module RequestLogAnalyzer::Tracker
26
26
  # 17:00 - 213 hits : ░░░░░
27
27
  # 18:00 - 107 hits : ░░
28
28
  # ................
29
- class HourlySpread < RequestLogAnalyzer::Tracker::Base
29
+ class HourlySpread < Base
30
30
 
31
31
  attr_reader :first, :last, :request_time_graph
32
-
32
+
33
33
  def prepare
34
34
  options[:field] ||= :timestamp
35
35
  @request_time_graph = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
36
36
  end
37
-
37
+
38
38
  def update(request)
39
39
  request = request.attributes
40
40
  timestamp = request[options[:field]]
@@ -43,10 +43,10 @@ module RequestLogAnalyzer::Tracker
43
43
  @first = timestamp if @first.nil? || timestamp < @first
44
44
  @last = timestamp if @last.nil? || timestamp > @last
45
45
  end
46
-
46
+
47
47
  def report(output)
48
48
  output.title("Requests graph - average per day per hour")
49
-
49
+
50
50
  if @request_time_graph == [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
51
51
  output << "None found.\n"
52
52
  return
@@ -56,12 +56,12 @@ module RequestLogAnalyzer::Tracker
56
56
  last_date = DateTime.parse(@last.to_s, '%Y%m%d%H%M%S')
57
57
  days = (@last && @first) ? (last_date - first_date).ceil : 1
58
58
  total_requests = @request_time_graph.inject(0) { |sum, value| sum + value }
59
-
59
+
60
60
  output.table({}, {:align => :right}, {:type => :ratio, :width => :rest, :treshold => 0.15}) do |rows|
61
61
  @request_time_graph.each_with_index do |requests, index|
62
62
  ratio = requests.to_f / total_requests.to_f
63
63
  requests_per_day = requests / days
64
-
64
+
65
65
  rows << ["#{index.to_s.rjust(3)}:00", "#{requests_per_day} hits", ratio]
66
66
  end
67
67
  end
@@ -1,5 +1,5 @@
1
1
  module RequestLogAnalyzer::Tracker
2
-
2
+
3
3
  # Determines the datetime of the first request and the last request
4
4
  # Also determines the amount of days inbetween these.
5
5
  #
@@ -16,30 +16,30 @@ module RequestLogAnalyzer::Tracker
16
16
  # First request: 2008-07-13 06:25:06
17
17
  # Last request: 2008-07-20 06:18:06
18
18
  # Total time analyzed: 7 days
19
- class Timespan < RequestLogAnalyzer::Tracker::Base
19
+ class Timespan < Base
20
20
 
21
21
  attr_reader :first, :last, :request_time_graph
22
-
22
+
23
23
  def prepare
24
24
  options[:field] ||= :timestamp
25
25
  end
26
-
26
+
27
27
  def update(request)
28
28
  timestamp = request[options[:field]]
29
29
 
30
30
  @first = timestamp if @first.nil? || timestamp < @first
31
31
  @last = timestamp if @last.nil? || timestamp > @last
32
32
  end
33
-
33
+
34
34
  def report(output)
35
35
  output.title(options[:title]) if options[:title]
36
-
36
+
37
37
  first_date = DateTime.parse(@first.to_s, '%Y%m%d%H%M%S') rescue nil
38
38
  last_date = DateTime.parse(@last.to_s, '%Y%m%d%H%M%S') rescue nil
39
-
39
+
40
40
  if @last && @first
41
41
  days = (@last && @first) ? (last_date - first_date).ceil : 1
42
-
42
+
43
43
  output.with_style(:cell_separator => false) do
44
44
  output.table({:width => 20}, {}) do |rows|
45
45
  rows << ['First request:', first_date.strftime('%Y-%m-%d %H:%M:%I')]
@@ -48,7 +48,7 @@ module RequestLogAnalyzer::Tracker
48
48
  end
49
49
  end
50
50
  end
51
-
51
+
52
52
  end
53
53
  end
54
- end
54
+ end
@@ -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
@@ -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
@@ -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' }
@@ -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: 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 +01:00
13
+ date: 2009-01-21 00:00:00 +01: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