request-log-analyzer 1.3.7 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/LICENSE +3 -3
  2. data/README.rdoc +1 -1
  3. data/bin/request-log-analyzer +17 -14
  4. data/lib/cli/command_line_arguments.rb +51 -51
  5. data/lib/cli/database_console.rb +3 -3
  6. data/lib/cli/database_console_init.rb +2 -2
  7. data/lib/cli/progressbar.rb +10 -10
  8. data/lib/cli/tools.rb +3 -3
  9. data/lib/request_log_analyzer.rb +4 -4
  10. data/lib/request_log_analyzer/aggregator.rb +10 -10
  11. data/lib/request_log_analyzer/aggregator/database_inserter.rb +9 -9
  12. data/lib/request_log_analyzer/aggregator/echo.rb +14 -9
  13. data/lib/request_log_analyzer/aggregator/summarizer.rb +26 -26
  14. data/lib/request_log_analyzer/controller.rb +153 -69
  15. data/lib/request_log_analyzer/database.rb +13 -13
  16. data/lib/request_log_analyzer/database/base.rb +17 -17
  17. data/lib/request_log_analyzer/database/connection.rb +3 -3
  18. data/lib/request_log_analyzer/database/request.rb +2 -2
  19. data/lib/request_log_analyzer/database/source.rb +1 -1
  20. data/lib/request_log_analyzer/file_format.rb +15 -15
  21. data/lib/request_log_analyzer/file_format/amazon_s3.rb +16 -16
  22. data/lib/request_log_analyzer/file_format/apache.rb +20 -19
  23. data/lib/request_log_analyzer/file_format/merb.rb +12 -12
  24. data/lib/request_log_analyzer/file_format/rack.rb +4 -4
  25. data/lib/request_log_analyzer/file_format/rails.rb +146 -70
  26. data/lib/request_log_analyzer/file_format/rails_development.rb +4 -49
  27. data/lib/request_log_analyzer/filter.rb +6 -6
  28. data/lib/request_log_analyzer/filter/anonymize.rb +6 -6
  29. data/lib/request_log_analyzer/filter/field.rb +9 -9
  30. data/lib/request_log_analyzer/filter/timespan.rb +12 -10
  31. data/lib/request_log_analyzer/line_definition.rb +15 -14
  32. data/lib/request_log_analyzer/log_processor.rb +22 -22
  33. data/lib/request_log_analyzer/mailer.rb +15 -9
  34. data/lib/request_log_analyzer/output.rb +53 -12
  35. data/lib/request_log_analyzer/output/fixed_width.rb +40 -41
  36. data/lib/request_log_analyzer/output/html.rb +20 -20
  37. data/lib/request_log_analyzer/request.rb +35 -36
  38. data/lib/request_log_analyzer/source.rb +7 -7
  39. data/lib/request_log_analyzer/source/database_loader.rb +7 -7
  40. data/lib/request_log_analyzer/source/log_parser.rb +48 -43
  41. data/lib/request_log_analyzer/tracker.rb +128 -14
  42. data/lib/request_log_analyzer/tracker/duration.rb +39 -132
  43. data/lib/request_log_analyzer/tracker/frequency.rb +31 -32
  44. data/lib/request_log_analyzer/tracker/hourly_spread.rb +20 -19
  45. data/lib/request_log_analyzer/tracker/timespan.rb +17 -17
  46. data/lib/request_log_analyzer/tracker/traffic.rb +36 -116
  47. data/request-log-analyzer.gemspec +19 -15
  48. data/spec/fixtures/rails_22.log +1 -1
  49. data/spec/integration/command_line_usage_spec.rb +1 -1
  50. data/spec/lib/helpers.rb +7 -7
  51. data/spec/lib/macros.rb +3 -3
  52. data/spec/lib/matchers.rb +41 -27
  53. data/spec/lib/mocks.rb +15 -14
  54. data/spec/lib/testing_format.rb +9 -9
  55. data/spec/spec_helper.rb +6 -6
  56. data/spec/unit/aggregator/database_inserter_spec.rb +13 -13
  57. data/spec/unit/aggregator/summarizer_spec.rb +4 -4
  58. data/spec/unit/controller/controller_spec.rb +2 -2
  59. data/spec/unit/controller/log_processor_spec.rb +1 -1
  60. data/spec/unit/database/base_class_spec.rb +19 -19
  61. data/spec/unit/database/connection_spec.rb +3 -3
  62. data/spec/unit/database/database_spec.rb +25 -25
  63. data/spec/unit/file_format/amazon_s3_format_spec.rb +5 -5
  64. data/spec/unit/file_format/apache_format_spec.rb +13 -13
  65. data/spec/unit/file_format/file_format_api_spec.rb +13 -13
  66. data/spec/unit/file_format/line_definition_spec.rb +24 -17
  67. data/spec/unit/file_format/merb_format_spec.rb +41 -45
  68. data/spec/unit/file_format/rails_format_spec.rb +157 -117
  69. data/spec/unit/filter/anonymize_filter_spec.rb +2 -2
  70. data/spec/unit/filter/field_filter_spec.rb +13 -13
  71. data/spec/unit/filter/filter_spec.rb +1 -1
  72. data/spec/unit/filter/timespan_filter_spec.rb +15 -15
  73. data/spec/unit/mailer_spec.rb +30 -0
  74. data/spec/unit/{source/request_spec.rb → request_spec.rb} +30 -30
  75. data/spec/unit/source/log_parser_spec.rb +27 -27
  76. data/spec/unit/tracker/duration_tracker_spec.rb +115 -78
  77. data/spec/unit/tracker/frequency_tracker_spec.rb +74 -63
  78. data/spec/unit/tracker/hourly_spread_spec.rb +28 -20
  79. data/spec/unit/tracker/timespan_tracker_spec.rb +25 -13
  80. data/spec/unit/tracker/tracker_api_spec.rb +13 -13
  81. data/spec/unit/tracker/traffic_tracker_spec.rb +81 -79
  82. data/tasks/github-gem.rake +125 -75
  83. data/tasks/request_log_analyzer.rake +2 -2
  84. metadata +8 -6
