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