scout_apm 3.0.0.pre23 → 3.0.0.pre25
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 +8 -0
- data/Gemfile +1 -1
- data/lib/scout_apm.rb +1 -0
- data/lib/scout_apm/agent_context.rb +4 -0
- data/lib/scout_apm/background_job_integrations/delayed_job.rb +1 -1
- 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/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 +50 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d2364c7ae5bfc518cc19c5059e90959a15203bc
|
4
|
+
data.tar.gz: 45a2372a9d6a96460b946419ec02c3ceb63a4d2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 607f2bf5f3b6eedab959e49c277972f00c72c03d408782a8cc0466a7fc44a2e5dce11a4279da227f64cb5baeda9d1ad4ed8ead972687906abd19750973e7246b
|
7
|
+
data.tar.gz: 0bb02a39eb5dd459665b9049038e275e08fe3ddd60a1ffcb5b2d6af1f7f31f8291d58eaac2a8cac577527a8a046167f2492058af6e20d7f725691b25e0b1d40f
|
data/CHANGELOG.markdown
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
|
3
3
|
* ScoutProf BETA
|
4
4
|
|
5
|
+
# 2.4.13
|
6
|
+
|
7
|
+
* Incorporating total time consumed into transaction trace policy
|
8
|
+
|
9
|
+
# 2.4.12
|
10
|
+
|
11
|
+
* Calculates DelayedJob queue latency correctly when jobs are scheduled to run in the future
|
12
|
+
|
5
13
|
# 2.4.11
|
6
14
|
|
7
15
|
* Adds transaction + periodic reporting callback extension support
|
data/Gemfile
CHANGED
data/lib/scout_apm.rb
CHANGED
@@ -146,6 +146,7 @@ require 'scout_apm/slow_request_policy'
|
|
146
146
|
require 'scout_apm/slow_job_policy'
|
147
147
|
require 'scout_apm/job_record'
|
148
148
|
require 'scout_apm/request_histograms'
|
149
|
+
require 'scout_apm/transaction_time_consumed'
|
149
150
|
|
150
151
|
require 'scout_apm/attribute_arranger'
|
151
152
|
require 'scout_apm/git_revision'
|
@@ -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
|
|
@@ -300,6 +300,8 @@ module ScoutApm
|
|
300
300
|
|
301
301
|
apply_name_override
|
302
302
|
|
303
|
+
@agent_context.transaction_time_consumed.add(unique_name, root_layer.total_call_time)
|
304
|
+
|
303
305
|
# Make a constant, then call converters.dup.each so it isn't inline?
|
304
306
|
converters = {
|
305
307
|
: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
@@ -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: 3.0.0.
|
4
|
+
version: 3.0.0.pre25
|
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-
|
12
|
+
date: 2018-06-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -315,6 +315,7 @@ files:
|
|
315
315
|
- lib/scout_apm/tracer.rb
|
316
316
|
- lib/scout_apm/tracked_request.rb
|
317
317
|
- lib/scout_apm/transaction.rb
|
318
|
+
- lib/scout_apm/transaction_time_consumed.rb
|
318
319
|
- lib/scout_apm/utils/active_record_metric_name.rb
|
319
320
|
- lib/scout_apm/utils/backtrace_parser.rb
|
320
321
|
- lib/scout_apm/utils/fake_stacks.rb
|
@@ -369,6 +370,7 @@ files:
|
|
369
370
|
- test/unit/tracer_test.rb
|
370
371
|
- test/unit/tracked_request_test.rb
|
371
372
|
- test/unit/transaction_test.rb
|
373
|
+
- test/unit/transaction_time_consumed_test.rb
|
372
374
|
- test/unit/utils/active_record_metric_name_test.rb
|
373
375
|
- test/unit/utils/backtrace_parser_test.rb
|
374
376
|
- test/unit/utils/numbers_test.rb
|
@@ -395,8 +397,52 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
395
397
|
version: 1.3.1
|
396
398
|
requirements: []
|
397
399
|
rubyforge_project: scout_apm
|
398
|
-
rubygems_version: 2.6
|
400
|
+
rubygems_version: 2.4.6
|
399
401
|
signing_key:
|
400
402
|
specification_version: 4
|
401
403
|
summary: Ruby application performance monitoring
|
402
|
-
test_files:
|
404
|
+
test_files:
|
405
|
+
- test/data/config_test_1.yml
|
406
|
+
- test/test_helper.rb
|
407
|
+
- test/unit/agent_test.rb
|
408
|
+
- test/unit/background_job_integrations/sidekiq_test.rb
|
409
|
+
- test/unit/config_test.rb
|
410
|
+
- test/unit/context_test.rb
|
411
|
+
- test/unit/db_query_metric_set_test.rb
|
412
|
+
- test/unit/db_query_metric_stats_test.rb
|
413
|
+
- test/unit/environment_test.rb
|
414
|
+
- test/unit/extensions/periodic_callbacks_test.rb
|
415
|
+
- test/unit/extensions/transaction_callbacks_test.rb
|
416
|
+
- test/unit/fake_store_test.rb
|
417
|
+
- test/unit/git_revision_test.rb
|
418
|
+
- test/unit/histogram_test.rb
|
419
|
+
- test/unit/ignored_uris_test.rb
|
420
|
+
- test/unit/instruments/active_record_instruments_test.rb
|
421
|
+
- test/unit/instruments/net_http_test.rb
|
422
|
+
- test/unit/instruments/percentile_sampler_test.rb
|
423
|
+
- test/unit/layaway_test.rb
|
424
|
+
- test/unit/layer_children_set_test.rb
|
425
|
+
- test/unit/layer_converters/depth_first_walker_test.rb
|
426
|
+
- test/unit/layer_converters/metric_converter_test.rb
|
427
|
+
- test/unit/layer_converters/stubs.rb
|
428
|
+
- test/unit/limited_layer_test.rb
|
429
|
+
- test/unit/logger_test.rb
|
430
|
+
- test/unit/metric_set_test.rb
|
431
|
+
- test/unit/remote/test_message.rb
|
432
|
+
- test/unit/remote/test_router.rb
|
433
|
+
- test/unit/remote/test_server.rb
|
434
|
+
- test/unit/scored_item_set_test.rb
|
435
|
+
- test/unit/serializers/payload_serializer_test.rb
|
436
|
+
- test/unit/slow_job_policy_test.rb
|
437
|
+
- test/unit/slow_request_policy_test.rb
|
438
|
+
- test/unit/sql_sanitizer_test.rb
|
439
|
+
- test/unit/store_test.rb
|
440
|
+
- test/unit/tracer_test.rb
|
441
|
+
- test/unit/tracked_request_test.rb
|
442
|
+
- test/unit/transaction_test.rb
|
443
|
+
- test/unit/transaction_time_consumed_test.rb
|
444
|
+
- test/unit/utils/active_record_metric_name_test.rb
|
445
|
+
- test/unit/utils/backtrace_parser_test.rb
|
446
|
+
- test/unit/utils/numbers_test.rb
|
447
|
+
- test/unit/utils/scm.rb
|
448
|
+
has_rdoc:
|