scout_apm 2.0.0.pre → 2.0.0.pre2

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.markdown +22 -5
  4. data/Rakefile +5 -0
  5. data/lib/scout_apm.rb +4 -0
  6. data/lib/scout_apm/agent.rb +22 -8
  7. data/lib/scout_apm/agent/reporting.rb +8 -3
  8. data/lib/scout_apm/attribute_arranger.rb +4 -0
  9. data/lib/scout_apm/bucket_name_splitter.rb +3 -3
  10. data/lib/scout_apm/config.rb +5 -2
  11. data/lib/scout_apm/histogram.rb +20 -0
  12. data/lib/scout_apm/instant_reporting.rb +40 -0
  13. data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +11 -1
  14. data/lib/scout_apm/instruments/percentile_sampler.rb +38 -0
  15. data/lib/scout_apm/layaway.rb +1 -4
  16. data/lib/scout_apm/layaway_file.rb +26 -2
  17. data/lib/scout_apm/layer.rb +1 -1
  18. data/lib/scout_apm/layer_converters/converter_base.rb +6 -4
  19. data/lib/scout_apm/layer_converters/slow_job_converter.rb +21 -13
  20. data/lib/scout_apm/layer_converters/slow_request_converter.rb +37 -24
  21. data/lib/scout_apm/metric_meta.rb +5 -1
  22. data/lib/scout_apm/metric_set.rb +15 -6
  23. data/lib/scout_apm/reporter.rb +9 -3
  24. data/lib/scout_apm/request_histograms.rb +46 -0
  25. data/lib/scout_apm/scored_item_set.rb +79 -0
  26. data/lib/scout_apm/serializers/payload_serializer_to_json.rb +2 -0
  27. data/lib/scout_apm/serializers/slow_jobs_serializer_to_json.rb +2 -0
  28. data/lib/scout_apm/slow_job_policy.rb +89 -19
  29. data/lib/scout_apm/slow_job_record.rb +18 -1
  30. data/lib/scout_apm/slow_request_policy.rb +80 -12
  31. data/lib/scout_apm/slow_transaction.rb +22 -3
  32. data/lib/scout_apm/store.rb +35 -13
  33. data/lib/scout_apm/tracked_request.rb +63 -11
  34. data/lib/scout_apm/utils/backtrace_parser.rb +4 -4
  35. data/lib/scout_apm/utils/sql_sanitizer.rb +1 -1
  36. data/lib/scout_apm/utils/sql_sanitizer_regex.rb +2 -2
  37. data/lib/scout_apm/utils/sql_sanitizer_regex_1_8_7.rb +2 -2
  38. data/lib/scout_apm/version.rb +1 -1
  39. data/scout_apm.gemspec +1 -0
  40. data/test/test_helper.rb +4 -3
  41. data/test/unit/layaway_test.rb +5 -8
  42. data/test/unit/metric_set_test.rb +101 -0
  43. data/test/unit/scored_item_set_test.rb +65 -0
  44. data/test/unit/serializers/payload_serializer_test.rb +2 -1
  45. data/test/unit/slow_item_set_test.rb +2 -1
  46. data/test/unit/slow_request_policy_test.rb +42 -0
  47. data/test/unit/sql_sanitizer_test.rb +6 -0
  48. metadata +28 -3
@@ -75,7 +75,7 @@ module ScoutApm
75
75
  end
76
76
 
77
77
  def scrubbed(str)
78
- return '' if !str.is_a?(String) || str.length > 1000 # safeguard - don't sanitize or scrub large SQL statements
78
+ return '' if !str.is_a?(String) || str.length > 4000 # safeguard - don't sanitize or scrub large SQL statements
79
79
  return str if !str.respond_to?(:encode) # Ruby <= 1.8 doesn't have string encoding
80
80
  return str if str.valid_encoding? # Whatever encoding it is, it is valid and we can operate on it
81
81
  ScoutApm::Agent.instance.logger.debug "Scrubbing invalid sql encoding."
@@ -13,8 +13,8 @@ module ScoutApm
13
13
 
