scout_apm 2.4.12 → 2.4.13
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/CHANGELOG.markdown +4 -0
- data/lib/scout_apm/agent_context.rb +4 -0
- data/lib/scout_apm/config.rb +4 -0
- data/lib/scout_apm/slow_job_policy.rb +18 -1
- data/lib/scout_apm/slow_request_policy.rb +18 -1
- data/lib/scout_apm/store.rb +2 -2
- data/lib/scout_apm/tracked_request.rb +2 -0
- data/lib/scout_apm/transaction_time_consumed.rb +51 -0
- data/lib/scout_apm/version.rb +1 -1
- data/lib/scout_apm.rb +1 -0
- data/test/unit/extensions/periodic_callbacks_test.rb +2 -2
- data/test/unit/slow_request_policy_test.rb +8 -3
- data/test/unit/transaction_time_consumed_test.rb +46 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ec07b46e556c0beae2648d2c25a610199814179
|
4
|
+
data.tar.gz: ed6284b5c6a58a7ab08a464eb6e60cb65334d12f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15c5a89d33a1af9e605a03390b9344cfad0ceefbb18a3afe6800c4afb3797bca60af57d15ef0323165e344d55454877d15e8455f12e3ba5fd15bf3c3eaf01867
|
7
|
+
data.tar.gz: 1caf6345c5900c54a493aa87bd95168fa5733ae91a7b73211094045b0437c707e6e755286481d89514f43dca1a8a2e31f3a8eeb5dec8cbbabdfebbfb8aed52ac
|
data/CHANGELOG.markdown
CHANGED
@@ -114,6 +114,10 @@ module ScoutApm
|
|
114
114
|
@request_histograms_by_time ||= Hash.new { |h, k| h[k] = ScoutApm::RequestHistograms.new }
|
115
115
|
end
|
116
116
|
|
117
|
+
def transaction_time_consumed
|
118
|
+
@transaction_time_consumed ||= ScoutApm::TransactionTimeConsumed.new
|
119
|
+
end
|
120
|
+
|
117
121
|
def store
|
118
122
|
return @store if @store
|
119
123
|
self.store = ScoutApm::Store.new(self)
|
data/lib/scout_apm/config.rb
CHANGED
@@ -20,6 +20,7 @@ require 'scout_apm/environment'
|
|
20
20
|
# key - the account key with Scout APM. Found in Settings in the Web UI
|
21
21
|
# log_file_path - either a directory or "STDOUT".
|
22
22
|
# log_level - DEBUG / INFO / WARN as usual
|
23
|
+
# max_traces - Internal: An experiment in trace quality, this requires a server-side setting as well. Setting this to a higher value will make your app server work harder for no benefit.
|
23
24
|
# monitor - true or false. False prevents any instrumentation from starting
|
24
25
|
# name - override the name reported to APM. This is the name that shows in the Web UI
|
25
26
|
# profile - turn on/off scoutprof (only applicable in Gem versions including scoutprof)
|
@@ -57,6 +58,7 @@ module ScoutApm
|
|
57
58
|
'log_level',
|
58
59
|
'log_stderr',
|
59
60
|
'log_stdout',
|
61
|
+
'max_traces',
|
60
62
|
'monitor',
|
61
63
|
'name',
|
62
64
|
'profile',
|
@@ -151,6 +153,7 @@ module ScoutApm
|
|
151
153
|
"dev_trace" => BooleanCoercion.new,
|
152
154
|
"enable_background_jobs" => BooleanCoercion.new,
|
153
155
|
"ignore" => JsonCoercion.new,
|
156
|
+
"max_traces" => IntegerCoercion.new,
|
154
157
|
"monitor" => BooleanCoercion.new,
|
155
158
|
'database_metric_limit' => IntegerCoercion.new,
|
156
159
|
'database_metric_report_limit' => IntegerCoercion.new,
|
@@ -250,6 +253,7 @@ module ScoutApm
|
|
250
253
|
'host' => 'https://checkin.scoutapp.com',
|
251
254
|
'ignore' => [],
|
252
255
|
'log_level' => 'info',
|
256
|
+
'max_traces' => 10,
|
253
257
|
'profile' => true, # for scoutprof
|
254
258
|
'report_format' => 'json',
|
255
259
|
'scm_subdirectory' => '',
|
@@ -17,6 +17,10 @@ module ScoutApm
|
|
17
17
|
# Outliers are worth up to "1000ms" of weight
|
18
18
|
POINT_MULTIPLIER_PERCENTILE = 1.0
|
19
19
|
|
20
|
+
# Points for an endpoint's who's throughput * response time is a large % of
|
21
|
+
# overall time spent processing requests
|
22
|
+
POINT_MULTIPLIER_PERCENT_TIME = 2.5
|
23
|
+
|
20
24
|
# A hash of Job Names to the last time we stored a slow trace for it.
|
21
25
|
#
|
22
26
|
# Defaults to a start time that is pretty close to application boot time.
|
@@ -60,7 +64,9 @@ module ScoutApm
|
|
60
64
|
# What approximate percentile was this request?
|
61
65
|
percentile = context.request_histograms.approximate_quantile_of_value(unique_name, total_time)
|
62
66
|
|
63
|
-
|
67
|
+
percent_of_total_time = context.transaction_time_consumed.percent_of_total(unique_name)
|
68
|
+
|
69
|
+
return speed_points(total_time) + percentile_points(percentile) + age_points(age) + percent_time_points(percent_of_total_time)
|
64
70
|
end
|
65
71
|
|
66
72
|
private
|
@@ -90,5 +96,16 @@ module ScoutApm
|
|
90
96
|
def age_points(age)
|
91
97
|
age / 60.0 * POINT_MULTIPLIER_AGE
|
92
98
|
end
|
99
|
+
|
100
|
+
# Of the total time spent handling endpoints in this app, if this endpoint
|
101
|
+
# is a higher percent, it should get more points.
|
102
|
+
#
|
103
|
+
# A: 20 calls @ 100ms each => 2 seconds of total time
|
104
|
+
# B: 10 calls @ 100ms each => 1 second of total time
|
105
|
+
#
|
106
|
+
# Then A is 66% of the total call time
|
107
|
+
def percent_time_points(percent) # Scale 0.0 - 1.0
|
108
|
+
percent * POINT_MULTIPLIER_PERCENT_TIME
|
109
|
+
end
|
93
110
|
end
|
94
111
|
end
|
@@ -17,6 +17,10 @@ module ScoutApm
|
|
17
17
|
# Outliers are worth up to "1000ms" of weight
|
18
18
|
POINT_MULTIPLIER_PERCENTILE = 1.0
|
19
19
|
|
20
|
+
# Points for an endpoint's who's throughput * response time is a large % of
|
21
|
+
# overall time spent processing requests
|
22
|
+
POINT_MULTIPLIER_PERCENT_TIME = 2.5
|
23
|
+
|
20
24
|
# A hash of Endpoint Name to the last time we stored a slow transaction for it.
|
21
25
|
#
|
22
26
|
# Defaults to a start time that is pretty close to application boot time.
|
@@ -60,7 +64,9 @@ module ScoutApm
|
|
60
64
|
# What approximate percentile was this request?
|
61
65
|
percentile = context.request_histograms.approximate_quantile_of_value(unique_name, total_time)
|
62
66
|
|
63
|
-
|
67
|
+
percent_of_total_time = context.transaction_time_consumed.percent_of_total(unique_name)
|
68
|
+
|
69
|
+
return speed_points(total_time) + percentile_points(percentile) + age_points(age) + percent_time_points(percent_of_total_time)
|
64
70
|
end
|
65
71
|
|
66
72
|
private
|
@@ -90,5 +96,16 @@ module ScoutApm
|
|
90
96
|
def age_points(age)
|
91
97
|
age / 60.0 * POINT_MULTIPLIER_AGE
|
92
98
|
end
|
99
|
+
|
100
|
+
# Of the total time spent handling endpoints in this app, if this endpoint
|
101
|
+
# is a higher percent, it should get more points.
|
102
|
+
#
|
103
|
+
# A: 20 calls @ 100ms each => 2 seconds of total time
|
104
|
+
# B: 10 calls @ 100ms each => 1 second of total time
|
105
|
+
#
|
106
|
+
# Then A is 66% of the total call time
|
107
|
+
def percent_time_points(percent) # Scale 0.0 - 1.0
|
108
|
+
percent * POINT_MULTIPLIER_PERCENT_TIME
|
109
|
+
end
|
93
110
|
end
|
94
111
|
end
|
data/lib/scout_apm/store.rb
CHANGED
@@ -205,8 +205,8 @@ module ScoutApm
|
|
205
205
|
def initialize(timestamp, context)
|
206
206
|
@timestamp = timestamp
|
207
207
|
|
208
|
-
@request_traces = ScoredItemSet.new
|
209
|
-
@job_traces = ScoredItemSet.new
|
208
|
+
@request_traces = ScoredItemSet.new(context.config.value('max_traces'))
|
209
|
+
@job_traces = ScoredItemSet.new(context.config.value('max_traces'))
|
210
210
|
|
211
211
|
@histograms = []
|
212
212
|
|
@@ -273,6 +273,8 @@ module ScoutApm
|
|
273
273
|
|
274
274
|
apply_name_override
|
275
275
|
|
276
|
+
@agent_context.transaction_time_consumed.add(unique_name, root_layer.total_call_time)
|
277
|
+
|
276
278
|
# Make a constant, then call converters.dup.each so it isn't inline?
|
277
279
|
converters = {
|
278
280
|
:histograms => LayerConverters::Histograms,
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module ScoutApm
|
2
|
+
class TransactionTimeConsumed
|
3
|
+
# Private Accessor:
|
4
|
+
# A hash of Endpoint Name to an time consumed record
|
5
|
+
attr_reader :endpoints
|
6
|
+
private :endpoints
|
7
|
+
|
8
|
+
# Private Accessor:
|
9
|
+
# The total time spent across all endpoints
|
10
|
+
attr_reader :total_duration
|
11
|
+
private :total_duration
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@total_duration = 0.0
|
15
|
+
@endpoints = Hash.new { |h, k| h[k] = TotalTimeRecord.new }
|
16
|
+
end
|
17
|
+
|
18
|
+
def add(item, duration)
|
19
|
+
@total_duration += duration.to_f
|
20
|
+
@endpoints[item].add(duration.to_f)
|
21
|
+
end
|
22
|
+
|
23
|
+
def percent_of_total(item)
|
24
|
+
if total_duration == 0.0
|
25
|
+
0
|
26
|
+
else
|
27
|
+
@endpoints[item].total_duration / total_duration
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def total_time_for(item)
|
32
|
+
@endpoints[item].total_duration
|
33
|
+
end
|
34
|
+
|
35
|
+
def call_count_for(item)
|
36
|
+
@endpoints[item].count
|
37
|
+
end
|
38
|
+
|
39
|
+
# Time is in seconds
|
40
|
+
TotalTimeRecord = Struct.new(:total_duration, :count) do
|
41
|
+
def initialize
|
42
|
+
super(0, 0)
|
43
|
+
end
|
44
|
+
|
45
|
+
def add(duration)
|
46
|
+
self.total_duration += duration.to_f
|
47
|
+
self.count += 1
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/scout_apm/version.rb
CHANGED
data/lib/scout_apm.rb
CHANGED
@@ -138,6 +138,7 @@ require 'scout_apm/slow_request_policy'
|
|
138
138
|
require 'scout_apm/slow_job_policy'
|
139
139
|
require 'scout_apm/job_record'
|
140
140
|
require 'scout_apm/request_histograms'
|
141
|
+
require 'scout_apm/transaction_time_consumed'
|
141
142
|
|
142
143
|
require 'scout_apm/attribute_arranger'
|
143
144
|
require 'scout_apm/git_revision'
|
@@ -38,7 +38,7 @@ class PeriodicCallbacksTest < Minitest::Test
|
|
38
38
|
private
|
39
39
|
|
40
40
|
def reporting_period
|
41
|
-
rp = ScoutApm::StoreReportingPeriod.new(
|
41
|
+
rp = ScoutApm::StoreReportingPeriod.new(Time.at(metadata[:agent_time].to_i), ScoutApm::AgentContext.new)
|
42
42
|
rp.absorb_metrics!(metrics)
|
43
43
|
end
|
44
44
|
|
@@ -55,4 +55,4 @@ class PeriodicCallbacksTest < Minitest::Test
|
|
55
55
|
{:app_root=>"/srv/rails_app", :unique_id=>"ID", :agent_version=>"2.4.10", :agent_time=>"1523287920", :agent_pid=>21581, :platform=>"ruby"}
|
56
56
|
end
|
57
57
|
|
58
|
-
end
|
58
|
+
end
|
@@ -37,9 +37,14 @@ class SlowRequestPolicyTest < Minitest::Test
|
|
37
37
|
request.set_duration(10) # 10 seconds
|
38
38
|
policy.last_seen[request.unique_name] = Time.now - 120 # 2 minutes since last seen
|
39
39
|
@context.request_histograms.add(request.unique_name, 1)
|
40
|
+
@context.transaction_time_consumed.add(request.unique_name, 1)
|
40
41
|
|
41
|
-
# Actual value I have in console is
|
42
|
-
|
43
|
-
|
42
|
+
# Actual value I have in console is 4.01
|
43
|
+
# Score uses Time.now to compare w/ last_seen, and will tick up slowly as
|
44
|
+
# time passes, hence the range below.
|
45
|
+
score = policy.score(request)
|
46
|
+
|
47
|
+
assert score > 3.95
|
48
|
+
assert score < 4.05
|
44
49
|
end
|
45
50
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'scout_apm/transaction_time_consumed'
|
4
|
+
|
5
|
+
module ScoutApm
|
6
|
+
class TransactionTimeConsumedTest < Minitest::Test
|
7
|
+
def setup
|
8
|
+
@ttc = ScoutApm::TransactionTimeConsumed.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_insert_new_times
|
12
|
+
@ttc.add("Controller/Foo", 1.5)
|
13
|
+
@ttc.add("Controller/Foo", 2.75)
|
14
|
+
assert_equal 4.25, @ttc.total_time_for("Controller/Foo")
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_insert_tracks_endpoints_separately
|
18
|
+
@ttc.add("Controller/Foo", 1.5)
|
19
|
+
@ttc.add("Controller/Foo", 2.75)
|
20
|
+
@ttc.add("Controller/Bar", 5)
|
21
|
+
@ttc.add("Controller/Bar", 5)
|
22
|
+
assert_equal 4.25, @ttc.total_time_for("Controller/Foo")
|
23
|
+
assert_equal 10.0, @ttc.total_time_for("Controller/Bar")
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_calculates_percent_of_total
|
27
|
+
@ttc.add("Controller/Foo", 1)
|
28
|
+
@ttc.add("Controller/Bar", 4)
|
29
|
+
assert_equal 0.2, @ttc.percent_of_total("Controller/Foo")
|
30
|
+
assert_equal 0.8, @ttc.percent_of_total("Controller/Bar")
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_counts_total_call_count
|
34
|
+
@ttc.add("Controller/Foo", 1)
|
35
|
+
@ttc.add("Controller/Foo", 1)
|
36
|
+
@ttc.add("Controller/Foo", 1)
|
37
|
+
@ttc.add("Controller/Bar", 4)
|
38
|
+
assert_equal 3, @ttc.call_count_for("Controller/Foo")
|
39
|
+
assert_equal 1, @ttc.call_count_for("Controller/Bar")
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_percent_of_total_is_0_with_no_data
|
43
|
+
assert_equal 0.0, @ttc.percent_of_total("Controller/Foo")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
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.4.
|
4
|
+
version: 2.4.13
|
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: 2018-06-
|
12
|
+
date: 2018-06-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -310,6 +310,7 @@ files:
|
|
310
310
|
- lib/scout_apm/tracer.rb
|
311
311
|
- lib/scout_apm/tracked_request.rb
|
312
312
|
- lib/scout_apm/transaction.rb
|
313
|
+
- lib/scout_apm/transaction_time_consumed.rb
|
313
314
|
- lib/scout_apm/utils/active_record_metric_name.rb
|
314
315
|
- lib/scout_apm/utils/backtrace_parser.rb
|
315
316
|
- lib/scout_apm/utils/gzip_helper.rb
|
@@ -363,6 +364,7 @@ files:
|
|
363
364
|
- test/unit/tracer_test.rb
|
364
365
|
- test/unit/tracked_request_test.rb
|
365
366
|
- test/unit/transaction_test.rb
|
367
|
+
- test/unit/transaction_time_consumed_test.rb
|
366
368
|
- test/unit/utils/active_record_metric_name_test.rb
|
367
369
|
- test/unit/utils/backtrace_parser_test.rb
|
368
370
|
- test/unit/utils/numbers_test.rb
|
@@ -388,7 +390,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
388
390
|
version: '0'
|
389
391
|
requirements: []
|
390
392
|
rubyforge_project: scout_apm
|
391
|
-
rubygems_version: 2.4.
|
393
|
+
rubygems_version: 2.4.6
|
392
394
|
signing_key:
|
393
395
|
specification_version: 4
|
394
396
|
summary: Ruby application performance monitoring
|
@@ -431,7 +433,9 @@ test_files:
|
|
431
433
|
- test/unit/tracer_test.rb
|
432
434
|
- test/unit/tracked_request_test.rb
|
433
435
|
- test/unit/transaction_test.rb
|
436
|
+
- test/unit/transaction_time_consumed_test.rb
|
434
437
|
- test/unit/utils/active_record_metric_name_test.rb
|
435
438
|
- test/unit/utils/backtrace_parser_test.rb
|
436
439
|
- test/unit/utils/numbers_test.rb
|
437
440
|
- test/unit/utils/scm.rb
|
441
|
+
has_rdoc:
|