@@ -3,139 +3,58 @@ module RequestLogAnalyzer::Tracker
3
3
  # Analyze the average and total traffic of requests
4
4
  #
5
5
  # === Options
6
- # * <tt>:amount</tt> The amount of lines in the report
7
6
  # * <tt>:category</tt> Proc that handles request categorization for given fileformat (REQUEST_CATEGORIZER)
8
7
  # * <tt>:traffic</tt> The field containing the duration in the request hash.
9
8
  # * <tt>:if</tt> Proc that has to return !nil for a request to be passed to the tracker.
10
9
  # * <tt>:line_type</tt> The line type that contains the duration field (determined by the category proc).
11
- # * <tt>:title</tt> Title do be displayed above the report
10
+ # * <tt>:title</tt> Title do be displayed above the report
12
11
  # * <tt>:unless</tt> Handle request if this proc is false for the handled request.
13
12
  class Traffic < Base
14
-
13
+
15
14
  attr_reader :categories
16
15
 
16
+ include RequestLogAnalyzer::Tracker::StatisticsTracking
17
+
17
18
  # Check if duration and catagory option have been received,
18
19
  def prepare
19
20
  raise "No traffic field set up for category tracker #{self.inspect}" unless options[:traffic]
20
- raise "No categorizer set up for duration tracker #{self.inspect}" unless options[:category]
21
+ raise "No categorizer set up for duration tracker #{self.inspect}" unless options[:category]
21
22
 
22
- @categorizer = options[:category].respond_to?(:call) ? options[:category] : lambda { |request| request[options[:category]] }
23
- @trafficizer = options[:traffic].respond_to?(:call) ? options[:traffic] : lambda { |request| request[options[:traffic]] }
24
- @categories = {}
23
+ @categorizer = create_lambda(options[:category])
24
+ @trafficizer = create_lambda(options[:traffic])
25
+ @categories = {}
25
26
  end
26
27
 
27
- # Get the duration information fron the request and store it in the different categories.
28
+
29
+ # Get the duration information from the request and store it in the different categories.
28
30
  # <tt>request</tt> The request.
29
31
  def update(request)
30
32
  category = @categorizer.call(request)
31
33
  traffic = @trafficizer.call(request)