14
14
  MYSQL_VAR_INTERPOLATION = %r|\[\[.*\]\]\s*$|.freeze
15
15
  MYSQL_REMOVE_INTEGERS = /(?<!LIMIT )\b\d+\b/.freeze
16
- MYSQL_REMOVE_SINGLE_QUOTE_STRINGS = /'(?:[^']|'')*'/.freeze
17
- MYSQL_REMOVE_DOUBLE_QUOTE_STRINGS = /"(?:[^"]|"")*"/.freeze
16
+ MYSQL_REMOVE_SINGLE_QUOTE_STRINGS = %r{'(?:\\'|[^']|'')*'}.freeze
17
+ MYSQL_REMOVE_DOUBLE_QUOTE_STRINGS = %r{"(?:\\"|[^"]|"")*"}.freeze
18
18
  MYSQL_IN_CLAUSE = /IN\s+\(\?[^\)]*\)/.freeze
19
19
 
20
20
  SQLITE_VAR_INTERPOLATION = %r|\[\[.*\]\]\s*$|.freeze
@@ -13,8 +13,8 @@ module ScoutApm
13
13
 
14
14
  MYSQL_VAR_INTERPOLATION = %r|\[\[.*\]\]\s*$|.freeze
15
15
  MYSQL_REMOVE_INTEGERS = /\b\d+\b/.freeze
16
- MYSQL_REMOVE_SINGLE_QUOTE_STRINGS = /'(?:[^']|'')*'/.freeze
17
- MYSQL_REMOVE_DOUBLE_QUOTE_STRINGS = /"(?:[^"]|"")*"/.freeze
16
+ MYSQL_REMOVE_SINGLE_QUOTE_STRINGS = /'(?:\\'|[^']|'')*'/.freeze
17
+ MYSQL_REMOVE_DOUBLE_QUOTE_STRINGS = /"(?:\\"|[^"]|"")*"/.freeze
18
18
  MYSQL_IN_CLAUSE = /IN\s+\(\?[^\)]*\)/.freeze
19
19
 
20
20
  SQLITE_VAR_INTERPOLATION = %r|\[\[.*\]\]\s*$|.freeze
@@ -1,4 +1,4 @@
1
1
  module ScoutApm
2
- VERSION = "2.0.0.pre"
2
+ VERSION = "2.0.0.pre2"
3
3
  end
4
4
 
@@ -25,4 +25,5 @@ Gem::Specification.new do |s|
25
25
  s.add_development_dependency "pry"
26
26
  s.add_development_dependency "m"
27
27
  s.add_development_dependency "simplecov"
28
+ s.add_development_dependency "rake-compiler"
28
29
  end
@@ -1,11 +1,12 @@
1
+ # Load & Start simplecov before loading scout_apm
2
+ require 'simplecov'
3
+ SimpleCov.start
4
+
1
5
  require 'minitest/autorun'
2
6
  require 'minitest/unit'
3
7
  require 'minitest/pride'
4
8
  require 'pry'
5
9
 
6
- # Load & Start simplecov before loading scout_apm
7
- require 'simplecov'
8
- SimpleCov.start
9
10
 
10
11
  require 'scout_apm'
11
12
 
@@ -18,15 +18,12 @@ class LayawayTest < Minitest::Test
18
18
 
19
19
  def test_merge_reporting_period
20
20
  File.open(DATA_FILE_PATH, 'w') { |file| file.write(Marshal.dump(NEW_FORMAT)) }
21
- ScoutApm::Agent.instance.start
22
-
23
- data = ScoutApm::Layaway.new
24
- t = ScoutApm::StoreReportingPeriodTimestamp.new
25
- data.add_reporting_period(TIMESTAMP,ScoutApm::StoreReportingPeriod.new(TIMESTAMP))
26
- assert_equal [TIMESTAMP], Marshal.load(File.read(DATA_FILE_PATH)).keys
27
- # TODO - add tests to verify metrics+slow transactions are merged
21
+ layaway = ScoutApm::Layaway.new
22
+ layaway.add_reporting_period(TIMESTAMP, ScoutApm::StoreReportingPeriod.new(TIMESTAMP))
23
+ unmarshalled = Marshal.load(File.read(DATA_FILE_PATH))
24
+ assert_equal [TIMESTAMP], unmarshalled.keys
28
25
  end
29
26
 
30
27
  TIMESTAMP = ScoutApm::StoreReportingPeriodTimestamp.new(Time.parse("2015-01-01"))
31
28
  NEW_FORMAT = {TIMESTAMP => ScoutApm::StoreReportingPeriod.new(TIMESTAMP)} # Format for 1.2+ agents
32
- end
29
+ end
@@ -0,0 +1,101 @@
1
+ require 'test_helper'
2
+
3
+ require 'scout_apm/metric_set'
4
+
5
+ module ScoutApm
6
+ class MetricSetTest < Minitest::Test
7
+ def setup
8
+ @metric_set = ScoutApm::MetricSet.new
9
+ end
10
+
11
+ def test_absorb_one_passthrough_metric
12
+ @metric_set.absorb(make_fake_stat("Controller/Foo", 1))
13
+
14
+ assert_equal 1, @metric_set.metrics.length
15
+ assert_equal "Controller/Foo", @metric_set.metrics.first.first.metric_name
16
+ end
17
+
18
+ def test_absorb_one_aggregate_metric
19
+ @metric_set.absorb(make_fake_stat("ActiveRecord/Foo", 1))
20
+
21
+ assert_equal 1, @metric_set.metrics.length
22
+ assert_equal "ActiveRecord/all", @metric_set.metrics.first.first.metric_name
23
+ end
24
+
25
+ def test_absorb_many_aggregate_metric
26
+ @metric_set.absorb(make_fake_stat("ActiveRecord/Foo", 1))
27
+ @metric_set.absorb(make_fake_stat("ActiveRecord/Bar", 1))
28
+ @metric_set.absorb(make_fake_stat("ActiveRecord/Baz", 1))
29
+ @metric_set.absorb(make_fake_stat("HTTP/Get", 1))
30
+ @metric_set.absorb(make_fake_stat("HTTP/Post", 1))
31
+
32
+ metrics = @metric_set.metrics.to_a.sort_by { |m| m.first.metric_name }
33
+ assert_equal 2, metrics.length
34
+ assert_equal "ActiveRecord/all", metrics[0][0].metric_name
35
+ assert_equal "HTTP/all", metrics[1][0].metric_name
36
+ assert_equal 3, metrics[0][1].call_count
37
+ assert_equal 2, metrics[1][1].call_count
38
+ end
39
+
40
+ def test_absorb_one_error
41
+ @metric_set.absorb(make_fake_stat("Errors/Controller/public/index", 1))
42
+
43
+ metrics = @metric_set.metrics.to_a.sort_by { |m| m.first.metric_name }
44
+ assert_equal 2, metrics.length
45
+ assert_equal "Errors/Controller/public/index", metrics[0].first.metric_name
46
+ assert_equal "Errors/Request", metrics[1].first.metric_name
47
+ end
48
+
49
+ def test_absorb_many_metrics
50
+ @metric_set.absorb_all([
51
+ make_fake_stat("ActiveRecord/Foo", 1),
52
+ make_fake_stat("Controller/Bar", 1)
53
+ ])
54
+
55
+ metrics = @metric_set.metrics.to_a.sort_by { |m| m.first.metric_name }
56
+ assert_equal 2, metrics.length
57
+ assert_equal "ActiveRecord/all", metrics[0].first.metric_name
58
+ assert_equal "Controller/Bar", metrics[1].first.metric_name
59
+ end
60
+
61
+ def test_combine
62
+ @other_set = ScoutApm::MetricSet.new
63
+
64
+ @metric_set.absorb_all([
65
+ make_fake_stat("ActiveRecord/Foo", 1),
66
+ make_fake_stat("Controller/Bar", 1),
67
+ make_fake_stat("Errors/Controller/public/index", 1),
68
+ ])
69
+
70
+ @other_set.absorb_all([
71
+ make_fake_stat("ActiveRecord/Foo", 1),
72
+ make_fake_stat("Controller/Bar", 1),
73
+ make_fake_stat("Errors/Controller/public/index", 1),
74
+ ])
75
+
76
+ @metric_set.combine!(@other_set)
77
+
78
+ metrics = @metric_set.metrics.to_a.sort_by { |m| m.first.metric_name }
79
+ assert_equal 4, metrics.length
80
+ assert_equal "ActiveRecord/all", metrics[0][0].metric_name
81
+ assert_equal "Controller/Bar", metrics[1][0].metric_name
82
+ assert_equal "Errors/Controller/public/index", metrics[2][0].metric_name
83
+ assert_equal "Errors/Request", metrics[3][0].metric_name
84
+
85
+ assert_equal 2, metrics[0][1].call_count
86
+ assert_equal 2, metrics[1][1].call_count
87
+ assert_equal 2, metrics[2][1].call_count
88
+ assert_equal 2, metrics[3][1].call_count
89
+ end
90
+
91
+ ############################################################
92
+ # Test helper functions
93
+ ############################################################
94
+ def make_fake_stat(name, count)
95
+ meta = MetricMeta.new(name)
96
+ stat = MetricStats.new
97
+ stat.update!(count)
98
+ [meta, stat]
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,65 @@
1
+ require 'test_helper'
2
+
3
+ require 'scout_apm/scored_item_set'
4
+
5
+ class FakeScoredItem
6
+ def initialize(name, score)
7
+ @name = name
8
+ @score = score
9
+ end
10
+ def name; @name; end
11
+ def score; @score; end
12
+ def call; "called_#{@score}_#{@name}"; end
13
+ end
14
+
15
+ class ScoredItemSetTest < Minitest::Test
16
+ def test_empty_set_always_adds_item
17
+ set = ScoutApm::ScoredItemSet.new
18
+ set << FakeScoredItem.new("users/index", 10)
19
+
20
+ assert_equal set.to_a.first, "called_10_users/index"
21
+ assert_equal set.count, 1
22
+ end
23
+
24
+ def test_repeated_additions_chooses_most_expensive
25
+ set = ScoutApm::ScoredItemSet.new
26
+
27
+ [ FakeScoredItem.new("users/index", 10),
28
+ FakeScoredItem.new("users/index", 11),
29
+ FakeScoredItem.new("users/index", 12)
30
+ ].shuffle.each { |fsi| set << fsi }
31
+
32
+ assert_equal set.to_a.first, "called_12_users/index"
33
+ assert_equal set.count, 1
34
+ end
35
+
36
+ def test_multiple_items_occupy_different_buckets
37
+ set = ScoutApm::ScoredItemSet.new
38
+
39
+ [ FakeScoredItem.new("users/index", 10),
40
+ FakeScoredItem.new("users/index", 11),
41
+ FakeScoredItem.new("users/show", 12),
42
+ FakeScoredItem.new("users/show", 10)
43
+ ].shuffle.each { |fsi| set << fsi }
44
+
45
+ assert_equal set.count, 2
46
+ assert set.to_a.include?("called_11_users/index")
47
+ assert set.to_a.include?("called_12_users/show")
48
+ end
49
+
50
+ def test_evicts_at_capacity
51
+ set = ScoutApm::ScoredItemSet.new(3) # Force max_size to 3
52
+
53
+ [ FakeScoredItem.new("users/index", 10),
54
+ FakeScoredItem.new("users/show", 11),
55
+ FakeScoredItem.new("posts/index", 12),
56
+ FakeScoredItem.new("posts/move", 13)
57
+ ].shuffle.each { |fsi| set << fsi }
58
+
59
+ assert_equal set.count, 3
60
+ assert !set.to_a.include?("called_10_users/index"), "Did not Expect to see users/index in #{set.to_a.inspect}"
61
+ assert set.to_a.include?("called_11_users/show"), "Expected to see users/show in #{set.to_a.inspect}"
62
+ assert set.to_a.include?("called_12_posts/index"), "Expected to see posts/index in #{set.to_a.inspect}"
63
+ assert set.to_a.include?("called_13_posts/move"), "Expected to see posts/move in #{set.to_a.inspect}"
64
+ end
65
+ end
@@ -145,7 +145,7 @@ class PayloadSerializerTest < Minitest::Test
145
145
  context = ScoutApm::Context.new
146
146
  context.add({"this" => "that"})
147
147
  context.add_user({"hello" => "goodbye"})
148
- slow_t = ScoutApm::SlowTransaction.new("http://example.com/blabla", "Buckethead/something/else", 1.23, slow_transaction_metrics, context, Time.at(1448198788), [])
148
+ slow_t = ScoutApm::SlowTransaction.new("http://example.com/blabla", "Buckethead/something/else", 1.23, slow_transaction_metrics, context, Time.at(1448198788), [], 10)
149
149
  payload = ScoutApm::Serializers::PayloadSerializerToJson.serialize({}, {}, [slow_t], [], [])
150
150
  formatted_slow_transactions = [
151
151
  {
@@ -158,6 +158,7 @@ class PayloadSerializerTest < Minitest::Test
158
158
  "uri" => "http://example.com/blabla",
159
159
  "context" => {"this"=>"that", "user"=>{"hello"=>"goodbye"}},
160
160
  "prof" => [],
161
+ "score" => 10,
161
162
  "metrics" => [
162
163
  {
163
164
  "key" => {
@@ -88,6 +88,7 @@ class SlowItemSetTest < Minitest::Test
88
88
  {}, # metrics
89
89
  {}, # context
90
90
  Time.now, # end time
91
- []) # stackprof
91
+ [], # stackprof
92
+ 0)
92
93
  end
93
94
  end
@@ -0,0 +1,42 @@
1
+ require 'test_helper'
2
+
3
+ require 'scout_apm/slow_request_policy'
4
+ require 'scout_apm/layer'
5
+
6
+ class FakeRequest
7
+ def initialize(name)
8
+ @name = name
9
+ @root_layer = ScoutApm::Layer.new("Controller", name)
10
+ @root_layer.instance_variable_set("@stop_time", Time.now)
11
+ end
12
+ def unique_name; "Controller/foo/bar"; end
13
+ def root_layer; @root_layer; end
14
+ def set_duration(seconds)
15
+ @root_layer.instance_variable_set("@start_time", Time.now - seconds)
16
+ end
17
+ end
18
+
19
+ class SlowRequestPolicyTest < Minitest::Test
20
+ def test_stored_records_current_time
21
+ test_start = Time.now
22
+ policy = ScoutApm::SlowRequestPolicy.new
23
+ request = FakeRequest.new("users/index")
24
+
25
+ policy.stored!(request)
26
+ assert policy.last_seen[request.unique_name] > test_start
27
+ end
28
+
29
+ def test_score
30
+ policy = ScoutApm::SlowRequestPolicy.new
31
+ request = FakeRequest.new("users/index")
32
+
33
+ request.set_duration(10) # 10 seconds
34
+ policy.last_seen[request.unique_name] = Time.now - 120 # 2 minutes since last seen
35
+ agent.request_histograms.add(request.unique_name, 1)
36
+
37
+ # Actual value I have in console is 1.599
38
+ assert policy.score(request) > 1.5
39
+ assert policy.score(request) < 2.0
40
+
41
+ end
42
+ end
@@ -85,6 +85,12 @@ module ScoutApm
85
85
  assert_equal %q|SELECT `blogs`.* FROM `blogs` WHERE (title = ?)|, ss.to_s
86
86
  end
87
87
 
88
+ def test_mysql_quotes
89
+ sql = %q|INSERT INTO `users` VALUES ('foo', 'b\'ar')|
90
+ ss = SqlSanitizer.new(sql).tap{ |it| it.database_engine = :mysql }
91
+ assert_equal %q|INSERT INTO `users` VALUES (?, ?)|, ss.to_s
92
+ end
93
+
88
94
  def test_scrubs_invalid_encoding
89
95
  sql = "SELECT `blogs`.* FROM `blogs` WHERE (title = 'a\255c')".force_encoding('UTF-8')
90
96
  assert_equal false, sql.valid_encoding?
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scout_apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre
4
+ version: 2.0.0.pre2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek Haynes
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-05-10 00:00:00.000000000 Z
12
+ date: 2016-06-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rusage
@@ -81,6 +81,20 @@ dependencies:
81
81
  - - ">="
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rake-compiler
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
84
98
  description: Monitors Ruby apps and reports detailed metrics on performance to Scout.
85
99
  email:
86
100
  - support@scoutapp.com
@@ -121,6 +135,7 @@ files:
121
135
  - lib/scout_apm/framework_integrations/ruby.rb
122
136
  - lib/scout_apm/framework_integrations/sinatra.rb
123
137
  - lib/scout_apm/histogram.rb
138
+ - lib/scout_apm/instant_reporting.rb
124
139
  - lib/scout_apm/instruments/.DS_Store
125
140
  - lib/scout_apm/instruments/action_controller_rails_2.rb
126
141
  - lib/scout_apm/instruments/action_controller_rails_3_rails4.rb
@@ -134,6 +149,7 @@ files:
134
149
  - lib/scout_apm/instruments/mongoid.rb
135
150
  - lib/scout_apm/instruments/moped.rb
136
151
  - lib/scout_apm/instruments/net_http.rb
152
+ - lib/scout_apm/instruments/percentile_sampler.rb
137
153
  - lib/scout_apm/instruments/process/process_cpu.rb
138
154
  - lib/scout_apm/instruments/process/process_memory.rb
139
155
  - lib/scout_apm/instruments/rails_router.rb
@@ -160,7 +176,9 @@ files:
160
176
  - lib/scout_apm/platform_integrations/heroku.rb
161
177
  - lib/scout_apm/platform_integrations/server.rb
162
178
  - lib/scout_apm/reporter.rb
179
+ - lib/scout_apm/request_histograms.rb
163
180
  - lib/scout_apm/request_manager.rb
181
+ - lib/scout_apm/scored_item_set.rb
164
182
  - lib/scout_apm/serializers/app_server_load_serializer.rb
165
183
  - lib/scout_apm/serializers/deploy_serializer.rb
166
184
  - lib/scout_apm/serializers/directive_serializer.rb
@@ -207,9 +225,12 @@ files:
207
225
  - test/unit/histogram_test.rb
208
226
  - test/unit/instruments/active_record_instruments_test.rb
209
227
  - test/unit/layaway_test.rb
228
+ - test/unit/metric_set_test.rb
229
+ - test/unit/scored_item_set_test.rb
210
230
  - test/unit/serializers/payload_serializer_test.rb
211
231
  - test/unit/slow_item_set_test.rb
212
232
  - test/unit/slow_job_policy_test.rb
233
+ - test/unit/slow_request_policy_test.rb
213
234
  - test/unit/sql_sanitizer_test.rb
214
235
  - test/unit/utils/active_record_metric_name_test.rb
215
236
  homepage: https://github.com/scoutapp/scout_apm_ruby
@@ -232,7 +253,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
232
253
  version: 1.3.1
233
254
  requirements: []
234
255
  rubyforge_project: scout_apm
235
- rubygems_version: 2.4.6
256
+ rubygems_version: 2.6.2
236
257
  signing_key:
237
258
  specification_version: 4
238
259
  summary: Ruby application performance monitoring
@@ -245,8 +266,12 @@ test_files:
245
266
  - test/unit/histogram_test.rb
246
267
  - test/unit/instruments/active_record_instruments_test.rb
247
268
  - test/unit/layaway_test.rb
269
+ - test/unit/metric_set_test.rb
270
+ - test/unit/scored_item_set_test.rb
248
271
  - test/unit/serializers/payload_serializer_test.rb
249
272
  - test/unit/slow_item_set_test.rb
250
273
  - test/unit/slow_job_policy_test.rb
274
+ - test/unit/slow_request_policy_test.rb
251
275
  - test/unit/sql_sanitizer_test.rb
252
276
  - test/unit/utils/active_record_metric_name_test.rb
277
+ has_rdoc: