scout_apm 1.6.8 → 2.0.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- 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
|