request-log-analyzer 1.6.2 → 1.6.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,7 +11,7 @@ module RequestLogAnalyzer
11
11
 
12
12
  # The current version of request-log-analyzer.
13
13
  # Do not change the value by hand; it will be updated automatically by the gem release script.
14
- VERSION = "1.6.2"
14
+ VERSION = "1.6.3"
15
15
 
16
16
  # Loads constants in the RequestLogAnalyzer namespace using self.load_default_class_file(base, const)
17
17
  # <tt>const</tt>:: The constant that is not yet loaded in the RequestLogAnalyzer namespace. This should be passed as a string or symbol.
@@ -11,24 +11,25 @@ module RequestLogAnalyzer::FileFormat
11
11
  line_definition :access do |line|
12
12
  line.header = true
13
13
  line.footer = true
14
- line.regexp = /^([^\ ]+) ([^\ ]+) \[(#{timestamp('%d/%b/%Y:%H:%M:%S %z')})?\] (#{ip_address}) ([^\ ]+) ([^\ ]+) (\w+(?:\.\w+)*) ([^\ ]+) "([^"]+)" (\d+) ([^\ ]+) (\d+) (\d+) (\d+) (\d+) "([^"]+)" "([^"]+)"/
15
- line.captures << { :name => :bucket_owner, :type => :string } <<
16
- { :name => :bucket, :type => :string } <<
17
- { :name => :timestamp, :type => :timestamp } <<
18
- { :name => :remote_ip, :type => :string } <<
19
- { :name => :requester, :type => :string } <<
20
- { :name => :request_id, :type => :string } <<
21
- { :name => :operation, :type => :string } <<
22
- { :name => :key, :type => :nillable_string } <<
23
- { :name => :request_uri, :type => :string } <<
24
- { :name => :http_status, :type => :integer } <<
25
- { :name => :error_code, :type => :nillable_string } <<
26
- { :name => :bytes_sent, :type => :traffic, :unit => :byte } <<
27
- { :name => :object_size, :type => :traffic, :unit => :byte } <<
28
- { :name => :total_time, :type => :duration, :unit => :msec } <<
29
- { :name => :turnaround_time, :type => :duration, :unit => :msec } <<
30
- { :name => :referer, :type => :referer } <<
31
- { :name => :user_agent, :type => :user_agent }
14
+ line.regexp = /^([^\ ]+) ([^\ ]+) \[(#{timestamp('%d/%b/%Y:%H:%M:%S %z')})?\] (#{ip_address}) ([^\ ]+) ([^\ ]+) (\w+(?:\.\w+)*) ([^\ ]+) "([^"]+)" (\d+) ([^\ ]+) (\d+) (\d+) (\d+) (\d+) "([^"]*)" "([^"]*)"/
15
+
16
+ line.capture(:bucket_owner)
17
+ line.capture(:bucket)
18
+ line.capture(:timestamp).as(:timestamp)
19
+ line.capture(:remote_ip)
20
+ line.capture(:requester)
21
+ line.capture(:request_id)
22
+ line.capture(:operation)
23
+ line.capture(:key).as(:nillable_string)
24
+ line.capture(:request_uri)
25
+ line.capture(:http_status).as(:integer)
26
+ line.capture(:error_code).as(:nillable_string)
27
+ line.capture(:bytes_sent).as(:traffic, :unit => :byte)
28
+ line.capture(:object_size).as(:traffic, :unit => :byte)
29
+ line.capture(:total_time).as(:duration, :unit => :msec)
30
+ line.capture(:turnaround_time).as(:duration, :unit => :msec)
31
+ line.capture(:referer).as(:referer)
32
+ line.capture(:user_agent).as(:user_agent)
32
33
  end
33
34
 
34
35
  report do |analyze|
@@ -7,38 +7,42 @@ module RequestLogAnalyzer::FileFormat
7
7
  line_definition :job_lock do |line|
8
8
  line.header = true
9
9
  line.regexp = /\* \[JOB\] acquiring lock on (\S+)/
10
- line.captures << { :name => :job, :type => :string }
10
+
11
+ line.capture(:job)
11
12
  end
12
13
 
13
14
  line_definition :job_completed do |line|
14
15
  line.footer = true
15
16
  line.regexp = /\* \[JOB\] (\S+) completed after (\d+\.\d+)/
16
- line.captures << { :name => :completed_job, :type => :string } <<
17
- { :name => :duration, :type => :duration, :unit => :sec }
17
+
18
+ line.capture(:completed_job)
19
+ line.capture(:duration).as(:duration, :unit => :sec)
18
20
  end
19
21
 
20
22
  line_definition :job_failed do |line|
21
23
  line.footer = true
22
24
  line.regexp = /\* \[JOB\] (\S+) failed with (\S+)\: .* - (\d+) failed attempts/
23
- line.captures << { :name => :failed_job, :type => :string } <<
24
- { :name => :exception, :type => :string } <<
25
- { :name => :attempts, :type => :integer }
26
25
 
26
+ line.capture(:failed_job)
27
+ line.capture(:exception)
28
+ line.capture(:attempts).as(:integer)
27
29
  end
28
30
 
29
31
  line_definition :job_lock_failed do |line|
30
32
  line.footer = true
31
33
  line.regexp = /\* \[JOB\] failed to acquire exclusive lock for (\S+)/
32
- line.captures << { :name => :locked_job, :type => :string }
34
+
35
+ line.capture(:locked_job)
33
36
  end
34
37
 
35
38
  # line_definition :batch_completed do |line|
36
39
  # line.header = true
37
40
  # line.footer = true
38
41
  # line.regexp = /(\d+) jobs processed at (\d+\.\d+) j\/s, (\d+) failed .../
39
- # line.captures << { :name => :total_amount, :type => :integer } <<
40
- # { :name => :mean_duration, :type => :duration, :unit => :sec } <<
41
- # { :name => :failed_amount, :type => :integer }
42
+ #
43
+ # line.capture(:total_amount).as(:integer)
44
+ # line.capture(:mean_duration).as(:duration, :unit => :sec)
45
+ # line.capture(:failed_amount).as(:integer)
42
46
  # end
43
47
 
44
48
  report do |analyze|
@@ -8,42 +8,45 @@ module RequestLogAnalyzer::FileFormat
8
8
  line.header = :alternative
9
9
  line.teaser = /\# Time: /
10
10
  line.regexp = /\# Time: (#{timestamp('%y%m%d %k:%M:%S')})/
11
- line.captures << { :name => :timestamp, :type => :timestamp }
11
+
12
+ line.capture(:timestamp).as(:timestamp)
12
13
  end
13
14
 
14
15
  line_definition :user_host do |line|
15
16
  line.header = :alternative
16
17
  line.teaser = /\# User\@Host\: /
17
18
  line.regexp = /\# User\@Host\: ([\w-]+)\[[\w-]+\] \@ ([\w\.-]*) \[(#{ip_address(true)})\]/
18
- line.captures << { :name => :user, :type => :string } <<
19
- { :name => :host, :type => :string } <<
20
- { :name => :ip, :type => :string }
19
+
20
+ line.capture(:user)
21
+ line.capture(:host)
22
+ line.capture(:ip)
21
23
  end
22
24
 
23
25
  line_definition :query_statistics do |line|
24
26
  line.header = :alternative
25
27
  line.teaser = /\# Query_time: /
26
28
  line.regexp = /\# Query_time: (\d+(?:\.\d+)?)\s+Lock_time: (\d+(?:\.\d+)?)\s+Rows_sent: (\d+)\s+Rows_examined: (\d+)/
27
- line.captures << { :name => :query_time, :type => :duration, :unit => :sec } <<
28
- { :name => :lock_time, :type => :duration, :unit => :sec } <<
29
- { :name => :rows_sent, :type => :integer } <<
30
- { :name => :rows_examined, :type => :integer }
29
+
30
+ line.capture(:query_time).as(:duration, :unit => :sec)
31
+ line.capture(:lock_time).as(:duration, :unit => :sec)
32
+ line.capture(:rows_sent).as(:integer)
33
+ line.capture(:rows_examined).as(:integer)
31
34
  end
32
35
 
33
36
  line_definition :use_database do |line|
34
37
  line.regexp = /^use (\w+);\s*$/
35
- line.captures << { :name => :database, :type => :string }
38
+ line.capture(:database)
36
39
  end
37
40
 
38
41
  line_definition :query_part do |line|
39
42
  line.regexp = /^(?!(?:use |\# |SET ))(.*[^;\s])\s*$/
40
- line.captures << { :name => :query_fragment, :type => :string }
43
+ line.capture(:query_fragment)
41
44
  end
42
45
 
43
46
  line_definition :query do |line|
44
- line.regexp = /^(?!(?:use |\# |SET ))(.*);\s*$/
45
- line.captures << { :name => :query, :type => :sql }
46
47
  line.footer = true
48
+ line.regexp = /^(?!(?:use |\# |SET ))(.*);\s*$/
49
+ line.capture(:query).as(:sql)
47
50
  end
48
51
 
49
52
  PER_USER = :user
@@ -8,21 +8,23 @@ module RequestLogAnalyzer::FileFormat
8
8
  line.header = true
9
9
  line.teaser = /LOG\: query\:/
10
10
  line.regexp = /(#{timestamp('%y-%m-%d %k:%M:%S')})\ LOG: query:\s+(.*)/
11
- line.captures << { :name => :timestamp, :type => :timestamp } <<
12
- { :name => :query_fragment, :type => :string }
11
+
12
+ line.capture(:timestamp).as(:timestamp)
13
+ line.capture(:query_fragment)
13
14
  end
14
15
 
15
16
  line_definition :duration do |line|
16
17
  line.footer = true
17
18
  line.teaser = /duration:/
18
19
  line.regexp = /#{timestamp('%y-%m-%d %k:%M:%S')}\ LOG\: duration\: (.*)(\ )sec/
19
- line.captures << { :name => :query_time, :type => :duration, :unit => :sec } <<
20
- { :name => :query, :type => :sql } # Hack to gather up fragments
20
+
21
+ line.capture(:query_time).as(:duration, :unit => :sec)
22
+ line.capture(:query).as(:sql) # Hack to gather up fragments
21
23
  end
22
24
 
23
25
  line_definition :query_fragment do |line|
24
26
  line.regexp = /^(?!.*LOG)\s*(.*)\s*/
25
- line.captures << { :name => :query_fragment, :type => :string }
27
+ line.capture(:query_fragment)
26
28
  end
27
29
 
28
30
  report do |analyze|
@@ -0,0 +1,86 @@
1
+ module RequestLogAnalyzer::FileFormat
2
+
3
+ # Default FileFormat class for Rails 3 logs.
4
+ #
5
+ # For now, this is just a basic implementation. It will probaby change after
6
+ # Rails 3 final has been released.
7
+ class Rails3 < Base
8
+
9
+ extend CommonRegularExpressions
10
+
11
+ # Started GET "/queries" for 127.0.0.1 at 2010-02-25 16:15:18
12
+ line_definition :started do |line|
13
+ line.header = true
14
+ line.teaser = /Started /
15
+ line.regexp = /Started ([A-Z]+) "([^"]+)" for (#{ip_address}) at (#{timestamp('%Y-%m-%d %H:%M:%S')})/
16
+
17
+ line.capture(:method)
18
+ line.capture(:path)
19
+ line.capture(:ip)
20
+ line.capture(:timestamp).as(:timestamp)
21
+ end
22
+
23
+ # Processing by QueriesController#index as HTML
24
+ line_definition :processing do |line|
25
+ line.teaser = /Processing by /
26
+ line.regexp = /Processing by (\w+)\#(\w+) as (\w+)/
27
+
28
+ line.capture(:controller)
29
+ line.capture(:action)
30
+ line.capture(:format)
31
+ end
32
+
33
+ # Completed in 9ms (Views: 4.9ms | ActiveRecord: 0.5ms) with 200
34
+ line_definition :completed do |line|
35
+ line.footer = true
36
+ line.teaser = /Completed /
37
+ line.regexp = /Completed (\d+) .* in (\d+)ms \([^\)]*\)/
38
+
39
+ line.capture(:status).as(:integer)
40
+ line.capture(:duration).as(:duration, :unit => :msec)
41
+ end
42
+
43
+ # ActionView::Template::Error (undefined local variable or method `field' for #<Class>) on line #3 of /Users/willem/Code/warehouse/app/views/queries/execute.csv.erb:
44
+ line_definition :failure do |line|
45
+ line.footer = true
46
+ line.regexp = /((?:[A-Z]\w*[a-z]\w+\:\:)*[A-Z]\w*[a-z]\w+) \((.*)\)(?: on line #(\d+) of (.+))?\:\s*$/
47
+
48
+ line.capture(:error)
49
+ line.capture(:message)
50
+ line.capture(:line).as(:integer)
51
+ line.capture(:file)
52
+ end
53
+
54
+ # # Not parsed at the moment:
55
+ # SQL (0.2ms) SET SQL_AUTO_IS_NULL=0
56
+ # Query Load (0.4ms) SELECT `queries`.* FROM `queries`
57
+ # Rendered collection (0.0ms)
58
+ # Rendered queries/index.html.erb (0.6ms)
59
+
60
+ REQUEST_CATEGORIZER = lambda { |request| "#{request[:controller]}##{request[:action]}.#{request[:format]}" }
61
+
62
+ report do |analyze|
63
+
64
+ analyze.timespan
65
+ analyze.hourly_spread
66
+
67
+ analyze.frequency :category => REQUEST_CATEGORIZER, :title => 'Most requested'
68
+ analyze.frequency :method, :title => 'HTTP methods'
69
+ analyze.frequency :status, :title => 'HTTP statuses returned'
70
+
71
+ analyze.duration :duration, :category => REQUEST_CATEGORIZER, :title => "Request duration", :line_type => :completed
72
+ # analyze.duration :view, :category => REQUEST_CATEGORIZER, :title => "View rendering time", :line_type => :completed
73
+ # analyze.duration :db, :category => REQUEST_CATEGORIZER, :title => "Database time", :line_type => :completed
74
+
75
+ analyze.frequency :category => REQUEST_CATEGORIZER, :title => 'Process blockers (> 1 sec duration)',
76
+ :if => lambda { |request| request[:duration] && request[:duration] > 1.0 }
77
+ end
78
+
79
+ class Request < RequestLogAnalyzer::Request
80
+ def convert_timestamp(value, defintion)
81
+ value.gsub(/[^0-9]/, '')[0...14].to_i
82
+ end
83
+ end
84
+
85
+ end
86
+ end
@@ -26,6 +26,19 @@ module RequestLogAnalyzer
26
26
  end
27
27
  end
28
28
 
29
+ class CaptureDefiner
30
+ attr_accessor :capture_hash
31
+
32
+ def initialize(hash)
33
+ @capture_hash = hash
34
+ end
35
+
36
+ def as(type, type_options = {})
37
+ @capture_hash.merge!(type_options.merge(:type => type))
38
+ return self
39
+ end
40
+ end
41
+
29
42
  attr_reader :name
30
43
  attr_accessor :teaser, :regexp, :captures
31
44
  attr_accessor :header, :footer
@@ -47,6 +60,12 @@ module RequestLogAnalyzer
47
60
  yield(definition) if block_given?
48
61
  return definition
49
62
  end
63
+
64
+ def capture(name)
65
+ new_capture_hash = { :name => name, :type => :string}
66
+ captures << new_capture_hash
67
+ CaptureDefiner.new(new_capture_hash)
68
+ end
50
69
 
51
70
  # Checks whether a given line matches this definition.
52
71
  # It will return false if a line does not match. If the line matches, a hash is returned
@@ -25,7 +25,25 @@ module RequestLogAnalyzer::Output
25
25
  def report_hourly_spread(tracker)
26
26
  title tracker.title
27
27
  puts tag(:img, nil, :width => '700', :height => '120', :src =>
28
- Gchart.sparkline(:data => tracker.hour_frequencies, :size => '700x120', :line_colors => '0077CC'))
28
+ Gchart.sparkline(:data => tracker.hour_frequencies, :size => '700x120', :line_colors => '0077CC',
29
+ :axis_with_labels => 'x,y', :axis_labels => [x_axis_labels(tracker),y_axis_labels(tracker)]))
30
+ end
31
+
32
+ def x_axis_labels(tracker)
33
+ frmt = '%H:%M'
34
+ x_axis_labels = []
35
+ num_labels = 5
36
+ start = tracker.first_timestamp
37
+ step = tracker.timespan / (num_labels - 1)
38
+ for i in 0...num_labels do
39
+ x_axis_labels << (start + step * i).strftime(frmt)
40
+ end
41
+ x_axis_labels
42
+ end
43
+
44
+ def y_axis_labels(tracker)
45
+ sorted_frequencies = tracker.hour_frequencies.sort
46
+ [sorted_frequencies.first, sorted_frequencies.last]
29
47
  end
30
48
  end
31
49
  end
@@ -2,8 +2,8 @@ Gem::Specification.new do |s|
2
2
  s.name = "request-log-analyzer"
3
3
 
4
4
  # Do not set the version and date field manually, this is done by the release script
5
- s.version = "1.6.2"
6
- s.date = "2010-01-29"
5
+ s.version = "1.6.3"
6
+ s.date = "2010-03-19"
7
7
 
8
8
  s.rubyforge_project = 'r-l-a'
9
9
 
@@ -36,6 +36,6 @@ Gem::Specification.new do |s|
36
36
 
37
37
  # The files and test_files directives are set automatically by the release script.
38
38
  # Do not change them by hand, but make sure to add the files to the git repository.
39
- s.files = %w(spec/unit/tracker/hourly_spread_spec.rb lib/request_log_analyzer/output/html.rb DESIGN.rdoc spec/fixtures/rails_unordered.log spec/fixtures/multiple_files_1.log lib/request_log_analyzer/database/source.rb README.rdoc spec/unit/file_format/amazon_s3_format_spec.rb lib/request_log_analyzer/file_format/rails_development.rb spec/fixtures/rails_22.log spec/fixtures/test_order.log spec/unit/database/base_class_spec.rb lib/request_log_analyzer/database/connection.rb lib/request_log_analyzer/aggregator.rb spec/fixtures/decompression.log lib/request_log_analyzer/file_format/apache.rb spec/unit/file_format/rack_format_spec.rb spec/fixtures/decompression.log.gz lib/request_log_analyzer/tracker/frequency.rb lib/request_log_analyzer/tracker/duration.rb tasks/github-gem.rake .gitignore spec/unit/filter/filter_spec.rb spec/lib/macros.rb spec/spec_helper.rb spec/fixtures/decompression.log.bz2 spec/unit/database/connection_spec.rb lib/request_log_analyzer/filter.rb spec/integration/scout_spec.rb spec/fixtures/test_file_format.log spec/unit/filter/timespan_filter_spec.rb lib/request_log_analyzer/tracker/traffic.rb spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/format_autodetection_spec.rb spec/unit/file_format/file_format_api_spec.rb lib/request_log_analyzer/filter/field.rb lib/request_log_analyzer/file_format/merb.rb lib/request_log_analyzer/filter/anonymize.rb lib/request_log_analyzer/file_format/amazon_s3.rb lib/cli/database_console.rb spec/integration/mailer_spec.rb lib/request_log_analyzer/line_definition.rb spec/unit/tracker/frequency_tracker_spec.rb spec/fixtures/postgresql.log spec/fixtures/multiple_files_2.log spec/lib/mocks.rb spec/unit/file_format/apache_format_spec.rb spec/fixtures/syslog_1x.log spec/integration/munin_plugins_rails_spec.rb spec/lib/helpers.rb spec/unit/file_format/delayed_job_format_spec.rb spec/fixtures/rails.db spec/unit/source/log_parser_spec.rb lib/request_log_analyzer/aggregator/database_inserter.rb spec/fixtures/header_and_footer.log spec/lib/testing_format.rb lib/request_log_analyzer/database.rb spec/unit/file_format/rails_format_spec.rb lib/request_log_analyzer/request.rb lib/request_log_analyzer/output/fixed_width.rb spec/integration/command_line_usage_spec.rb lib/request_log_analyzer/file_format/rack.rb lib/request_log_analyzer/tracker/numeric_value.rb spec/fixtures/test_language_combined.log spec/unit/request_spec.rb lib/cli/command_line_arguments.rb lib/request_log_analyzer.rb spec/database.yml lib/request_log_analyzer/database/base.rb spec/unit/aggregator/database_inserter_spec.rb lib/request_log_analyzer/database/request.rb lib/request_log_analyzer/output/fancy_html.rb lib/cli/database_console_init.rb lib/cli/progressbar.rb lib/request_log_analyzer/database/warning.rb spec/unit/filter/anonymize_filter_spec.rb spec/fixtures/apache_combined.log spec/unit/tracker/duration_tracker_spec.rb spec/fixtures/rails_22_cached.log lib/request_log_analyzer/aggregator/summarizer.rb spec/unit/file_format/postgresql_format_spec.rb spec/unit/file_format/common_regular_expressions_spec.rb spec/fixtures/rails_1x.log lib/request_log_analyzer/file_format/delayed_job.rb lib/request_log_analyzer/output.rb spec/unit/file_format/line_definition_spec.rb lib/request_log_analyzer/file_format/mysql.rb spec/unit/file_format/mysql_format_spec.rb request-log-analyzer.gemspec spec/fixtures/apache_common.log spec/unit/mailer_spec.rb lib/request_log_analyzer/file_format/rails.rb Rakefile lib/request_log_analyzer/tracker/hourly_spread.rb spec/unit/aggregator/summarizer_spec.rb spec/unit/tracker/traffic_tracker_spec.rb spec/unit/tracker/numeric_value_tracker_spec.rb lib/request_log_analyzer/file_format/postgresql.rb lib/request_log_analyzer/tracker/timespan.rb spec/unit/controller/log_processor_spec.rb spec/fixtures/sinatra.log spec/unit/filter/field_filter_spec.rb spec/fixtures/merb_prefixed.log lib/request_log_analyzer/log_processor.rb lib/request_log_analyzer/filter/timespan.rb spec/unit/controller/controller_spec.rb lib/request_log_analyzer/mailer.rb lib/cli/tools.rb spec/fixtures/decompression.tar.gz spec/unit/tracker/timespan_tracker_spec.rb spec/lib/matchers.rb lib/request_log_analyzer/controller.rb spec/unit/tracker/tracker_api_spec.rb lib/request_log_analyzer/source/database_loader.rb spec/fixtures/merb.log LICENSE lib/request_log_analyzer/file_format.rb tasks/request_log_analyzer.rake spec/unit/database/database_spec.rb spec/fixtures/decompression.log.zip spec/fixtures/decompression.tgz bin/request-log-analyzer lib/request_log_analyzer/tracker.rb lib/request_log_analyzer/source.rb spec/fixtures/mysql_slow_query.log lib/request_log_analyzer/source/log_parser.rb lib/request_log_analyzer/aggregator/echo.rb)
40
- s.test_files = %w(spec/unit/tracker/hourly_spread_spec.rb spec/unit/file_format/amazon_s3_format_spec.rb spec/unit/database/base_class_spec.rb spec/unit/file_format/rack_format_spec.rb spec/unit/filter/filter_spec.rb spec/unit/database/connection_spec.rb spec/integration/scout_spec.rb spec/unit/filter/timespan_filter_spec.rb spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/format_autodetection_spec.rb spec/unit/file_format/file_format_api_spec.rb spec/integration/mailer_spec.rb spec/unit/tracker/frequency_tracker_spec.rb spec/unit/file_format/apache_format_spec.rb spec/integration/munin_plugins_rails_spec.rb spec/unit/file_format/delayed_job_format_spec.rb spec/unit/source/log_parser_spec.rb spec/unit/file_format/rails_format_spec.rb spec/integration/command_line_usage_spec.rb spec/unit/request_spec.rb spec/unit/aggregator/database_inserter_spec.rb spec/unit/filter/anonymize_filter_spec.rb spec/unit/tracker/duration_tracker_spec.rb spec/unit/file_format/postgresql_format_spec.rb spec/unit/file_format/common_regular_expressions_spec.rb spec/unit/file_format/line_definition_spec.rb spec/unit/file_format/mysql_format_spec.rb spec/unit/mailer_spec.rb spec/unit/aggregator/summarizer_spec.rb spec/unit/tracker/traffic_tracker_spec.rb spec/unit/tracker/numeric_value_tracker_spec.rb spec/unit/controller/log_processor_spec.rb spec/unit/filter/field_filter_spec.rb spec/unit/controller/controller_spec.rb spec/unit/tracker/timespan_tracker_spec.rb spec/unit/tracker/tracker_api_spec.rb spec/unit/database/database_spec.rb)
39
+ s.files = %w(spec/unit/tracker/hourly_spread_spec.rb lib/request_log_analyzer/output/html.rb DESIGN.rdoc spec/fixtures/rails_unordered.log spec/fixtures/multiple_files_1.log lib/request_log_analyzer/database/source.rb README.rdoc spec/unit/file_format/amazon_s3_format_spec.rb lib/request_log_analyzer/file_format/rails_development.rb spec/fixtures/rails_22.log spec/fixtures/test_order.log spec/unit/database/base_class_spec.rb lib/request_log_analyzer/database/connection.rb lib/request_log_analyzer/aggregator.rb spec/fixtures/decompression.log lib/request_log_analyzer/file_format/apache.rb spec/unit/file_format/rack_format_spec.rb spec/fixtures/decompression.log.gz lib/request_log_analyzer/tracker/frequency.rb lib/request_log_analyzer/tracker/duration.rb tasks/github-gem.rake spec/unit/filter/filter_spec.rb .gitignore spec/lib/macros.rb spec/spec_helper.rb spec/fixtures/decompression.log.bz2 spec/unit/database/connection_spec.rb lib/request_log_analyzer/filter.rb spec/integration/scout_spec.rb spec/fixtures/test_file_format.log spec/unit/filter/timespan_filter_spec.rb lib/request_log_analyzer/tracker/traffic.rb spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/format_autodetection_spec.rb spec/unit/file_format/file_format_api_spec.rb lib/request_log_analyzer/filter/field.rb lib/request_log_analyzer/file_format/merb.rb lib/request_log_analyzer/filter/anonymize.rb lib/request_log_analyzer/file_format/amazon_s3.rb lib/cli/database_console.rb spec/integration/mailer_spec.rb lib/request_log_analyzer/line_definition.rb spec/unit/tracker/frequency_tracker_spec.rb spec/fixtures/postgresql.log spec/fixtures/multiple_files_2.log spec/lib/mocks.rb spec/unit/file_format/apache_format_spec.rb spec/fixtures/syslog_1x.log spec/unit/file_format/rails3_format_spec.rb spec/integration/munin_plugins_rails_spec.rb lib/request_log_analyzer/file_format/rails3.rb spec/lib/helpers.rb spec/unit/file_format/delayed_job_format_spec.rb spec/fixtures/rails.db spec/unit/source/log_parser_spec.rb lib/request_log_analyzer/aggregator/database_inserter.rb spec/fixtures/header_and_footer.log spec/lib/testing_format.rb lib/request_log_analyzer/database.rb spec/unit/file_format/rails_format_spec.rb lib/request_log_analyzer/request.rb lib/request_log_analyzer/output/fixed_width.rb spec/integration/command_line_usage_spec.rb lib/request_log_analyzer/file_format/rack.rb lib/request_log_analyzer/tracker/numeric_value.rb spec/fixtures/test_language_combined.log spec/unit/request_spec.rb lib/cli/command_line_arguments.rb lib/request_log_analyzer.rb spec/database.yml lib/request_log_analyzer/database/base.rb spec/unit/aggregator/database_inserter_spec.rb lib/request_log_analyzer/database/request.rb lib/request_log_analyzer/output/fancy_html.rb lib/cli/database_console_init.rb lib/cli/progressbar.rb lib/request_log_analyzer/database/warning.rb spec/unit/filter/anonymize_filter_spec.rb spec/fixtures/apache_combined.log spec/unit/tracker/duration_tracker_spec.rb spec/fixtures/rails_22_cached.log lib/request_log_analyzer/aggregator/summarizer.rb spec/unit/file_format/postgresql_format_spec.rb spec/unit/file_format/common_regular_expressions_spec.rb spec/fixtures/rails_1x.log lib/request_log_analyzer/file_format/delayed_job.rb lib/request_log_analyzer/output.rb spec/unit/file_format/line_definition_spec.rb lib/request_log_analyzer/file_format/mysql.rb spec/unit/file_format/mysql_format_spec.rb request-log-analyzer.gemspec spec/fixtures/apache_common.log spec/unit/mailer_spec.rb lib/request_log_analyzer/file_format/rails.rb Rakefile lib/request_log_analyzer/tracker/hourly_spread.rb spec/unit/aggregator/summarizer_spec.rb spec/unit/tracker/traffic_tracker_spec.rb spec/unit/tracker/numeric_value_tracker_spec.rb lib/request_log_analyzer/file_format/postgresql.rb lib/request_log_analyzer/tracker/timespan.rb spec/unit/controller/log_processor_spec.rb spec/unit/filter/field_filter_spec.rb spec/fixtures/sinatra.log spec/fixtures/merb_prefixed.log lib/request_log_analyzer/log_processor.rb lib/request_log_analyzer/filter/timespan.rb spec/unit/controller/controller_spec.rb lib/request_log_analyzer/mailer.rb lib/cli/tools.rb spec/fixtures/decompression.tar.gz spec/unit/tracker/timespan_tracker_spec.rb spec/lib/matchers.rb lib/request_log_analyzer/controller.rb spec/unit/tracker/tracker_api_spec.rb lib/request_log_analyzer/source/database_loader.rb spec/fixtures/merb.log LICENSE lib/request_log_analyzer/file_format.rb tasks/request_log_analyzer.rake spec/unit/database/database_spec.rb spec/fixtures/decompression.log.zip spec/fixtures/decompression.tgz bin/request-log-analyzer lib/request_log_analyzer/tracker.rb lib/request_log_analyzer/source.rb spec/fixtures/mysql_slow_query.log lib/request_log_analyzer/source/log_parser.rb lib/request_log_analyzer/aggregator/echo.rb)
40
+ s.test_files = %w(spec/unit/tracker/hourly_spread_spec.rb spec/unit/file_format/amazon_s3_format_spec.rb spec/unit/database/base_class_spec.rb spec/unit/file_format/rack_format_spec.rb spec/unit/filter/filter_spec.rb spec/unit/database/connection_spec.rb spec/integration/scout_spec.rb spec/unit/filter/timespan_filter_spec.rb spec/unit/file_format/merb_format_spec.rb spec/unit/file_format/format_autodetection_spec.rb spec/unit/file_format/file_format_api_spec.rb spec/integration/mailer_spec.rb spec/unit/tracker/frequency_tracker_spec.rb spec/unit/file_format/apache_format_spec.rb spec/unit/file_format/rails3_format_spec.rb spec/integration/munin_plugins_rails_spec.rb spec/unit/file_format/delayed_job_format_spec.rb spec/unit/source/log_parser_spec.rb spec/unit/file_format/rails_format_spec.rb spec/integration/command_line_usage_spec.rb spec/unit/request_spec.rb spec/unit/aggregator/database_inserter_spec.rb spec/unit/filter/anonymize_filter_spec.rb spec/unit/tracker/duration_tracker_spec.rb spec/unit/file_format/postgresql_format_spec.rb spec/unit/file_format/common_regular_expressions_spec.rb spec/unit/file_format/line_definition_spec.rb spec/unit/file_format/mysql_format_spec.rb spec/unit/mailer_spec.rb spec/unit/aggregator/summarizer_spec.rb spec/unit/tracker/traffic_tracker_spec.rb spec/unit/tracker/numeric_value_tracker_spec.rb spec/unit/controller/log_processor_spec.rb spec/unit/filter/field_filter_spec.rb spec/unit/controller/controller_spec.rb spec/unit/tracker/timespan_tracker_spec.rb spec/unit/tracker/tracker_api_spec.rb spec/unit/database/database_spec.rb)
41
41
  end
@@ -46,4 +46,22 @@ describe RequestLogAnalyzer::FileFormat::AmazonS3 do
46
46
  end
47
47
  end
48
48
 
49
+ it "should parse a COPY request correctly" do
50
+ line = '09216466b5571a8db0bf5abca72041fd3fc163e5eb83c51159735353ac6a2b9a testbucket [03/Mar/2010:23:04:59 +0000] 174.119.31.76 09216466b5571a8db0bf5abca72041fd3fc163e5eb83c51159735353ac6a2b9a ACCC34B843C87BC9 REST.COPY.OBJECT files/image.png "PUT /files/image.png HTTP/1.1" 200 - 234 65957 365 319 "-" "" -'
51
+ @file_format.should parse_line(line).as(:access).and_capture(
52
+ :bucket_owner => '09216466b5571a8db0bf5abca72041fd3fc163e5eb83c51159735353ac6a2b9a',
53
+ :bucket => 'testbucket',
54
+ :timestamp => 20100303230459,
55
+ :remote_ip => '174.119.31.76',
56
+ :requester => '09216466b5571a8db0bf5abca72041fd3fc163e5eb83c51159735353ac6a2b9a',
57
+ :key => 'files/image.png',
58
+ :operation => 'REST.COPY.OBJECT',
59
+ :total_time => 0.365,
60
+ :turnaround_time => 0.319,
61
+ :bytes_sent => 234,
62
+ :object_size => 65957,
63
+ :referer => nil,
64
+ :user_agent => '')
65
+ end
66
+
49
67
  end
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+
3
+ describe RequestLogAnalyzer::FileFormat::Rails do
4
+
5
+ it "should be a valid file format" do
6
+ RequestLogAnalyzer::FileFormat.load(:rails3).should be_valid
7
+ end
8
+
9
+ describe '#parse_line' do
10
+ before(:each) { @file_format = RequestLogAnalyzer::FileFormat.load(:rails3) }
11
+
12
+ it "should parse :started lines correctly" do
13
+ line = 'Started GET "/queries" for 127.0.0.1 at 2010-02-25 16:15:18'
14
+ @file_format.should parse_line(line).as(:started).and_capture(:method => 'GET',
15
+ :path => '/queries', :ip => '127.0.0.1', :timestamp => 20100225161518)
16
+ end
17
+
18
+ it "should parse :processing lines correctly" do
19
+ line = ' Processing by QueriesController#index as HTML'
20
+ @file_format.should parse_line(line).as(:processing).and_capture(
21
+ :controller => 'QueriesController', :action => 'index', :format => 'HTML')
22
+ end
23
+
24
+
25
+ # it "should parse beta :completed lines correctly" do
26
+ # line = 'Completed in 9ms (Views: 4.9ms | ActiveRecord: 0.5ms) with 200'
27
+ # @file_format.should parse_line(line).as(:completed).and_capture(
28
+ # :duration => 0.009, :status => 200)
29
+ # end
30
+
31
+ it "should parse :completed lines correctly" do
32
+ line = 'Completed 200 OK in 170ms (Views: 78.4ms | ActiveRecord: 48.2ms)'
33
+ @file_format.should parse_line(line).as(:completed).and_capture(
34
+ :duration => 0.170, :status => 200)
35
+ end
36
+
37
+ it "should pase :failure lines correctly" do
38
+ line = "ActionView::Template::Error (undefined local variable or method `field' for #<Class>) on line #3 of /Users/willem/Code/warehouse/app/views/queries/execute.csv.erb:"
39
+ @file_format.should parse_line(line).as(:failure).and_capture(:line => 3,
40
+ :error => 'ActionView::Template::Error',
41
+ :message => "undefined local variable or method `field' for #<Class>",
42
+ :file => '/Users/willem/Code/warehouse/app/views/queries/execute.csv.erb')
43
+ end
44
+ end
45
+
46
+ describe '#parse_io' do
47
+ before(:each) do
48
+ @log_parser = RequestLogAnalyzer::Source::LogParser.new(RequestLogAnalyzer::FileFormat.load(:rails3))
49
+ end
50
+
51
+ it "should parse a successful request correctly" do
52
+ log = <<-EOLOG
53
+ Started GET "/" for 127.0.0.1 at 2010-03-19 06:40:41
54
+ Processing by QueriesController#index as HTML
55
+ SQL (16.3ms) SHOW TABLES
56
+ Query Load (32.0ms) SELECT `queries`.* FROM `queries`
57
+ Rendered queries/index.html.erb within layouts/default (40.9ms)
58
+ Completed 200 OK in 170ms (Views: 78.4ms | ActiveRecord: 48.2ms)
59
+ EOLOG
60
+
61
+ request_counter.should_receive(:hit!).once
62
+ @log_parser.should_not_receive(:warn)
63
+
64
+ @log_parser.parse_io(StringIO.new(log)) do |request|
65
+ request_counter.hit! if request.kind_of?(RequestLogAnalyzer::FileFormat::Rails3::Request) && request.completed?
66
+ end
67
+ end
68
+
69
+ it "should parse an unroutable request correctly" do
70
+ log = <<-EOLOG
71
+ Started GET "/404" for 127.0.0.1 at 2010-03-19 06:40:57
72
+
73
+ ActionController::RoutingError (No route matches "/404"):
74
+
75
+
76
+ Rendered /Users/rails/actionpack/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (1.0ms)
77
+
78
+ EOLOG
79
+
80
+ request_counter.should_receive(:hit!).once
81
+ @log_parser.should_not_receive(:warn)
82
+
83
+ @log_parser.parse_io(StringIO.new(log)) do |request|
84
+ request_counter.hit! if request.kind_of?(RequestLogAnalyzer::FileFormat::Rails3::Request) && request.completed?
85
+ end
86
+ end
87
+
88
+ it "should parse a failing request correctly" do
89
+ log = <<-EOLOG
90
+ Started POST "/queries/397638749/execute.csv" for 127.0.0.1 at 2010-03-01 18:44:33
91
+ Processing by QueriesController#execute as CSV
92
+ Parameters: {"commit"=>"Run query", "authenticity_token"=>"pz9WcxkcrlG/43eg6BgSAnJL7yIsaffuHbYxPHUsUzQ=", "id"=>"397638749"}
93
+
94
+ ActionView::Template::Error (undefined local variable or method `field' for #<Class>) on line #3 of /Users/application/app/views/queries/execute.csv.erb:
95
+ 1: <%=raw @result.fields.map { |f| f.humanize.to_json }.join(',') %>
96
+ 2: <% @result.each do |record| %>
97
+ 3: <%=raw @result.fields.map { |f| record[field].to_s }.join(",") %>
98
+ 4: <% end %>
99
+
100
+ app/views/queries/execute.csv.erb:3:in `_render_template__652100315_2182241460_0'
101
+ app/views/queries/execute.csv.erb:3:in `map'
102
+ app/views/queries/execute.csv.erb:3:in `_render_template__652100315_2182241460_0'
103
+ app/views/queries/execute.csv.erb:2:in `_render_template__652100315_2182241460_0'
104
+ app/controllers/queries_controller.rb:34:in `execute'
105
+
106
+ Rendered /rails/actionpack-3.0.0.beta/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.0ms)
107
+ Rendered /rails/actionpack-3.0.0.beta/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (9.7ms)
108
+ Rendered /rails/actionpack-3.0.0.beta/lib/action_dispatch/middleware/templates/rescues/template_error.erb within /Users/willem/.rvm/gems/ruby-1.8.7-p248/gems/actionpack-3.0.0.beta/lib/action_dispatch/middleware/templates/rescues/layout.erb (20.4ms)
109
+
110
+ EOLOG
111
+
112
+ request_counter.should_receive(:hit!).once
113
+ @log_parser.should_not_receive(:warn)
114
+
115
+ @log_parser.parse_io(StringIO.new(log)) do |request|
116
+ request_counter.hit! if request.kind_of?(RequestLogAnalyzer::FileFormat::Rails3::Request) && request.completed?
117
+ end
118
+ end
119
+ end
120
+ end
@@ -119,19 +119,19 @@ module GithubGem
119
119
  checks = [:check_current_branch, :check_clean_status, :check_not_diverged, :check_version]
120
120
  checks.unshift('spec:basic') if has_specs?
121
121
  checks.unshift('test:basic') if has_tests?
122
- checks.push << [:check_rubyforge] if gemspec.rubyforge_project
122
+ # checks.push << [:check_rubyforge] if gemspec.rubyforge_project
123
123
 
124
124
  desc "Perform all checks that would occur before a release"
125
125
  task(:release_checks => checks)
126
126
 
127
127
  release_tasks = [:release_checks, :set_version, :build, :github_release, :gemcutter_release]
128
- release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
128
+ # release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
129
129
 
130
130
  desc "Release a new verison of the gem"
131
131
  task(:release => release_tasks) { release_task }
132
132
 
133
- task(:check_rubyforge) { check_rubyforge_task }
134
- task(:rubyforge_release) { rubyforge_release_task }
133
+ # task(:check_rubyforge) { check_rubyforge_task }
134
+ # task(:rubyforge_release) { rubyforge_release_task }
135
135
  task(:gemcutter_release) { gemcutter_release_task }
136
136
  task(:github_release => [:commit_modified_files, :tag_version]) { github_release_task }
137
137
  task(:tag_version) { tag_version_task }
@@ -216,19 +216,19 @@ module GithubGem
216
216
  git.push(remote, remote_branch, true)
217
217
  end
218
218
 
219
- # Checks whether Rubyforge is configured properly
220
- def check_rubyforge_task
221
- # Login no longer necessary when using rubyforge 2.0.0 gem
222
- # raise "Could not login on rubyforge!" unless `rubyforge login 2>&1`.strip.empty?
223
- output = `rubyforge names`.split("\n")
224
- raise "Rubyforge group not found!" unless output.any? { |line| %r[^groups\s*\:.*\b#{Regexp.quote(gemspec.rubyforge_project)}\b.*] =~ line }
225
- raise "Rubyforge package not found!" unless output.any? { |line| %r[^packages\s*\:.*\b#{Regexp.quote(gemspec.name)}\b.*] =~ line }
226
- end
227
-
228
- # Task to release the .gem file toRubyforge.
229
- def rubyforge_release_task
230
- sh 'rubyforge', 'add_release', gemspec.rubyforge_project, gemspec.name, gemspec.version.to_s, "pkg/#{gemspec.name}-#{gemspec.version}.gem"
231
- end
219
+ # # Checks whether Rubyforge is configured properly
220
+ # def check_rubyforge_task
221
+ # # Login no longer necessary when using rubyforge 2.0.0 gem
222
+ # # raise "Could not login on rubyforge!" unless `rubyforge login 2>&1`.strip.empty?
223
+ # output = `rubyforge names`.split("\n")
224
+ # raise "Rubyforge group not found!" unless output.any? { |line| %r[^groups\s*\:.*\b#{Regexp.quote(gemspec.rubyforge_project)}\b.*] =~ line }
225
+ # raise "Rubyforge package not found!" unless output.any? { |line| %r[^packages\s*\:.*\b#{Regexp.quote(gemspec.name)}\b.*] =~ line }
226
+ # end
227
+
228
+ # # Task to release the .gem file toRubyforge.
229
+ # def rubyforge_release_task
230
+ # sh 'rubyforge', 'add_release', gemspec.rubyforge_project, gemspec.name, gemspec.version.to_s, "pkg/#{gemspec.name}-#{gemspec.version}.gem"
231
+ # end
232
232
 
233
233
  def gemcutter_release_task
234
234
  sh "gem push pkg/#{gemspec.name}-#{gemspec.version}.gem"
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: request-log-analyzer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.2
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 6
8
+ - 3
9
+ version: 1.6.3
5
10
  platform: ruby
6
11
  authors:
7
12
  - Willem van Bergen
@@ -10,29 +15,37 @@ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2010-01-29 00:00:00 +01:00
18
+ date: 2010-03-19 00:00:00 -04:00
14
19
  default_executable: request-log-analyzer
15
20
  dependencies:
16
21
  - !ruby/object:Gem::Dependency
17
22
  name: rspec
18
- type: :development
19
- version_requirement:
20
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
21
25
  requirements:
22
26
  - - ">="
23
27
  - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 2
31
+ - 4
24
32
  version: 1.2.4
25
- version:
33
+ type: :development
34
+ version_requirements: *id001
26
35
  - !ruby/object:Gem::Dependency
27
36
  name: git
28
- type: :development
29
- version_requirement:
30
- version_requirements: !ruby/object:Gem::Requirement
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
31
39
  requirements:
32
40
  - - ">="
33
41
  - !ruby/object:Gem::Version
42
+ segments:
43
+ - 1
44
+ - 1
45
+ - 0
34
46
  version: 1.1.0
35
- version:
47
+ type: :development
48
+ version_requirements: *id002
36
49
  description: " Request log analyzer's purpose is to find out how your web application is being used, how it performs and to\n focus your optimization efforts. This tool will parse all requests in the application's log file and aggregate the \n information. Once it is finished parsing the log file(s), it will show the requests that take op most server time \n using various metrics. It can also insert all parsed request information into a database so you can roll your own\n analysis. It supports Rails-, Merb- and Rack-based applications logs, Apache and Amazon S3 access logs and MySQL \n slow query logs out of the box, but file formats of other applications can easily be supported by supplying an \n easy to write log file format definition.\n"
37
50
  email:
38
51
  - willem@railsdoctors.com
@@ -65,8 +78,8 @@ files:
65
78
  - lib/request_log_analyzer/tracker/frequency.rb
66
79
  - lib/request_log_analyzer/tracker/duration.rb
67
80
  - tasks/github-gem.rake
68
- - .gitignore
69
81
  - spec/unit/filter/filter_spec.rb
82
+ - .gitignore
70
83
  - spec/lib/macros.rb
71
84
  - spec/spec_helper.rb
72
85
  - spec/fixtures/decompression.log.bz2
@@ -92,7 +105,9 @@ files:
92
105
  - spec/lib/mocks.rb
93
106
  - spec/unit/file_format/apache_format_spec.rb
94
107
  - spec/fixtures/syslog_1x.log
108
+ - spec/unit/file_format/rails3_format_spec.rb
95
109
  - spec/integration/munin_plugins_rails_spec.rb
110
+ - lib/request_log_analyzer/file_format/rails3.rb
96
111
  - spec/lib/helpers.rb
97
112
  - spec/unit/file_format/delayed_job_format_spec.rb
98
113
  - spec/fixtures/rails.db
@@ -144,8 +159,8 @@ files:
144
159
  - lib/request_log_analyzer/file_format/postgresql.rb
145
160
  - lib/request_log_analyzer/tracker/timespan.rb
146
161
  - spec/unit/controller/log_processor_spec.rb
147
- - spec/fixtures/sinatra.log
148
162
  - spec/unit/filter/field_filter_spec.rb
163
+ - spec/fixtures/sinatra.log
149
164
  - spec/fixtures/merb_prefixed.log
150
165
  - lib/request_log_analyzer/log_processor.rb
151
166
  - lib/request_log_analyzer/filter/timespan.rb
@@ -189,18 +204,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
189
204
  requirements:
190
205
  - - ">="
191
206
  - !ruby/object:Gem::Version
207
+ segments:
208
+ - 0
192
209
  version: "0"
193
- version:
194
210
  required_rubygems_version: !ruby/object:Gem::Requirement
195
211
  requirements:
196
212
  - - ">="
197
213
  - !ruby/object:Gem::Version
214
+ segments:
215
+ - 0
198
216
  version: "0"
199
- version:
200
217
  requirements:
201
218
  - To use the database inserter, ActiveRecord and an appropriate database adapter are required.
202
219
  rubyforge_project: r-l-a
203
- rubygems_version: 1.3.5
220
+ rubygems_version: 1.3.6
204
221
  signing_key:
205
222
  specification_version: 3
206
223
  summary: A command line tool to analyze request logs for Apache, Rails, Merb, MySQL and other web application servers
@@ -219,6 +236,7 @@ test_files:
219
236
  - spec/integration/mailer_spec.rb
220
237
  - spec/unit/tracker/frequency_tracker_spec.rb
221
238
  - spec/unit/file_format/apache_format_spec.rb
239
+ - spec/unit/file_format/rails3_format_spec.rb
222
240
  - spec/integration/munin_plugins_rails_spec.rb
223
241
  - spec/unit/file_format/delayed_job_format_spec.rb
224
242
  - spec/unit/source/log_parser_spec.rb