32
-
33
- if traffic.kind_of?(Numeric) && !category.nil?
34
- @categories[category] ||= {:hits => 0, :cumulative => 0, :min => traffic, :max => traffic }
35
- @categories[category][:hits] += 1
36
- @categories[category][:cumulative] += traffic
37
- @categories[category][:min] = traffic if traffic < @categories[category][:min]
38
- @categories[category][:max] = traffic if traffic > @categories[category][:max]
39
- end
40
- end
41
-
42
- # Get the number of hits of a specific category.
43
- # <tt>cat</tt> The category
44
- def hits(cat)
45
- categories[cat][:hits]
46
- end
47
-
48
- # Get the total duration of a specific category.
49
- # <tt>cat</tt> The category
50
- def cumulative_traffic(cat)
51
- categories[cat][:cumulative]
52
- end
53
-
54
- # Get the minimal duration of a specific category.
55
- # <tt>cat</tt> The category
56
- def min_traffic(cat)
57
- categories[cat][:min]
58
- end
59
-
60
- # Get the maximum duration of a specific category.
61
- # <tt>cat</tt> The category
62
- def max_traffic(cat)
63
- categories[cat][:max]
64
- end
65
-
66
- # Get the average duration of a specific category.
67
- # <tt>cat</tt> The category
68
- def average_traffic(cat)
69
- categories[cat][:cumulative].to_f / categories[cat][:hits]
70
- end
71
-
72
- # Get the average duration of a all categories.
73
- def overall_average_traffic
74
- overall_cumulative_duration.to_f / overall_hits
75
- end
76
-
77
- # Get the cumlative duration of a all categories.
78
- def overall_cumulative_traffic
79
- categories.inject(0) { |sum, (name, cat)| sum + cat[:cumulative] }
80
- end
81
-
82
- # Get the total hits of a all categories.
83
- def overall_hits
84
- categories.inject(0) { |sum, (name, cat)| sum + cat[:hits] }
34
+ update_statistics(category, traffic) if traffic.kind_of?(Numeric) && !category.nil?
85
35
  end
86
36
 
87
- # Return categories sorted by hits.
88
- def sorted_by_hits
89
- sorted_by(:hits)
90
- end
91
-
92
- # Return categories sorted by cumulative duration.
93
- def sorted_by_cumulative
94
- sorted_by(:cumulative)
95
- end
96
-
97
- # Return categories sorted by cumulative duration.
98
- def sorted_by_average
99
- sorted_by { |cat| cat[:cumulative].to_f / cat[:hits] }
100
- end
101
-
102
- # Return categories sorted by a given key.
103
- # <tt>by</tt> The key.
104
- def sorted_by(by = nil)
105
- if block_given?
106
- categories.sort { |a, b| yield(b[1]) <=> yield(a[1]) }
107
- else
108
- categories.sort { |a, b| b[1][by] <=> a[1][by] }
109
- end
110
- end
111
-
112
37
  # Block function to build a result table using a provided sorting function.
113
38
  # <tt>output</tt> The output object.
114
39
  # <tt>amount</tt> The number of rows in the report table (default 10).
115
40
  # === Options
116
41
  # * </tt>:title</tt> The title of the table
117
42
  # * </tt>:sort</tt> The key to sort on (:hits, :cumulative, :average, :min or :max)
118
- def report_table(output, amount = 10, options = {}, &block)
119
-
120
- output.title(options[:title])
121
-
122
- top_categories = @categories.sort { |a, b| yield(b[1]) <=> yield(a[1]) }.slice(0...amount)
123
- output.table({:title => 'Category', :width => :rest},
124
- {:title => 'Hits', :align => :right, :highlight => (options[:sort] == :hits), :min_width => 4},
125
- {:title => 'Cumulative', :align => :right, :highlight => (options[:sort] == :cumulative), :min_width => 10},
126
- {:title => 'Average', :align => :right, :highlight => (options[:sort] == :average), :min_width => 8},
127
- {:title => 'Min', :align => :right, :highlight => (options[:sort] == :min)},
128
- {:title => 'Max', :align => :right, :highlight => (options[:sort] == :max)}) do |rows|
129
-
130
- top_categories.each do |(cat, info)|
131
- rows << [cat, info[:hits], format_traffic(info[:cumulative]), format_traffic((info[:cumulative] / info[:hits]).round),
132
- format_traffic(info[:min]), format_traffic(info[:max])]
43
+ def report_table(output, sort, options = {}, &block)
44
+ output.puts
45
+
46
+ top_categories = output.slice_results(sorted_by(sort))
47
+ output.with_style(:top_line => true) do
48
+ output.table(*statistics_header(:title => options[:title],:highlight => sort)) do |rows|
49
+ top_categories.each { |(cat, info)| rows.push(statistics_row(cat)) }
133
50
  end
134
51
  end
52
+ output.puts
135
53
  end
136
-
54
+
137
55
  # Formats the traffic number using x B/kB/MB/GB etc notation
138
- def format_traffic(bytes)
56
+ def display_value(bytes)
57
+ return "-" if bytes.nil?
139
58
  return "0 B" if bytes.zero?
140
59
  case Math.log10(bytes).floor
141
60
  when 1...4 then '%d B' % bytes
@@ -152,31 +71,32 @@ module RequestLogAnalyzer::Tracker
152
71
  # <tt>output</tt> The output object
153
72
  def report(output)
154
73
 
155
- options[:report] ||= [:cumulative, :average]
156
- options[:top] ||= 20
157
-
158
- options[:report].each do |report|
74
+ sortings = output.options[:sort] || [:sum, :mean]
75
+
76
+ sortings.each do |report|
159
77
  case report
