request-log-analyzer 1.13.1 → 1.13.3

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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/bin/console +17 -0
  4. data/lib/cli/command_line_arguments.rb +29 -36
  5. data/lib/cli/database_console.rb +1 -3
  6. data/lib/cli/database_console_init.rb +11 -11
  7. data/lib/cli/progressbar.rb +30 -32
  8. data/lib/cli/tools.rb +20 -23
  9. data/lib/request_log_analyzer.rb +8 -8
  10. data/lib/request_log_analyzer/aggregator.rb +4 -7
  11. data/lib/request_log_analyzer/aggregator/database_inserter.rb +10 -13
  12. data/lib/request_log_analyzer/aggregator/echo.rb +5 -7
  13. data/lib/request_log_analyzer/aggregator/summarizer.rb +15 -18
  14. data/lib/request_log_analyzer/class_level_inheritable_attributes.rb +23 -0
  15. data/lib/request_log_analyzer/controller.rb +36 -42
  16. data/lib/request_log_analyzer/database.rb +4 -6
  17. data/lib/request_log_analyzer/database/base.rb +39 -41
  18. data/lib/request_log_analyzer/database/connection.rb +8 -10
  19. data/lib/request_log_analyzer/database/request.rb +1 -3
  20. data/lib/request_log_analyzer/database/source.rb +0 -2
  21. data/lib/request_log_analyzer/database/warning.rb +4 -6
  22. data/lib/request_log_analyzer/file_format.rb +46 -49
  23. data/lib/request_log_analyzer/file_format/amazon_s3.rb +15 -19
  24. data/lib/request_log_analyzer/file_format/apache.rb +42 -45
  25. data/lib/request_log_analyzer/file_format/delayed_job.rb +13 -15
  26. data/lib/request_log_analyzer/file_format/delayed_job2.rb +9 -11
  27. data/lib/request_log_analyzer/file_format/delayed_job21.rb +9 -11
  28. data/lib/request_log_analyzer/file_format/delayed_job3.rb +5 -8
  29. data/lib/request_log_analyzer/file_format/delayed_job4.rb +5 -8
  30. data/lib/request_log_analyzer/file_format/haproxy.rb +44 -48
  31. data/lib/request_log_analyzer/file_format/merb.rb +13 -17
  32. data/lib/request_log_analyzer/file_format/mysql.rb +21 -25
  33. data/lib/request_log_analyzer/file_format/nginx.rb +0 -2
  34. data/lib/request_log_analyzer/file_format/oink.rb +30 -31
  35. data/lib/request_log_analyzer/file_format/postgresql.rb +11 -15
  36. data/lib/request_log_analyzer/file_format/rack.rb +0 -2
  37. data/lib/request_log_analyzer/file_format/rails.rb +100 -104
  38. data/lib/request_log_analyzer/file_format/rails3.rb +19 -23
  39. data/lib/request_log_analyzer/file_format/rails_development.rb +0 -1
  40. data/lib/request_log_analyzer/file_format/w3c.rb +16 -18
  41. data/lib/request_log_analyzer/filter.rb +0 -2
  42. data/lib/request_log_analyzer/filter/anonymize.rb +4 -7
  43. data/lib/request_log_analyzer/filter/field.rb +3 -6
  44. data/lib/request_log_analyzer/filter/timespan.rb +2 -6
  45. data/lib/request_log_analyzer/line_definition.rb +16 -19
  46. data/lib/request_log_analyzer/log_processor.rb +10 -14
  47. data/lib/request_log_analyzer/mailer.rb +9 -12
  48. data/lib/request_log_analyzer/output.rb +12 -14
  49. data/lib/request_log_analyzer/output/fixed_width.rb +21 -28
  50. data/lib/request_log_analyzer/output/html.rb +11 -14
  51. data/lib/request_log_analyzer/request.rb +53 -33
  52. data/lib/request_log_analyzer/source.rb +2 -5
  53. data/lib/request_log_analyzer/source/log_parser.rb +9 -16
  54. data/lib/request_log_analyzer/tracker.rb +10 -12
  55. data/lib/request_log_analyzer/tracker/duration.rb +4 -6
  56. data/lib/request_log_analyzer/tracker/frequency.rb +9 -11
  57. data/lib/request_log_analyzer/tracker/hourly_spread.rb +8 -11
  58. data/lib/request_log_analyzer/tracker/numeric_value.rb +40 -44
  59. data/lib/request_log_analyzer/tracker/timespan.rb +5 -8
  60. data/lib/request_log_analyzer/tracker/traffic.rb +8 -10
  61. data/lib/request_log_analyzer/version.rb +1 -1
  62. data/request-log-analyzer.gemspec +6 -6
  63. data/spec/integration/command_line_usage_spec.rb +33 -33
  64. data/spec/integration/mailer_spec.rb +181 -185
  65. data/spec/integration/munin_plugins_rails_spec.rb +20 -20
  66. data/spec/integration/scout_spec.rb +40 -41
  67. data/spec/lib/helpers.rb +8 -9
  68. data/spec/lib/macros.rb +2 -4
  69. data/spec/lib/matchers.rb +20 -25
  70. data/spec/lib/mocks.rb +10 -11
  71. data/spec/lib/testing_format.rb +8 -10
  72. data/spec/spec_helper.rb +5 -1
  73. data/spec/unit/aggregator/database_inserter_spec.rb +23 -23
  74. data/spec/unit/aggregator/summarizer_spec.rb +7 -7
  75. data/spec/unit/controller/controller_spec.rb +14 -14
  76. data/spec/unit/controller/log_processor_spec.rb +3 -3
  77. data/spec/unit/database/base_class_spec.rb +36 -37
  78. data/spec/unit/database/connection_spec.rb +10 -10
  79. data/spec/unit/database/database_spec.rb +11 -11
  80. data/spec/unit/file_format/amazon_s3_format_spec.rb +66 -62
  81. data/spec/unit/file_format/apache_format_spec.rb +57 -52
  82. data/spec/unit/file_format/common_regular_expressions_spec.rb +18 -21
  83. data/spec/unit/file_format/delayed_job21_format_spec.rb +22 -16
  84. data/spec/unit/file_format/delayed_job2_format_spec.rb +22 -16
  85. data/spec/unit/file_format/delayed_job3_format_spec.rb +14 -10
  86. data/spec/unit/file_format/delayed_job4_format_spec.rb +14 -10
  87. data/spec/unit/file_format/delayed_job_format_spec.rb +12 -12
  88. data/spec/unit/file_format/file_format_api_spec.rb +19 -19
  89. data/spec/unit/file_format/format_autodetection_spec.rb +7 -7
  90. data/spec/unit/file_format/haproxy_format_spec.rb +53 -49
  91. data/spec/unit/file_format/inheritance_spec.rb +13 -0
  92. data/spec/unit/file_format/line_definition_spec.rb +35 -33
  93. data/spec/unit/file_format/merb_format_spec.rb +13 -11
  94. data/spec/unit/file_format/mysql_format_spec.rb +24 -24
  95. data/spec/unit/file_format/oink_format_spec.rb +29 -29
  96. data/spec/unit/file_format/postgresql_format_spec.rb +9 -9
  97. data/spec/unit/file_format/rack_format_spec.rb +36 -31
  98. data/spec/unit/file_format/rails3_format_spec.rb +46 -46
  99. data/spec/unit/file_format/rails_format_spec.rb +52 -53
  100. data/spec/unit/file_format/w3c_format_spec.rb +27 -24
  101. data/spec/unit/filter/anonymize_filter_spec.rb +7 -7
  102. data/spec/unit/filter/field_filter_spec.rb +26 -26
  103. data/spec/unit/filter/filter_spec.rb +4 -4
  104. data/spec/unit/filter/timespan_filter_spec.rb +22 -22
  105. data/spec/unit/mailer_spec.rb +21 -21
  106. data/spec/unit/request_spec.rb +29 -29
  107. data/spec/unit/source/log_parser_spec.rb +5 -5
  108. data/spec/unit/tracker/duration_tracker_spec.rb +23 -23
  109. data/spec/unit/tracker/frequency_tracker_spec.rb +29 -30
  110. data/spec/unit/tracker/hourly_spread_spec.rb +35 -35
  111. data/spec/unit/tracker/numeric_value_tracker_spec.rb +71 -72
  112. data/spec/unit/tracker/timespan_tracker_spec.rb +31 -31
  113. data/spec/unit/tracker/tracker_api_spec.rb +43 -44
  114. data/spec/unit/tracker/traffic_tracker_spec.rb +7 -7
  115. metadata +38 -35
