scout_apm 1.6.8 → 2.0.0.pre
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.
- checksums.yaml +4 -4
- data/.gitignore +8 -1
- data/CHANGELOG.markdown +7 -57
- data/ext/allocations/allocations.c +84 -0
- data/ext/allocations/extconf.rb +3 -0
- data/lib/scout_apm/agent/reporting.rb +9 -32
- data/lib/scout_apm/agent.rb +45 -31
- data/lib/scout_apm/app_server_load.rb +1 -2
- data/lib/scout_apm/attribute_arranger.rb +0 -4
- data/lib/scout_apm/background_worker.rb +6 -9
- data/lib/scout_apm/bucket_name_splitter.rb +3 -3
- data/lib/scout_apm/call_set.rb +1 -0
- data/lib/scout_apm/config.rb +110 -66
- data/lib/scout_apm/environment.rb +16 -10
- data/lib/scout_apm/framework_integrations/rails_2.rb +12 -14
- data/lib/scout_apm/framework_integrations/rails_3_or_4.rb +5 -17
- data/lib/scout_apm/framework_integrations/ruby.rb +0 -4
- data/lib/scout_apm/framework_integrations/sinatra.rb +0 -4
- data/lib/scout_apm/histogram.rb +0 -20
- data/lib/scout_apm/instruments/action_controller_rails_3_rails4.rb +1 -4
- data/lib/scout_apm/instruments/active_record.rb +149 -8
- data/lib/scout_apm/instruments/mongoid.rb +5 -78
- data/lib/scout_apm/instruments/process/process_cpu.rb +0 -12
- data/lib/scout_apm/instruments/process/process_memory.rb +14 -43
- data/lib/scout_apm/layaway.rb +34 -134
- data/lib/scout_apm/layaway_file.rb +50 -27
- data/lib/scout_apm/layer.rb +45 -1
- data/lib/scout_apm/layer_converters/allocation_metric_converter.rb +17 -0
- data/lib/scout_apm/layer_converters/converter_base.rb +4 -6
- data/lib/scout_apm/layer_converters/job_converter.rb +1 -0
- data/lib/scout_apm/layer_converters/metric_converter.rb +2 -1
- data/lib/scout_apm/layer_converters/slow_job_converter.rb +42 -21
- data/lib/scout_apm/layer_converters/slow_request_converter.rb +58 -37
- data/lib/scout_apm/metric_meta.rb +1 -5
- data/lib/scout_apm/metric_set.rb +6 -15
- data/lib/scout_apm/reporter.rb +4 -6
- data/lib/scout_apm/serializers/metrics_to_json_serializer.rb +5 -1
- data/lib/scout_apm/serializers/payload_serializer_to_json.rb +1 -3
- data/lib/scout_apm/serializers/slow_jobs_serializer_to_json.rb +5 -3
- data/lib/scout_apm/slow_job_policy.rb +19 -89
- data/lib/scout_apm/slow_job_record.rb +12 -20
- data/lib/scout_apm/slow_request_policy.rb +12 -80
- data/lib/scout_apm/slow_transaction.rb +16 -20
- data/lib/scout_apm/stackprof_tree_collapser.rb +103 -0
- data/lib/scout_apm/store.rb +16 -78
- data/lib/scout_apm/tracked_request.rb +53 -36
- data/lib/scout_apm/utils/active_record_metric_name.rb +2 -0
- data/lib/scout_apm/utils/fake_stack_prof.rb +40 -0
- data/lib/scout_apm/utils/klass_helper.rb +26 -0
- data/lib/scout_apm/utils/sql_sanitizer.rb +1 -1
- data/lib/scout_apm/utils/sql_sanitizer_regex.rb +2 -2
- data/lib/scout_apm/utils/sql_sanitizer_regex_1_8_7.rb +2 -2
- data/lib/scout_apm/version.rb +1 -1
- data/lib/scout_apm.rb +13 -7
- data/scout_apm.gemspec +3 -1
- data/test/test_helper.rb +3 -4
- data/test/unit/layaway_test.rb +8 -5
- data/test/unit/serializers/payload_serializer_test.rb +2 -2
- data/test/unit/slow_item_set_test.rb +1 -2
- data/test/unit/sql_sanitizer_test.rb +0 -6
- metadata +28 -20
- data/LICENSE.md +0 -27
- data/lib/scout_apm/instruments/grape.rb +0 -69
- data/lib/scout_apm/instruments/percentile_sampler.rb +0 -37
- data/lib/scout_apm/request_histograms.rb +0 -46
- data/lib/scout_apm/scored_item_set.rb +0 -79
- data/test/unit/metric_set_test.rb +0 -101
- data/test/unit/scored_item_set_test.rb +0 -65
- data/test/unit/slow_request_policy_test.rb +0 -42
@@ -1,101 +0,0 @@
|
|
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
|
@@ -1,65 +0,0 @@
|
|
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
|
@@ -1,42 +0,0 @@
|
|
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
|