160
- when :average
161
- report_table(output, options[:top], :title => "#{title} - top #{options[:top]} by average", :sort => :average) { |cat| cat[:cumulative] / cat[:hits] }
162
- when :cumulative
163
- report_table(output, options[:top], :title => "#{title} - top #{options[:top]} by sum", :sort => :cumulative) { |cat| cat[:cumulative] }
78
+ when :mean
79
+ report_table(output, :mean, :title => "#{title} - sorted by mean")
80
+ when :stddev
81
+ report_table(output, :stddev, :title => "#{title} - sorted by standard deviation")
82
+ when :sum
83
+ report_table(output, :sum, :title => "#{title} - sorted by sum")
164
84
  when :hits
165
- report_table(output, options[:top], :title => "#{title} - top #{options[:top]} by hits", :sort => :hits) { |cat| cat[:hits] }
85
+ report_table(output, :hits, :title => "#{title} - sorted by hits")
166
86
  else
167
87
  raise "Unknown duration report specified: #{report}!"
168
88
  end
169
89
  end
170
-
90
+
171
91
  output.puts
172
- output.puts "#{output.colorize(title, :white, :bold)} - observed total: " + output.colorize(format_traffic(overall_cumulative_traffic), :brown, :bold)
92
+ output.puts "#{output.colorize(title, :white, :bold)} - observed total: " + output.colorize(display_value(sum_overall), :brown, :bold)
173
93
  end
174
-
94
+
175
95
  # Returns the title of this tracker for reports
176
96
  def title
177
97
  options[:title] || 'Request traffic'
178
98
  end
179
-
99
+
180
100
  # Returns all the categories and the tracked duration as a hash than can be exported to YAML
181
101
  def to_yaml_object
182
102
  return nil if @categories.empty?
@@ -1,36 +1,40 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "request-log-analyzer"
3
- s.version = "1.3.7"
4
- s.date = "2009-09-22"
5
3
 
4
+ # Do not set the version and date field manually, this is done by the release script
5
+ s.version = "1.4.0"
6
+ s.date = "2009-09-30"
7
+
6
8
  s.rubyforge_project = 'r-l-a'
7
-
9
+
8
10
  s.bindir = 'bin'
9
11
  s.executables = ['request-log-analyzer']
10
12
  s.default_executable = 'request-log-analyzer'
11
-
12
- s.summary = "A command line tool to analyze request logs for Apache, Rails, Merb and other application servers"
13
+
14
+ s.summary = "A command line tool to analyze request logs for Apache, Rails, Merb and other web application servers"
13
15
  s.description = <<-eos
14
16
  Request log analyzer's purpose is to find ot how your web application is being used and to focus your optimization efforts.
15
- This tool will parse all requests in the application's log file and aggregate the information. Once it is finished parsing
16
- the log file(s), it will show the requests that take op most server time using various metrics. It can also insert all
17
- parsed request information into a database so you can roll your own analysis. It supports Rails- and Merb-based applications
18
- and Apache access log files out of the box, but file formats of other applications can easily be supported by supplying an
17
+ This tool will parse all requests in the application's log file and aggregate the information. Once it is finished parsing
18
+ the log file(s), it will show the requests that take op most server time using various metrics. It can also insert all
19
+ parsed request information into a database so you can roll your own analysis. It supports Rails- and Merb-based applications
20
+ and Apache access log files out of the box, but file formats of other applications can easily be supported by supplying an
19
21
  easy to write log file format definition.
20
22
  eos
21
-
23
+
22
24
  s.rdoc_options << '--title' << s.name << '--main' << 'README.rdoc' << '--line-numbers' << '--inline-source'
23
25
  s.extra_rdoc_files = ['README.rdoc']
24
-
26
+
25
27
  s.requirements << "To use the database inserter, ActiveRecord and an appropriate database adapter are required."
26
-
28
+
27
29
  s.add_development_dependency('rspec', '>= 1.2.4')
28
30
  s.add_development_dependency('git', '>= 1.1.0')
29
-
31
+
30
32
  s.authors = ['Willem van Bergen', 'Bart ten Brinke']
31
33
  s.email = ['willem@railsdoctors.com', 'bart@railsdoctors.com']
32
34
  s.homepage = 'http://railsdoctors.com'
33
35
 
