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