@@ -1,20 +1,18 @@
1
1
  module RequestLogAnalyzer::FileFormat
2
-
3
2
  # PostgresQL spec 8.3.7
4
3
  class Postgresql < Base
5
-
6
4
  extend CommonRegularExpressions
7
-
5
+
8
6
  line_definition :query do |line|
9
7
  line.header = true
10
8
  line.teaser = /.*LOG\:/
11
9
  line.regexp = /(#{timestamp('%Y-%m-%d %k:%M:%S')})\ \S+ \[\d+\]\:\ \[.*\]\ LOG\:\ \ \d+\:\ duration\: (.*)\ ms\ \ statement:\ (.*)/
12
10
 
13
11
  line.capture(:timestamp).as(:timestamp)
14
- line.capture(:query_time).as(:duration, :unit => :sec)
12
+ line.capture(:query_time).as(:duration, unit: :sec)
15
13
  line.capture(:query_fragment)
16
14
  end
17
-
15
+
18
16
  line_definition :location do |line|
19
17
  line.footer = true
20
18
  line.teaser = /.*LOCATION:/
@@ -22,7 +20,7 @@ module RequestLogAnalyzer::FileFormat
22
20
 
23
21
  line.capture(:query).as(:sql) # Hack to gather up fragments
24
22
  end
25
-
23
+
26
24
  line_definition :query_fragment do |line|
27
25
  line.regexp = /^(?!.*LOG)\s*(.*)\s*/
28
26
  line.capture(:query_fragment)
@@ -30,14 +28,12 @@ module RequestLogAnalyzer::FileFormat
30
28
 
31
29
  report do |analyze|
32
30
  analyze.timespan
33
- analyze.hourly_spread
34
- analyze.duration :query_time, :category => :query, :title => 'Query time'
31
+ analyze.hourly_spread
32
+ analyze.duration :query_time, category: :query, title: 'Query time'
35
33
  end
36
-
37
- class Request < RequestLogAnalyzer::Request
38
34
 
39
- def convert_sql(value, definition)
40
-
35
+ class Request < RequestLogAnalyzer::Request
36
+ def convert_sql(value, _definition)
41
37
  # Recreate the full SQL query by joining all the previous parts and this last line
42
38
  sql = every(:query_fragment).join("\n") + value
43
39
 
@@ -52,7 +48,7 @@ module RequestLogAnalyzer::FileFormat
52
48
  sql.gsub!(/(:int,)+:int/, ':ints') # replace multiple ints by a list
53
49
  sql.gsub!(/(:string,)+:string/, ':strings') # replace multiple strings by a list
54
50
 
55
- return sql.lstrip.rstrip
51
+ sql.lstrip.rstrip
56
52
  end
57
53
 
58
54
  def host
@@ -60,9 +56,9 @@ module RequestLogAnalyzer::FileFormat
60
56
  end
61
57
 
62
58
  # Convert the timestamp to an integer
63
- def convert_timestamp(value, definition)
59
+ def convert_timestamp(value, _definition)
64
60
  _, y, m, d, h, i, s = value.split(/(\d\d)-(\d\d)-(\d\d)\s+(\d?\d):(\d\d):(\d\d)/)
65
- ('20%s%s%s%s%s%s' % [y,m,d,h.rjust(2, '0'),i,s]).to_i
61
+ ('20%s%s%s%s%s%s' % [y, m, d, h.rjust(2, '0'), i, s]).to_i
66
62
  end
67
63
  end
68
64
  end
@@ -1,7 +1,5 @@
1
1
  module RequestLogAnalyzer::FileFormat
2
-
3
2
  class Rack < Apache
4
-
5
3
  def self.create(*args)
6
4
  super(:rack, *args)
7
5
  end
@@ -1,79 +1,77 @@
1
1
  module RequestLogAnalyzer::FileFormat
2
-
3
2
  # Default FileFormat class for Rails logs.
4
3
  #
5
4
  # Instances will be created dynamically based on the lines you want it to parse. You can
6
5
  # specify what lines should be included in the parser by providing a list to the create
7
6
  # method as first argument.
8
7
  class Rails < Base
9
-
10
8
  extend CommonRegularExpressions
11
9
 
12
10
  # Creates a Rails FileFormat instance.
13
11
  #
14
- # The lines that will be parsed can be defined by the argument to this function,
12
+ # The lines that will be parsed can be defined by the argument to this function,
15
13
  # which should be an array of line names, or a list of line names as comma separated
16
- # string. The resulting report depends on the lines that will be parsed. You can
14
+ # string. The resulting report depends on the lines that will be parsed. You can
17
15
  # also provide s string that describes a common set of lines, like "production",
18
16
  # "development" or "production".
19
17
  def self.create(lines = 'production')
20
18
  definitions_hash = line_definer.line_definitions.clone
21
-
22
- lines = lines.to_s.split(',') if lines.kind_of?(String)
23
- lines = [lines.to_s] if lines.kind_of?(Symbol)
24
-
19
+
20
+ lines = lines.to_s.split(',') if lines.is_a?(String)
21
+ lines = [lines.to_s] if lines.is_a?(Symbol)
22
+
25
23
  lines.each do |line|
26
24
  line = line.to_sym
27
- if LINE_COLLECTIONS.has_key?(line)
25
+ if LINE_COLLECTIONS.key?(line)
28
26
  LINE_COLLECTIONS[line].each { |l| definitions_hash[l] ||= LINE_DEFINITIONS[l] }
29
- elsif LINE_DEFINITIONS.has_key?(line)
27
+ elsif LINE_DEFINITIONS.key?(line)
30
28
  definitions_hash[line] ||= LINE_DEFINITIONS[line]
31
29
  else
32
- raise "Unrecognized Rails log line name: #{line.inspect}!"
30
+ fail "Unrecognized Rails log line name: #{line.inspect}!"
33
31
  end
34
32
  end
35
33
 
36
- return self.new(definitions_hash, report_trackers(definitions_hash))
34
+ new(definitions_hash, report_trackers(definitions_hash))
37
35
  end
38
-
36
+
39
37
  # Creates trackers based on the specified line definitions.
40
38
  #
41
39
  # The more lines that will be parsed, the more information will appear in the report.
42
40
  def self.report_trackers(lines)
43
41
  analyze = RequestLogAnalyzer::Aggregator::Summarizer::Definer.new
44
-
42
+
45
43
  analyze.timespan
46
44
  analyze.hourly_spread
47
-
48
- analyze.frequency :category => REQUEST_CATEGORIZER, :title => 'Most requested'
49
- analyze.frequency :method, :title => 'HTTP methods'
50
- analyze.frequency :status, :title => 'HTTP statuses returned'
51
-
52
- if lines.has_key?(:cache_hit)
53
- analyze.frequency(:category => lambda { |request| request =~ :cache_hit ? 'Cache hit' : 'No hit' },
54
- :title => 'Rails action cache hits')
45
+
46
+ analyze.frequency category: REQUEST_CATEGORIZER, title: 'Most requested'
47
+ analyze.frequency :method, title: 'HTTP methods'
48
+ analyze.frequency :status, title: 'HTTP statuses returned'
49
+
50
+ if lines.key?(:cache_hit)
51
+ analyze.frequency(category: lambda { |request| request =~ :cache_hit ? 'Cache hit' : 'No hit' },
52
+ title: 'Rails action cache hits')
55
53
  end
56
-
57
- analyze.duration :duration, :category => REQUEST_CATEGORIZER, :title => "Request duration", :line_type => :completed
58
- analyze.duration :view, :category => REQUEST_CATEGORIZER, :title => "View rendering time", :line_type => :completed
59
- analyze.duration :db, :category => REQUEST_CATEGORIZER, :title => "Database time", :line_type => :completed
60
-
61
- analyze.frequency :category => REQUEST_CATEGORIZER, :title => 'Process blockers (> 1 sec duration)',
62
- :if => lambda { |request| request[:duration] && request[:duration] > 1.0 }
63
-
64
- if lines.has_key?(:failure)
65
- analyze.frequency :error, :title => 'Failed requests', :line_type => :failure
54
+
55
+ analyze.duration :duration, category: REQUEST_CATEGORIZER, title: 'Request duration', line_type: :completed
56
+ analyze.duration :view, category: REQUEST_CATEGORIZER, title: 'View rendering time', line_type: :completed
57
+ analyze.duration :db, category: REQUEST_CATEGORIZER, title: 'Database time', line_type: :completed
58
+
59
+ analyze.frequency category: REQUEST_CATEGORIZER, title: 'Process blockers (> 1 sec duration)',
60
+ if: lambda { |request| request[:duration] && request[:duration] > 1.0 }
61
+
62
+ if lines.key?(:failure)
63
+ analyze.frequency :error, title: 'Failed requests', line_type: :failure
66
64
  end
67
65
 
68
- if lines.has_key?(:rendered)
69
- analyze.duration :render_duration, :category => :render_file, :multiple => true, :title => 'Partial rendering duration'
66
+ if lines.key?(:rendered)
67
+ analyze.duration :render_duration, category: :render_file, multiple: true, title: 'Partial rendering duration'
70
68
  end
71
69
 
72
- if lines.has_key?(:query_executed)
73
- analyze.duration :query_duration, :category => :query_sql, :multiple => true, :title => 'Query duration'
70
+ if lines.key?(:query_executed)
71
+ analyze.duration :query_duration, category: :query_sql, multiple: true, title: 'Query duration'
74
72
  end
75
-
76
- return analyze.trackers + report_definer.trackers
73
+
74
+ analyze.trackers + report_definer.trackers
77
75
  end
78
76
 
79
77
  # Rails < 2.1 completed line example
@@ -83,92 +81,90 @@ module RequestLogAnalyzer::FileFormat
83
81
  # Rails > 2.1 completed line example
84
82
  # Completed in 614ms (View: 120, DB: 31) | 200 OK [http://floorplanner.local/demo]
85
83
  RAILS_22_COMPLETED = /Completed in (\d+)ms \((?:View: (\d+))?,?(?:.?DB: (\d+))?\)? \| (\d{3}).+\[(http.+)\]/
86
-
84
+
87
85
  # A hash of definitions for all common lines in Rails logs.
88
86
  LINE_DEFINITIONS = {
89
- :processing => RequestLogAnalyzer::LineDefinition.new(:processing, :header => true,
90
- :teaser => /Processing /,
91
- :regexp => /Processing ((?:\w+::)*\w+)#(\w+)(?: to (\w+))? \(for (#{ip_address}) at (#{timestamp('%Y-%m-%d %H:%M:%S')})\) \[([A-Z]+)\]/,
92
- :captures => [{ :name => :controller, :type => :string },
93
- { :name => :action, :type => :string },
94
- { :name => :format, :type => :string, :default => 'html' },
95
- { :name => :ip, :type => :string },
96
- { :name => :timestamp, :type => :timestamp },
97
- { :name => :method, :type => :string }]),
98
-
99
- :completed => RequestLogAnalyzer::LineDefinition.new(:completed, :footer => true,
100
- :teaser => /Completed in /,
101
- :regexp => Regexp.union(RAILS_21_COMPLETED, RAILS_22_COMPLETED),
102
- :captures => [{ :name => :duration, :type => :duration, :unit => :sec }, # First old variant capture
103
- { :name => :view, :type => :duration, :unit => :sec },
104
- { :name => :db, :type => :duration, :unit => :sec },
105
- { :name => :status, :type => :integer },
106
- { :name => :url, :type => :string }, # Last old variant capture
107
- { :name => :duration, :type => :duration, :unit => :msec }, # First new variant capture
108
- { :name => :view, :type => :duration, :unit => :msec },
109
- { :name => :db, :type => :duration, :unit => :msec },
110
- { :name => :status, :type => :integer },
111
- { :name => :url, :type => :string }]), # Last new variant capture
112
-
113
- :failure => RequestLogAnalyzer::LineDefinition.new(:failure, :footer => true,
114
- :teaser => /((?:[A-Z]\w*[a-z]\w+\:\:)*[A-Z]\w*[a-z]\w+) \((.*)\)(?: on line #(\d+) of (.+))?\:/,
115
- :regexp => /((?:[A-Z]\w*[a-z]\w+\:\:)*[A-Z]\w*[a-z]\w+) \((.*)\)(?: on line #(\d+) of (.+))?\:\s*$/,
116
- :captures => [{ :name => :error, :type => :string },
117
- { :name => :message, :type => :string },
118
- { :name => :line, :type => :integer },
119
- { :name => :file, :type => :string }]),
120
-
121
- :cache_hit => RequestLogAnalyzer::LineDefinition.new(:cache_hit,
122
- :regexp => /Filter chain halted as \[\#<ActionController::Filters::AroundFilter.*\@method=.*(?:Caching::Actions::ActionCacheFilter|action_controller\/caching\/actions\.rb).*\] did_not_yield/),
123
-
124
- :parameters => RequestLogAnalyzer::LineDefinition.new(:parameters,
125
- :teaser => / Parameters:/,
126
- :regexp => / Parameters:\s+(\{.*\})/,
127
- :captures => [{ :name => :params, :type => :eval }]),
128
-
129
- :rendered => RequestLogAnalyzer::LineDefinition.new(:rendered,
130
- :teaser => /Rendered /,
131
- :regexp => /Rendered (\w+(?:\/\w+)+) \((\d+\.\d+)ms\)/,
132
- :captures => [{ :name => :render_file, :type => :string },
133
- { :name => :render_duration, :type => :duration, :unit => :msec }]),
134
-
135
- :query_executed => RequestLogAnalyzer::LineDefinition.new(:query_executed,
136
- :regexp => /\s+(?:\e\[4;36;1m)?((?:\w+::)*\w+) Load \((\d+\.\d+)ms\)(?:\e\[0m)?\s+(?:\e\[0;1m)?([^\e]+) ?(?:\e\[0m)?/,
137
- :captures => [{ :name => :query_class, :type => :string },
138
- { :name => :query_duration, :type => :duration, :unit => :msec },
139
- { :name => :query_sql, :type => :sql }]),
140
-
141
- :query_cached => RequestLogAnalyzer::LineDefinition.new(:query_cached,
142
- :regexp => /\s+(?:\e\[4;35;1m)?CACHE \((\d+\.\d+)ms\)(?:\e\[0m)?\s+(?:\e\[0m)?([^\e]+) ?(?:\e\[0m)?/,
143
- :captures => [{ :name => :cached_duration, :type => :duration, :unit => :msec },
144
- { :name => :cached_sql, :type => :sql }])
87
+ processing: RequestLogAnalyzer::LineDefinition.new(:processing, header: true,
88
+ teaser: /Processing /,
89
+ regexp: /Processing ((?:\w+::)*\w+)#(\w+)(?: to (\w+))? \(for (#{ip_address}) at (#{timestamp('%Y-%m-%d %H:%M:%S')})\) \[([A-Z]+)\]/,
90
+ captures: [{ name: :controller, type: :string },
91
+ { name: :action, type: :string },
92
+ { name: :format, type: :string, default: 'html' },
93
+ { name: :ip, type: :string },
94
+ { name: :timestamp, type: :timestamp },
95
+ { name: :method, type: :string }]),
96
+
97
+ completed: RequestLogAnalyzer::LineDefinition.new(:completed, footer: true,
98
+ teaser: /Completed in /,
99
+ regexp: Regexp.union(RAILS_21_COMPLETED, RAILS_22_COMPLETED),
100
+ captures: [{ name: :duration, type: :duration, unit: :sec }, # First old variant capture
101
+ { name: :view, type: :duration, unit: :sec },
102
+ { name: :db, type: :duration, unit: :sec },
103
+ { name: :status, type: :integer },
104
+ { name: :url, type: :string }, # Last old variant capture
105
+ { name: :duration, type: :duration, unit: :msec }, # First new variant capture
106
+ { name: :view, type: :duration, unit: :msec },
107
+ { name: :db, type: :duration, unit: :msec },
108
+ { name: :status, type: :integer },
109
+ { name: :url, type: :string }]), # Last new variant capture
110
+
111
+ failure: RequestLogAnalyzer::LineDefinition.new(:failure, footer: true,
112
+ teaser: /((?:[A-Z]\w*[a-z]\w+\:\:)*[A-Z]\w*[a-z]\w+) \((.*)\)(?: on line #(\d+) of (.+))?\:/,
113
+ regexp: /((?:[A-Z]\w*[a-z]\w+\:\:)*[A-Z]\w*[a-z]\w+) \((.*)\)(?: on line #(\d+) of (.+))?\:\s*$/,
114
+ captures: [{ name: :error, type: :string },
115
+ { name: :message, type: :string },
116
+ { name: :line, type: :integer },
117
+ { name: :file, type: :string }]),
118
+
119
+ cache_hit: RequestLogAnalyzer::LineDefinition.new(:cache_hit,
120
+ regexp: /Filter chain halted as \[\#<ActionController::Filters::AroundFilter.*\@method=.*(?:Caching::Actions::ActionCacheFilter|action_controller\/caching\/actions\.rb).*\] did_not_yield/),
121
+
122
+ parameters: RequestLogAnalyzer::LineDefinition.new(:parameters,
123
+ teaser: / Parameters:/,
124
+ regexp: / Parameters:\s+(\{.*\})/,
125
+ captures: [{ name: :params, type: :eval }]),
126
+
127
+ rendered: RequestLogAnalyzer::LineDefinition.new(:rendered,
128
+ teaser: /Rendered /,
129
+ regexp: /Rendered (\w+(?:\/\w+)+) \((\d+\.\d+)ms\)/,
130
+ captures: [{ name: :render_file, type: :string },
131
+ { name: :render_duration, type: :duration, unit: :msec }]),
132
+
133
+ query_executed: RequestLogAnalyzer::LineDefinition.new(:query_executed,
134
+ regexp: /\s+(?:\e\[4;36;1m)?((?:\w+::)*\w+) Load \((\d+\.\d+)ms\)(?:\e\[0m)?\s+(?:\e\[0;1m)?([^\e]+) ?(?:\e\[0m)?/,
135
+ captures: [{ name: :query_class, type: :string },
136
+ { name: :query_duration, type: :duration, unit: :msec },
137
+ { name: :query_sql, type: :sql }]),
138
+
139
+ query_cached: RequestLogAnalyzer::LineDefinition.new(:query_cached,
140
+ regexp: /\s+(?:\e\[4;35;1m)?CACHE \((\d+\.\d+)ms\)(?:\e\[0m)?\s+(?:\e\[0m)?([^\e]+) ?(?:\e\[0m)?/,
141
+ captures: [{ name: :cached_duration, type: :duration, unit: :msec },
142
+ { name: :cached_sql, type: :sql }])
145
143
  }
146
144
 
147
145
  # Definitions of common combinations of lines that can be parsed
148
146
  LINE_COLLECTIONS = {
149
- :minimal => [:processing, :completed],
150
- :production => [:processing, :completed, :failure, :cache_hit],
151
- :development => [:processing, :completed, :failure, :rendered, :query_executed, :query_cached],
152
- :all => LINE_DEFINITIONS.keys
147
+ minimal: [:processing, :completed],
148
+ production: [:processing, :completed, :failure, :cache_hit],
149
+ development: [:processing, :completed, :failure, :rendered, :query_executed, :query_cached],
150
+ all: LINE_DEFINITIONS.keys
153
151
  }
154
152
 
155
-
156
153
  # Simple function to categorize Rails requests using controller/actions/format and method.
157
- REQUEST_CATEGORIZER = Proc.new do |request|
154
+ REQUEST_CATEGORIZER = proc do |request|
158
155
  "#{request[:controller]}##{request[:action]}.#{request[:format]} [#{request[:method]}]"
159
156
  end
160
157
 
161
158
  # Define a custom Request class for the Rails file format to speed up timestamp handling
162
159
  # and to ensure that a format is always set.
163
160
  class Request < RequestLogAnalyzer::Request
164
-
165
161
  # Do not use DateTime.parse
166
- def convert_timestamp(value, definition)
162
+ def convert_timestamp(value, _definition)
167
163
  value.gsub(/[^0-9]/, '')[0...14].to_i
168
164
  end
169
165
 
170
166
  # Sanitizes SQL queries so that they can be grouped
171
- def convert_sql(sql, definition)
167
+ def convert_sql(sql, _definition)
172
168
  sql.gsub(/\b\d+\b/, ':int').gsub(/`([^`]+)`/, '\1').gsub(/'[^']*'/, ':string').rstrip
173
169
  end
174
170
  end
@@ -1,11 +1,9 @@
1
1
  module RequestLogAnalyzer::FileFormat
2
-
3
2
  # Default FileFormat class for Rails 3 logs.
4
3
  #
5
4
  # For now, this is just a basic implementation. It will probaby change after
6
5
  # Rails 3 final has been released.
7
6
  class Rails3 < Base
8
-
9
7
  extend CommonRegularExpressions
10
8
 
11
9
  # beta4: Started GET "/" for 127.0.0.1 at Wed Jul 07 09:13:27 -0700 2010 (different time format)
@@ -46,9 +44,9 @@ module RequestLogAnalyzer::FileFormat
46
44
  line.regexp = /Completed (\d+)? .*in (\d+(?:\.\d+)?)ms(?:[^\(]*\(Views: (\d+(?:\.\d+)?)ms .* ActiveRecord: (\d+(?:\.\d+)?)ms.*\))?/
47
45
 
48
46
  line.capture(:status).as(:integer)
49
- line.capture(:duration).as(:duration, :unit => :msec)
50
- line.capture(:view).as(:duration, :unit => :msec)
51
- line.capture(:db).as(:duration, :unit => :msec)
47
+ line.capture(:duration).as(:duration, unit: :msec)
48
+ line.capture(:view).as(:duration, unit: :msec)
49
+ line.capture(:db).as(:duration, unit: :msec)
52
50
  end
53
51
 
54
52
  # ActionController::RoutingError (No route matches [GET] "/missing_stuff"):
@@ -76,7 +74,7 @@ module RequestLogAnalyzer::FileFormat
76
74
  line.teaser = /\bRendered /
77
75
  line.regexp = /\bRendered ([a-zA-Z0-9_\-\/.]+(?:\/[a-zA-Z0-9_\-.]+)+)(?:\ within\ .*?)? \((\d+(?:\.\d+)?)ms\)/
78
76
  line.capture(:rendered_file)
79
- line.capture(:partial_duration).as(:duration, :unit => :msec)
77
+ line.capture(:partial_duration).as(:duration, unit: :msec)
80
78
  end
81
79
 
82
80
  # # Not parsed at the moment:
@@ -91,46 +89,44 @@ module RequestLogAnalyzer::FileFormat
91
89
  analyze.timespan
92
90
  analyze.hourly_spread
93
91
 
94
- analyze.frequency :category => REQUEST_CATEGORIZER, :title => 'Most requested'
95
- analyze.frequency :method, :title => 'HTTP methods'
96
- analyze.frequency :status, :title => 'HTTP statuses returned'
92
+ analyze.frequency category: REQUEST_CATEGORIZER, title: 'Most requested'
93
+ analyze.frequency :method, title: 'HTTP methods'
94
+ analyze.frequency :status, title: 'HTTP statuses returned'
97
95
 
98
- analyze.duration :duration, :category => REQUEST_CATEGORIZER, :title => "Request duration", :line_type => :completed
99
- analyze.duration :partial_duration, :category => :rendered_file, :title => 'Partials rendering time', :line_type => :rendered
100
- analyze.duration :view, :category => REQUEST_CATEGORIZER, :title => "View rendering time", :line_type => :completed
101
- analyze.duration :db, :category => REQUEST_CATEGORIZER, :title => "Database time", :line_type => :completed
96
+ analyze.duration :duration, category: REQUEST_CATEGORIZER, title: 'Request duration', line_type: :completed
97
+ analyze.duration :partial_duration, category: :rendered_file, title: 'Partials rendering time', line_type: :rendered
98
+ analyze.duration :view, category: REQUEST_CATEGORIZER, title: 'View rendering time', line_type: :completed
99
+ analyze.duration :db, category: REQUEST_CATEGORIZER, title: 'Database time', line_type: :completed
102
100
 
103
- analyze.frequency :category => REQUEST_CATEGORIZER, :title => 'Process blockers (> 1 sec duration)',
104
- :if => lambda { |request| request[:duration] && request[:duration] > 1.0 }
101
+ analyze.frequency category: REQUEST_CATEGORIZER, title: 'Process blockers (> 1 sec duration)',
102
+ if: lambda { |request| request[:duration] && request[:duration] > 1.0 }
105
103
 
106
- analyze.frequency :category => lambda{|x| "[#{x[:missing_resource_method]}] #{x[:missing_resource]}"},
107
- :title => "Routing Errors", :if => lambda{ |request| !request[:missing_resource].nil? }
104
+ analyze.frequency category: lambda { |x| "[#{x[:missing_resource_method]}] #{x[:missing_resource]}" },
105
+ title: 'Routing Errors', if: lambda { |request| !request[:missing_resource].nil? }
108
106
  end
109
107
 
110
108
  class Request < RequestLogAnalyzer::Request
111
109
  # Used to handle conversion of abbrev. month name to a digit
112
110
  MONTHS = %w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
113
111
 
114
- def convert_timestamp(value, definition)
112
+ def convert_timestamp(value, _definition)
115
113
  # the time value can be in 2 formats:
116
114
  # - 2010-10-26 02:27:15 +0000 (ruby 1.9.2)
117
115
  # - Thu Oct 25 16:15:18 -0800 2010
118
116
  if value =~ /^#{CommonRegularExpressions::TIMESTAMP_PARTS['Y']}/
119
- value.gsub!(/\W/,'')
117
+ value.gsub!(/\W/, '')
120
118
  value[0..13].to_i
121
119
  else
122
- value.gsub!(/\W/,'')
120
+ value.gsub!(/\W/, '')
123
121
  time_as_str = value[-4..-1] # year
124
122
  # convert the month to a 2-digit representation
125
- month = MONTHS.index(value[3..5])+1
123
+ month = MONTHS.index(value[3..5]) + 1
126
124
  month < 10 ? time_as_str << "0#{month}" : time_as_str << month.to_s
127
125
 
128
126
  time_as_str << value[6..13] # day of month + time
129
127
  time_as_str.to_i
130
128
  end
131
-
132
129
  end
133
130
  end
134
-
135
131
  end
136
132
  end
@@ -1,5 +1,4 @@
1
1
  module RequestLogAnalyzer::FileFormat
2
-
3
2
  # The RailsDevelopment FileFormat is an extention to the default Rails file format. It includes
4
3
  # all lines of the normal Rails file format, but parses SQL queries and partial rendering lines
5
4
  # as well.