34
- s.files = %w(spec/unit/filter/anonymize_filter_spec.rb spec/fixtures/rails_22_cached.log lib/request_log_analyzer/line_definition.rb lib/request_log_analyzer/output/html.rb lib/request_log_analyzer/controller.rb spec/lib/macros.rb lib/request_log_analyzer/file_format/rails_development.rb spec/fixtures/apache_combined.log spec/fixtures/apache_common.log spec/fixtures/merb_prefixed.log lib/request_log_analyzer/file_format/amazon_s3.rb tasks/request_log_analyzer.rake spec/unit/file_format/file_format_api_spec.rb spec/unit/file_format/apache_format_spec.rb spec/integration/command_line_usage_spec.rb lib/request_log_analyzer/database.rb spec/fixtures/decompression.log.bz2 spec/fixtures/rails_unordered.log lib/request_log_analyzer/log_processor.rb lib/request_log_analyzer/tracker.rb lib/request_log_analyzer/filter.rb bin/request-log-analyzer request-log-analyzer.gemspec DESIGN.rdoc spec/unit/filter/timespan_filter_spec.rb spec/unit/aggregator/database_inserter_spec.rb spec/lib/matchers.rb lib/request_log_analyzer/filter/field.rb lib/request_log_analyzer/tracker/frequency.rb spec/fixtures/decompression.log.gz spec/fixtures/decompression.log spec/lib/testing_format.rb spec/fixtures/test_order.log spec/fixtures/rails.db lib/request_log_analyzer/output/fixed_width.rb lib/request_log_analyzer/filter/anonymize.rb lib/request_log_analyzer/tracker/timespan.rb lib/request_log_analyzer/database/base.rb lib/request_log_analyzer/aggregator.rb lib/cli/progressbar.rb lib/request_log_analyzer/mailer.rb README.rdoc lib/request_log_analyzer/database/warning.rb spec/fixtures/merb.log lib/request_log_analyzer/tracker/hourly_spread.rb .gitignore spec/unit/tracker/tracker_api_spec.rb spec/unit/tracker/duration_tracker_spec.rb spec/unit/file_format/amazon_s3_format_spec.rb lib/request_log_analyzer/aggregator/echo.rb spec/unit/controller/log_processor_spec.rb spec/spec_helper.rb lib/request_log_analyzer.rb spec/database.yml Rakefile lib/request_log_analyzer/database/connection.rb spec/unit/filter/filter_spec.rb spec/fixtures/test_language_combined.log lib/request_log_analyzer/aggregator/database_inserter.rb lib/request_log_analyzer/aggregator/summarizer.rb lib/request_log_analyzer/file_format/rack.rb lib/request_log_analyzer/database/source.rb lib/request_log_analyzer/file_format/rails.rb spec/fixtures/decompression.tar.gz spec/unit/tracker/traffic_tracker_spec.rb spec/unit/filter/field_filter_spec.rb spec/unit/database/base_class_spec.rb lib/request_log_analyzer/filter/timespan.rb lib/request_log_analyzer/source/log_parser.rb spec/fixtures/decompression.tgz spec/unit/tracker/timespan_tracker_spec.rb spec/unit/tracker/hourly_spread_spec.rb spec/fixtures/header_and_footer.log lib/cli/tools.rb lib/request_log_analyzer/file_format/merb.rb spec/fixtures/multiple_files_1.log spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/line_definition_spec.rb lib/request_log_analyzer/source.rb lib/request_log_analyzer/request.rb lib/cli/database_console.rb spec/unit/database/connection_spec.rb spec/unit/controller/controller_spec.rb spec/lib/mocks.rb spec/lib/helpers.rb spec/fixtures/rails_1x.log lib/cli/database_console_init.rb lib/request_log_analyzer/output.rb lib/request_log_analyzer/file_format/apache.rb spec/fixtures/decompression.log.zip spec/unit/source/request_spec.rb spec/unit/source/log_parser_spec.rb spec/fixtures/test_file_format.log tasks/github-gem.rake spec/unit/database/database_spec.rb lib/request_log_analyzer/tracker/duration.rb lib/request_log_analyzer/tracker/traffic.rb lib/request_log_analyzer/file_format.rb spec/unit/aggregator/summarizer_spec.rb spec/fixtures/syslog_1x.log spec/fixtures/rails_22.log lib/request_log_analyzer/database/request.rb spec/fixtures/multiple_files_2.log LICENSE lib/request_log_analyzer/source/database_loader.rb spec/unit/tracker/frequency_tracker_spec.rb spec/unit/file_format/rails_format_spec.rb lib/cli/command_line_arguments.rb)
35
- s.test_files = %w(spec/unit/filter/anonymize_filter_spec.rb spec/unit/file_format/file_format_api_spec.rb spec/unit/file_format/apache_format_spec.rb spec/integration/command_line_usage_spec.rb spec/unit/filter/timespan_filter_spec.rb spec/unit/aggregator/database_inserter_spec.rb spec/unit/tracker/tracker_api_spec.rb spec/unit/tracker/duration_tracker_spec.rb spec/unit/file_format/amazon_s3_format_spec.rb spec/unit/controller/log_processor_spec.rb spec/unit/filter/filter_spec.rb spec/unit/tracker/traffic_tracker_spec.rb spec/unit/filter/field_filter_spec.rb spec/unit/database/base_class_spec.rb spec/unit/tracker/timespan_tracker_spec.rb spec/unit/tracker/hourly_spread_spec.rb spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/line_definition_spec.rb spec/unit/database/connection_spec.rb spec/unit/controller/controller_spec.rb spec/unit/source/request_spec.rb spec/unit/source/log_parser_spec.rb spec/unit/database/database_spec.rb spec/unit/aggregator/summarizer_spec.rb spec/unit/tracker/frequency_tracker_spec.rb spec/unit/file_format/rails_format_spec.rb)
36
+ # The files and test_files directives are set automatically by the release script.
37
+ # Do not change them by hand, but make sure to add the files to the git repository.
38
+ s.files = %w(spec/unit/filter/anonymize_filter_spec.rb spec/fixtures/rails_22_cached.log lib/request_log_analyzer/line_definition.rb lib/request_log_analyzer/output/html.rb lib/request_log_analyzer/controller.rb spec/lib/macros.rb lib/request_log_analyzer/file_format/rails_development.rb spec/fixtures/apache_combined.log spec/fixtures/apache_common.log spec/fixtures/merb_prefixed.log lib/request_log_analyzer/file_format/amazon_s3.rb tasks/request_log_analyzer.rake spec/unit/file_format/file_format_api_spec.rb spec/unit/file_format/apache_format_spec.rb spec/integration/command_line_usage_spec.rb lib/request_log_analyzer/database.rb spec/fixtures/decompression.log.bz2 spec/fixtures/rails_unordered.log lib/request_log_analyzer/log_processor.rb lib/request_log_analyzer/tracker.rb lib/request_log_analyzer/filter.rb bin/request-log-analyzer request-log-analyzer.gemspec DESIGN.rdoc spec/unit/filter/timespan_filter_spec.rb spec/unit/aggregator/database_inserter_spec.rb spec/lib/matchers.rb lib/request_log_analyzer/filter/field.rb lib/request_log_analyzer/tracker/frequency.rb spec/fixtures/decompression.log.gz spec/fixtures/decompression.log spec/lib/testing_format.rb spec/fixtures/test_order.log spec/fixtures/rails.db lib/request_log_analyzer/output/fixed_width.rb lib/request_log_analyzer/filter/anonymize.rb lib/request_log_analyzer/tracker/timespan.rb lib/request_log_analyzer/database/base.rb lib/request_log_analyzer/aggregator.rb spec/unit/request_spec.rb lib/cli/progressbar.rb lib/request_log_analyzer/mailer.rb README.rdoc lib/request_log_analyzer/database/warning.rb spec/fixtures/merb.log lib/request_log_analyzer/tracker/hourly_spread.rb .gitignore spec/unit/tracker/tracker_api_spec.rb spec/unit/tracker/duration_tracker_spec.rb spec/unit/file_format/amazon_s3_format_spec.rb lib/request_log_analyzer/aggregator/echo.rb spec/unit/mailer_spec.rb spec/unit/controller/log_processor_spec.rb spec/spec_helper.rb lib/request_log_analyzer.rb spec/database.yml Rakefile lib/request_log_analyzer/database/connection.rb spec/unit/filter/filter_spec.rb spec/fixtures/test_language_combined.log lib/request_log_analyzer/aggregator/database_inserter.rb lib/request_log_analyzer/aggregator/summarizer.rb lib/request_log_analyzer/file_format/rack.rb lib/request_log_analyzer/database/source.rb lib/request_log_analyzer/file_format/rails.rb spec/fixtures/decompression.tar.gz spec/unit/tracker/traffic_tracker_spec.rb spec/unit/filter/field_filter_spec.rb spec/unit/database/base_class_spec.rb lib/request_log_analyzer/filter/timespan.rb lib/request_log_analyzer/source/log_parser.rb spec/fixtures/decompression.tgz spec/unit/tracker/timespan_tracker_spec.rb spec/unit/tracker/hourly_spread_spec.rb spec/fixtures/header_and_footer.log lib/cli/tools.rb lib/request_log_analyzer/file_format/merb.rb spec/fixtures/multiple_files_1.log spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/line_definition_spec.rb lib/request_log_analyzer/source.rb lib/request_log_analyzer/request.rb lib/cli/database_console.rb spec/unit/database/connection_spec.rb spec/unit/controller/controller_spec.rb spec/lib/mocks.rb spec/lib/helpers.rb spec/fixtures/rails_1x.log lib/cli/database_console_init.rb lib/request_log_analyzer/output.rb lib/request_log_analyzer/file_format/apache.rb spec/fixtures/decompression.log.zip spec/unit/source/log_parser_spec.rb spec/fixtures/test_file_format.log tasks/github-gem.rake spec/unit/database/database_spec.rb lib/request_log_analyzer/tracker/duration.rb lib/request_log_analyzer/tracker/traffic.rb lib/request_log_analyzer/file_format.rb spec/unit/aggregator/summarizer_spec.rb spec/fixtures/syslog_1x.log spec/fixtures/rails_22.log lib/request_log_analyzer/database/request.rb spec/fixtures/multiple_files_2.log LICENSE lib/request_log_analyzer/source/database_loader.rb spec/unit/tracker/frequency_tracker_spec.rb spec/unit/file_format/rails_format_spec.rb lib/cli/command_line_arguments.rb)
39
+ s.test_files = %w(spec/unit/filter/anonymize_filter_spec.rb spec/unit/file_format/file_format_api_spec.rb spec/unit/file_format/apache_format_spec.rb spec/integration/command_line_usage_spec.rb spec/unit/filter/timespan_filter_spec.rb spec/unit/aggregator/database_inserter_spec.rb spec/unit/request_spec.rb spec/unit/tracker/tracker_api_spec.rb spec/unit/tracker/duration_tracker_spec.rb spec/unit/file_format/amazon_s3_format_spec.rb spec/unit/mailer_spec.rb spec/unit/controller/log_processor_spec.rb spec/unit/filter/filter_spec.rb spec/unit/tracker/traffic_tracker_spec.rb spec/unit/filter/field_filter_spec.rb spec/unit/database/base_class_spec.rb spec/unit/tracker/timespan_tracker_spec.rb spec/unit/tracker/hourly_spread_spec.rb spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/line_definition_spec.rb spec/unit/database/connection_spec.rb spec/unit/controller/controller_spec.rb spec/unit/source/log_parser_spec.rb spec/unit/database/database_spec.rb spec/unit/aggregator/summarizer_spec.rb spec/unit/tracker/frequency_tracker_spec.rb spec/unit/file_format/rails_format_spec.rb)
36
40
  end
@@ -9,4 +9,4 @@ Rendered shared/_analytics (0.2ms)
9
9
  Rendered layouts/_actions (0.6ms)
10
10
  Rendered layouts/_menu (2.2ms)
11
11
  Rendered layouts/_tabbar (0.5ms)
12
- Completed in 614ms (View: 120, DB: 31) | 200 OK [http://www.example.coml/demo]
12
+ Completed in 614ms (View: 120, DB: 31) | 200 OK [http://www.example.com/demo]
@@ -76,7 +76,7 @@ describe RequestLogAnalyzer, 'running from command line' do
76
76
  File.exist?(temp_output_file(:dump)).should be_true
77
77
  YAML::load(File.read(temp_output_file(:dump))).should have_at_least(1).item
78
78
  end
79
-
79
+
80
80
  it "should parse 4 requests from the standard input" do
81
81
  output = run("- < #{log_fixture(:rails_1x)}")
82
82
  output.any? { |line| /^Parsed requests\:\s*4\s/ =~ line }.should be_true
data/spec/lib/helpers.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  module RequestLogAnalyzer::Spec::Helpers
2
-
2
+
3
3
  # Create or return a new TestingFormat
4
4
  def testing_format
5
5
  @testing_format ||= TestingFormat.create
6
6
  end
7
-
7
+
8
8
  # Load a log file from the fixture folder
9
9
  def log_fixture(name, extention = "log")
10
10
  File.dirname(__FILE__) + "/../fixtures/#{name}.#{extention}"
@@ -15,7 +15,7 @@ module RequestLogAnalyzer::Spec::Helpers
15
15
  if fields.kind_of?(Array)
16
16
  format.request(*fields)
17
17
  else
18
- format.request(fields)
18
+ format.request(fields)
19
19
  end
20
20
  end
21
21
 
@@ -24,7 +24,7 @@ module RequestLogAnalyzer::Spec::Helpers
24
24
  def run(arguments)
25
25
  binary = "#{File.dirname(__FILE__)}/../../bin/request-log-analyzer"
26
26
  arguments = arguments.join(' ') if arguments.kind_of?(Array)
27
-
27
+
28
28
  output = []
29
29
  IO.popen("#{binary} #{arguments}") do |pipe|
30
30
  output = pipe.readlines
@@ -32,16 +32,16 @@ module RequestLogAnalyzer::Spec::Helpers
32
32
  $?.exitstatus.should == 0
33
33
  output
34
34
  end
35
-
35
+
36
36
  # Cleanup all temporary files generated by specs
37
37
  def cleanup_temp_files!
38
38
  Dir["#{File.dirname(__FILE__)}/../../tmp/spec.*tmp"].each do |file|
39
39
  File.unlink(file)
40
40
  end
41
41
  end
42
-
42
+
43
43
  # Return a filename that can be used as temporary file in specs
44
44
  def temp_output_file(file_type)
45
- "#{File.dirname(__FILE__)}/../../tmp/spec.#{file_type}.tmp"
45
+ "#{File.dirname(__FILE__)}/../../tmp/spec.#{file_type}.tmp"
46
46
  end
47
47
  end
data/spec/lib/macros.rb CHANGED
@@ -1,16 +1,16 @@
1
1
  module RequestLogAnalyzer::Spec::Macros
2
-
2
+
3
3
  def test_databases
4
4
  require 'yaml'
5
5
  hash = YAML.load(File.read("#{File.dirname(__FILE__)}/../database.yml"))
6
6
  hash.inject({}) { |res, (name, h)| res[name] = h.map { |(k,v)| "#{k}=#{v}" }.join(';'); res }
7
7
  end
8
-
8
+
9
9
  # Create or return a new TestingFormat
10
10
  def testing_format
11
11
  @testing_format ||= TestingFormat.create
12
12
  end
13
-
13
+
14
14
  def default_orm_class_names
15
15
  ['Warning', 'Request', 'Source']
16
16
  end
data/spec/lib/matchers.rb CHANGED
@@ -1,17 +1,17 @@
1
1
  module RequestLogAnalyzer::Spec::Matchers
2
-
2
+
3
3
  class HasLineDefinition
4
-
4
+
5
5
  def initialize(line_type)
6
6
  @line_type = line_type.to_sym
7
7
  @captures = []
8
8
  end
9
-
9
+
10
10
  def capturing(*captures)
11
11
  @captures += captures
12
12
  return self
13
13
  end
14
-
14
+
15
15
  def matches?(file_format)
16
16
  file_format = file_format.create if file_format.kind_of?(Class)
17
17
  if ld = file_format.line_definitions[@line_type]
@@ -21,43 +21,57 @@ module RequestLogAnalyzer::Spec::Matchers
21
21
  end
22
22
  end
23
23
  end
24
-
25
- class Parse
24
+
25
+ class ParseLine
26
+
26
27
  def initialize(line)
27
- @line = line
28
- @captures = nil
28
+ @line = line
29
+ @captures = {}
30
+ @line_type = nil
29
31
  end
30
-
32
+
31
33
  def failure_message
32
- message = "expected to parse the provided line"
33
- if @found_captures
34
- message << "with captures #{@captures.inspect}, but captured #{@found_captures.inspect}"
35
- end
36
- return message
34
+ @failure_message
35
+ end
36
+
37
+ def as(line_type)
38
+ @line_type = line_type
39
+ return self
37
40
  end
38
41
 
39
- def capturing(*captures)
42
+ def and_capture(captures)
40
43
  @captures = captures
41
44
  return self
42
45
  end
43
-
44
- def matches?(line_definition)
45
- hash = line_definition.matches(@line)
46
- if hash
47
- @found_captures = hash[:captures].to_a
48
- @captures.nil? ? true : @found_captures.eql?(@captures)
46
+
47
+ def fail(message)
48
+ @failure_message = message
49
+ return false
50
+ end
51
+
52
+ def matches?(file_format)
53
+ if @line_hash = file_format.parse_line(@line)
54
+ if @line_type.nil? || @line_hash[:line_definition].name == @line_type
55
+ @request = file_format.request(@line_hash)
56
+ @captures.each do |key, value|
57
+ return fail("Expected line #{@line.inspect}\n to capture #{key.inspect} as #{value.inspect} but was #{@request[key].inspect}.") if @request[key] != value
58
+ end
59
+ return true
60
+ else
61
+ return fail("The line should match the #{@line_type.inspect} line definition, but matched #{@line_hash[:line_definition].name.inspect} instead.")
62
+ end
49
63
  else
50
- return false
64
+ return fail("The line did not match any line definition.")
51
65
  end
52
66
  end
53
67
  end
54
-
68
+
55
69
  def have_line_definition(line_type)
56
70
  return HasLineDefinition.new(line_type)
57
71
  end
58
-
59
- def parse(line)
60
- Parse.new(line)
72
+
73
+ def parse_line(line)
74
+ ParseLine.new(line)
61
75
  end
62
-
76
+
63
77
  end