scout_apm 2.4.10 → 2.4.11.pre
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.rb +3 -0
- data/lib/scout_apm/agent_context.rb +4 -0
- data/lib/scout_apm/context.rb +9 -0
- data/lib/scout_apm/extensions/config.rb +87 -0
- data/lib/scout_apm/extensions/transaction_callback_payload.rb +74 -0
- data/lib/scout_apm/layer_converters/allocation_metric_converter.rb +3 -1
- data/lib/scout_apm/layer_converters/database_converter.rb +2 -0
- data/lib/scout_apm/layer_converters/error_converter.rb +4 -2
- data/lib/scout_apm/layer_converters/histograms.rb +1 -0
- data/lib/scout_apm/layer_converters/job_converter.rb +1 -0
- data/lib/scout_apm/layer_converters/metric_converter.rb +1 -0
- data/lib/scout_apm/layer_converters/request_queue_time_converter.rb +4 -2
- data/lib/scout_apm/layer_converters/slow_job_converter.rb +1 -0
- data/lib/scout_apm/layer_converters/slow_request_converter.rb +1 -0
- data/lib/scout_apm/reporting.rb +14 -10
- data/lib/scout_apm/tracked_request.rb +22 -15
- data/lib/scout_apm/version.rb +1 -1
- data/test/unit/extensions/periodic_callbacks_test.rb +58 -0
- data/test/unit/extensions/transaction_callbacks_test.rb +58 -0
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1686beb2285cb415ac0f73e4dfa65524b85a369d
|
4
|
+
data.tar.gz: f56d09891f9b899721c711f43dc48e06160073b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3af376cdc73869c73775ca02aaad1817fa735a7b2c73521fe2015f0584c5085e50f7ec94c40bc402363c691e70d98c6cfbc4d0887ff1b0cb7082efeae1bc2578
|
7
|
+
data.tar.gz: 6ace83f9f30fd8bfeb48875e6a58c508f2cc65f1fafd36e8fc1e6421c6556ddc096a27396dc2546ae623af9765586da976da64b6cec9654c29c71feea0927bd6
|
data/CHANGELOG.markdown
CHANGED
data/lib/scout_apm.rb
CHANGED
@@ -172,6 +172,9 @@ require 'scout_apm/agent/exit_handler'
|
|
172
172
|
require 'scout_apm/tasks/doctor'
|
173
173
|
require 'scout_apm/tasks/support'
|
174
174
|
|
175
|
+
require 'scout_apm/extensions/config'
|
176
|
+
require 'scout_apm/extensions/transaction_callback_payload'
|
177
|
+
|
175
178
|
if defined?(Rails) && defined?(Rails::VERSION) && defined?(Rails::VERSION::MAJOR) && Rails::VERSION::MAJOR >= 3 && defined?(Rails::Railtie)
|
176
179
|
module ScoutApm
|
177
180
|
class Railtie < Rails::Railtie
|
@@ -1,5 +1,8 @@
|
|
1
1
|
module ScoutApm
|
2
2
|
class AgentContext
|
3
|
+
|
4
|
+
attr_accessor :extensions
|
5
|
+
|
3
6
|
# Initially start up without attempting to load a configuration file. We
|
4
7
|
# need to be able to lookup configuration options like "application_root"
|
5
8
|
# which would then in turn influence where the yaml configuration file is
|
@@ -9,6 +12,7 @@ module ScoutApm
|
|
9
12
|
def initialize()
|
10
13
|
@logger = LoggerFactory.build_minimal_logger
|
11
14
|
@process_start_time = Time.now
|
15
|
+
@extensions = ScoutApm::Extensions::Config.new(self)
|
12
16
|
end
|
13
17
|
|
14
18
|
def marshal_dump
|
data/lib/scout_apm/context.rb
CHANGED
@@ -23,6 +23,15 @@ module ScoutApm
|
|
23
23
|
@extra.merge({:user => @user})
|
24
24
|
end
|
25
25
|
|
26
|
+
def to_flat_hash
|
27
|
+
h = to_hash
|
28
|
+
user = h.delete(:user)
|
29
|
+
if user
|
30
|
+
user.each { |k,v| h["user_#{k}"] = v}
|
31
|
+
end
|
32
|
+
h
|
33
|
+
end
|
34
|
+
|
26
35
|
def self.current
|
27
36
|
RequestManager.lookup.context
|
28
37
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module ScoutApm
|
2
|
+
module Extensions
|
3
|
+
# !!! Extensions are a 0.x level API and breakage is expected as the API is refined.
|
4
|
+
# Extensions fan out data collected by the agent to additional services.
|
5
|
+
class Config
|
6
|
+
attr_reader :agent_context
|
7
|
+
attr_accessor :transaction_callbacks
|
8
|
+
attr_accessor :periodic_callbacks
|
9
|
+
|
10
|
+
# Adds a new callback that runs after a transaction completes.
|
11
|
+
# These run inline during the request and thus should add minimal overhead.
|
12
|
+
# For example, a transaction callback should NOT make inline HTTP calls to outside services.
|
13
|
+
# +callback+ must be an object that respond to a +call(payload)+ method.
|
14
|
+
#
|
15
|
+
# Example:
|
16
|
+
# ScoutApm::Extensions::Config.add_transaction_callback(Proc.new { |payload| puts "Duration: #{payload.duration_ms}" })
|
17
|
+
#
|
18
|
+
# +payload+ is a +ScoutApm::Extensions::TransactionCallbackPayload+ object.
|
19
|
+
def self.add_transaction_callback(callback)
|
20
|
+
agent_context.extensions.transaction_callbacks << callback
|
21
|
+
end
|
22
|
+
|
23
|
+
# Adds a callback that runs when the per-minute report data is sent to Scout.
|
24
|
+
# These run in a background thread so external HTTP calls are OK.
|
25
|
+
# +callback+ must be an object that responds to a +call(reporting_period, metadata)+ method.
|
26
|
+
#
|
27
|
+
# Example:
|
28
|
+
# ScoutApm::Extensions::Config.add_periodic_callback(Proc.new { |reporting_period, metadata| ... })
|
29
|
+
def self.add_periodic_callback(callback)
|
30
|
+
agent_context.extensions.periodic_callbacks << callback
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(agent_context)
|
34
|
+
@agent_context = agent_context
|
35
|
+
@transaction_callbacks = []
|
36
|
+
@periodic_callbacks = []
|
37
|
+
end
|
38
|
+
|
39
|
+
# Runs each reporting period callback.
|
40
|
+
# Each callback runs inside a begin/rescue block so a broken callback doesn't prevent other
|
41
|
+
# callbacks from executing or reporting data from being sent.
|
42
|
+
def run_periodic_callbacks(reporting_period, metadata)
|
43
|
+
return unless periodic_callbacks.any?
|
44
|
+
|
45
|
+
periodic_callbacks.each do |callback|
|
46
|
+
begin
|
47
|
+
callback.call(reporting_period, metadata)
|
48
|
+
rescue => e
|
49
|
+
logger.warn "Error running reporting callback extension=#{callback}"
|
50
|
+
logger.info e.message
|
51
|
+
logger.debug e.backtrace
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Runs each transaction callback.
|
57
|
+
# Each callback runs inside a begin/rescue block so a broken callback doesn't prevent other
|
58
|
+
# callbacks from executing or the transaction from being recorded.
|
59
|
+
def run_transaction_callbacks(converter_results, context, scope_layer)
|
60
|
+
# It looks like layer_finder.scope = nil when a Sidekiq job is retried
|
61
|
+
return unless scope_layer
|
62
|
+
return unless transaction_callbacks.any?
|
63
|
+
|
64
|
+
payload = ScoutApm::Extensions::TransactionCallbackPayload.new(agent_context,converter_results,context,scope_layer)
|
65
|
+
|
66
|
+
transaction_callbacks.each do |callback|
|
67
|
+
begin
|
68
|
+
callback.call(payload)
|
69
|
+
rescue => e
|
70
|
+
logger.warn "Error running transaction callback extension=#{callback}"
|
71
|
+
logger.info e.message
|
72
|
+
logger.debug e.backtrace
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.agent_context
|
78
|
+
ScoutApm::Agent.instance.context
|
79
|
+
end
|
80
|
+
|
81
|
+
def logger
|
82
|
+
agent_context.logger
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module ScoutApm
|
2
|
+
module Extensions
|
3
|
+
# A +TransactionCallbackPayload+ is passed to each Transaction callback's +call+ method.
|
4
|
+
# It encapsulates the data about a specific transaction.
|
5
|
+
class TransactionCallbackPayload
|
6
|
+
# A Hash that stores the output of each layer converter by name. See the naming conventions in +TrackedRequest+.
|
7
|
+
attr_accessor :converter_results
|
8
|
+
|
9
|
+
def initialize(agent_context,converter_results,context,scope_layer)
|
10
|
+
@agent_context = agent_context
|
11
|
+
@converter_results = converter_results
|
12
|
+
@context = context
|
13
|
+
@scope_layer = scope_layer
|
14
|
+
end
|
15
|
+
|
16
|
+
# A flat hash of the context associated w/this transaction (ie user ip and another other data added to context).
|
17
|
+
def context
|
18
|
+
@context.to_flat_hash
|
19
|
+
end
|
20
|
+
|
21
|
+
# The total duration of the transaction
|
22
|
+
def duration_ms
|
23
|
+
@scope_layer.total_call_time*1000 # ms
|
24
|
+
end
|
25
|
+
|
26
|
+
# The time in queue of the transaction in ms. If not present, +nil+ is returned as this is unknown.
|
27
|
+
def queue_time_ms
|
28
|
+
# Controller logic
|
29
|
+
if converter_results[:queue_time] && converter_results[:queue].any?
|
30
|
+
converter_results[:queue_time].values.first.total_call_time*1000 # ms
|
31
|
+
# Job logic
|
32
|
+
elsif converter_results[:job]
|
33
|
+
stat = converter_results[:job].metric_set.metrics[ScoutApm::MetricMeta.new("Latency/all", :scope => transaction_name)]
|
34
|
+
stat ? stat.total_call_time*1000 : nil
|
35
|
+
else
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def hostname
|
41
|
+
@agent_context.environment.hostname
|
42
|
+
end
|
43
|
+
|
44
|
+
def app_name
|
45
|
+
@agent_context.config.value('name')
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns +true+ if the transaction raised an exception.
|
49
|
+
def error?
|
50
|
+
converter_results[:errors] && converter_results[:errors].any?
|
51
|
+
end
|
52
|
+
|
53
|
+
def transation_type
|
54
|
+
@scope_layer.type
|
55
|
+
end
|
56
|
+
|
57
|
+
def transaction_name
|
58
|
+
@scope_layer.legacy_metric_name
|
59
|
+
end
|
60
|
+
|
61
|
+
# Web/Job are more language-agnostic names for controller/job. For example, Python Django does not have controllers.
|
62
|
+
def transaction_type_slug
|
63
|
+
case transation_type
|
64
|
+
when 'Controller'
|
65
|
+
'web'
|
66
|
+
when 'Job'
|
67
|
+
'job'
|
68
|
+
else
|
69
|
+
'transaction'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -8,8 +8,10 @@ module ScoutApm
|
|
8
8
|
meta = MetricMeta.new("ObjectAllocations", {:scope => scope_layer.legacy_metric_name})
|
9
9
|
stat = MetricStats.new
|
10
10
|
stat.update!(root_layer.total_allocations)
|
11
|
+
metrics = { meta => stat }
|
11
12
|
|
12
|
-
@store.track!(
|
13
|
+
@store.track!(metrics)
|
14
|
+
nil # not returning anything in the layer results ... not used
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -32,6 +32,8 @@ module ScoutApm
|
|
32
32
|
# only due to 1 http request)
|
33
33
|
@db_query_metric_set.increment_transaction_count!
|
34
34
|
@store.track_db_query_metrics!(@db_query_metric_set)
|
35
|
+
|
36
|
+
nil # not returning anything in the layer results ... not used
|
35
37
|
end
|
36
38
|
|
37
39
|
def skip_layer?(layer)
|
@@ -10,8 +10,10 @@ module ScoutApm
|
|
10
10
|
meta = MetricMeta.new("Errors/#{scope_layer.legacy_metric_name}", {})
|
11
11
|
stat = MetricStats.new
|
12
12
|
stat.update!(1)
|
13
|
-
|
14
|
-
|
13
|
+
metrics = { meta => stat }
|
14
|
+
|
15
|
+
@store.track!(metrics)
|
16
|
+
metrics # this result must be returned so it can be accessed by transaction callback extensions
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -28,8 +28,10 @@ module ScoutApm
|
|
28
28
|
meta = MetricMeta.new("QueueTime/Request", {:scope => scope_layer.legacy_metric_name})
|
29
29
|
stat = MetricStats.new(true)
|
30
30
|
stat.update!(queue_time)
|
31
|
-
|
32
|
-
|
31
|
+
metrics = { meta => stat }
|
32
|
+
|
33
|
+
@store.track!(metrics)
|
34
|
+
metrics # this result must be returned so it can be accessed by transaction callback extensions
|
33
35
|
end
|
34
36
|
|
35
37
|
private
|
data/lib/scout_apm/reporting.rb
CHANGED
@@ -48,7 +48,9 @@ module ScoutApm
|
|
48
48
|
begin
|
49
49
|
merged = rps.inject { |memo, rp| memo.merge(rp) }
|
50
50
|
logger.debug("Merged #{rps.length} reporting periods, delivering")
|
51
|
-
|
51
|
+
metadata = metadata(merged)
|
52
|
+
deliver_period(merged,metadata)
|
53
|
+
context.extensions.run_periodic_callbacks(merged, metadata)
|
52
54
|
true
|
53
55
|
rescue => e
|
54
56
|
logger.debug("Error merging reporting periods #{e.message}")
|
@@ -63,15 +65,8 @@ module ScoutApm
|
|
63
65
|
end
|
64
66
|
end
|
65
67
|
|
66
|
-
def
|
67
|
-
|
68
|
-
slow_transactions = reporting_period.slow_transactions_payload
|
69
|
-
jobs = reporting_period.jobs
|
70
|
-
slow_jobs = reporting_period.slow_jobs_payload
|
71
|
-
histograms = reporting_period.histograms
|
72
|
-
db_query_metrics = reporting_period.db_query_metrics_payload
|
73
|
-
|
74
|
-
metadata = {
|
68
|
+
def metadata(reporting_period)
|
69
|
+
{
|
75
70
|
:app_root => context.environment.root.to_s,
|
76
71
|
:unique_id => ScoutApm::Utils::UniqueId.simple,
|
77
72
|
:agent_version => ScoutApm::VERSION,
|
@@ -79,6 +74,15 @@ module ScoutApm
|
|
79
74
|
:agent_pid => Process.pid,
|
80
75
|
:platform => "ruby",
|
81
76
|
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def deliver_period(reporting_period,metadata)
|
80
|
+
metrics = reporting_period.metrics_payload
|
81
|
+
slow_transactions = reporting_period.slow_transactions_payload
|
82
|
+
jobs = reporting_period.jobs
|
83
|
+
slow_jobs = reporting_period.slow_jobs_payload
|
84
|
+
histograms = reporting_period.histograms
|
85
|
+
db_query_metrics = reporting_period.db_query_metrics_payload
|
82
86
|
|
83
87
|
log_deliver(metrics, slow_transactions, metadata, slow_jobs, histograms)
|
84
88
|
|
@@ -64,7 +64,6 @@ module ScoutApm
|
|
64
64
|
@mem_start = mem_usage
|
65
65
|
@recorder = agent_context.recorder
|
66
66
|
@real_request = false
|
67
|
-
|
68
67
|
ignore_request! if @recorder.nil?
|
69
68
|
end
|
70
69
|
|
@@ -116,6 +115,7 @@ module ScoutApm
|
|
116
115
|
layer.capture_backtrace!
|
117
116
|
end
|
118
117
|
|
118
|
+
|
119
119
|
if finalized?
|
120
120
|
stop_request
|
121
121
|
end
|
@@ -273,27 +273,34 @@ module ScoutApm
|
|
273
273
|
|
274
274
|
apply_name_override
|
275
275
|
|
276
|
-
converters
|
277
|
-
|
278
|
-
LayerConverters::
|
279
|
-
LayerConverters::
|
280
|
-
LayerConverters::
|
281
|
-
LayerConverters::
|
282
|
-
LayerConverters::
|
283
|
-
LayerConverters::
|
276
|
+
# Make a constant, then call converters.dup.each so it isn't inline?
|
277
|
+
converters = {
|
278
|
+
:histograms => LayerConverters::Histograms,
|
279
|
+
:metrics => LayerConverters::MetricConverter,
|
280
|
+
:errors => LayerConverters::ErrorConverter,
|
281
|
+
:allocation_metrics => LayerConverters::AllocationMetricConverter,
|
282
|
+
:queue_time => LayerConverters::RequestQueueTimeConverter,
|
283
|
+
:job => LayerConverters::JobConverter,
|
284
|
+
:db => LayerConverters::DatabaseConverter,
|
284
285
|
|
285
|
-
LayerConverters::SlowJobConverter,
|
286
|
-
LayerConverters::SlowRequestConverter,
|
287
|
-
|
286
|
+
:slow_job => LayerConverters::SlowJobConverter,
|
287
|
+
:slow_req => LayerConverters::SlowRequestConverter,
|
288
|
+
}
|
288
289
|
|
289
290
|
walker = LayerConverters::DepthFirstWalker.new(self.root_layer)
|
290
|
-
|
291
|
+
converter_instances = converters.inject({}) do |memo, (slug, klass)|
|
291
292
|
instance = klass.new(@agent_context, self, layer_finder, @store)
|
292
293
|
instance.register_hooks(walker)
|
293
|
-
instance
|
294
|
+
memo[slug] = instance
|
295
|
+
memo
|
294
296
|
end
|
295
297
|
walker.walk
|
296
|
-
|
298
|
+
converter_results = converter_instances.inject({}) do |memo, (slug,i)|
|
299
|
+
memo[slug] = i.record!
|
300
|
+
memo
|
301
|
+
end
|
302
|
+
|
303
|
+
@agent_context.extensions.run_transaction_callbacks(converter_results,context,layer_finder.scope)
|
297
304
|
|
298
305
|
# If there's an instant_key, it means we need to report this right away
|
299
306
|
if web? && instant?
|
data/lib/scout_apm/version.rb
CHANGED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PeriodicCallbacksTest < Minitest::Test
|
4
|
+
|
5
|
+
# We don't have a test that ensures we actually report data to the server, so we can't be 100% sure this doesn't break
|
6
|
+
# reporting.
|
7
|
+
def test_broken_callback_does_not_throw_exception
|
8
|
+
ScoutApm::Extensions::Config.add_periodic_callback(BrokenCallback.new)
|
9
|
+
# Runs via agent context as calling +add_periodic_callback+ initializing the context + extension config.
|
10
|
+
ScoutApm::Agent.instance.context.extensions.run_periodic_callbacks(reporting_period,metadata)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_callback_runs
|
14
|
+
Thread.current[:periodic_callback_output] = nil
|
15
|
+
ScoutApm::Extensions::Config.add_periodic_callback(PeriodicCallback.new)
|
16
|
+
ScoutApm::Agent.instance.context.extensions.run_periodic_callbacks(reporting_period,metadata)
|
17
|
+
assert Thread.current[:periodic_callback_output]
|
18
|
+
end
|
19
|
+
|
20
|
+
def run_proc_callback
|
21
|
+
Thread.current[:proc_periodic] = nil
|
22
|
+
ScoutApm::Extensions::Config.add_periodic_callback(Proc.new { |reporting_period, metadata| Thread.current[:proc_periodic] = Time.at(metadata[:agent_time].to_i) })
|
23
|
+
ScoutApm::Agent.instance.context.extensions.run_periodic_callbacks(reporting_period,metadata)
|
24
|
+
assert Thread.current[:proc_periodic]
|
25
|
+
end
|
26
|
+
|
27
|
+
# Doesn't respond to +call+.
|
28
|
+
class BrokenCallback
|
29
|
+
end
|
30
|
+
|
31
|
+
# Sets a Thread local so we can verify that the callback ran.
|
32
|
+
class PeriodicCallback
|
33
|
+
def call(reporting_period,metadata)
|
34
|
+
Thread.current[:periodic_callback_output] = true
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def reporting_period
|
41
|
+
rp = ScoutApm::StoreReportingPeriod.new(ScoutApm::AgentContext.new, Time.at(metadata[:agent_time].to_i))
|
42
|
+
rp.absorb_metrics!(metrics)
|
43
|
+
end
|
44
|
+
|
45
|
+
def metrics
|
46
|
+
meta = ScoutApm::MetricMeta.new("Controller/users/index")
|
47
|
+
stats = ScoutApm::MetricStats.new
|
48
|
+
stats.update!(0.1)
|
49
|
+
{
|
50
|
+
meta => stats
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def metadata
|
55
|
+
{:app_root=>"/srv/rails_app", :unique_id=>"ID", :agent_version=>"2.4.10", :agent_time=>"1523287920", :agent_pid=>21581, :platform=>"ruby"}
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TransactionCallbacksTest < Minitest::Test
|
4
|
+
|
5
|
+
def setup
|
6
|
+
# Another test could set the recorder to +FakeRecorder+, which does not call +TrackedRequest#record!+.
|
7
|
+
ScoutApm::Agent.instance.context.recorder = ScoutApm::RecorderFactory.build(ScoutApm::Agent.instance.context)
|
8
|
+
end
|
9
|
+
|
10
|
+
# This is more of an integration test to ensure that we don't break TrackedRequest.
|
11
|
+
def test_broken_callback_does_not_break_tracked_request
|
12
|
+
ScoutApm::Extensions::Config.add_transaction_callback(BrokenCallback.new)
|
13
|
+
|
14
|
+
controller_layer = ScoutApm::Layer.new("Controller", "users/index")
|
15
|
+
# why doesn't this run? check if callbacks are configured
|
16
|
+
tr = ScoutApm::TrackedRequest.new(ScoutApm::Agent.instance.context, ScoutApm::FakeStore.new)
|
17
|
+
tr.start_layer(controller_layer)
|
18
|
+
tr.stop_layer
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_callback_runs
|
22
|
+
Thread.current[:transaction_callback_output] = nil
|
23
|
+
ScoutApm::Extensions::Config.add_transaction_callback(TransactionCallback.new)
|
24
|
+
|
25
|
+
controller_layer = ScoutApm::Layer.new("Controller", "users/index")
|
26
|
+
|
27
|
+
tr = ScoutApm::TrackedRequest.new(ScoutApm::Agent.instance.context, ScoutApm::FakeStore.new)
|
28
|
+
tr.start_layer(controller_layer)
|
29
|
+
tr.stop_layer
|
30
|
+
|
31
|
+
assert Thread.current[:transaction_callback_output]
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_run_proc_callback
|
35
|
+
Thread.current[:proc_transaction_duration] = nil
|
36
|
+
ScoutApm::Extensions::Config.add_transaction_callback(Proc.new { |payload| Thread.current[:proc_transaction_duration] = payload.duration_ms })
|
37
|
+
|
38
|
+
controller_layer = ScoutApm::Layer.new("Controller", "users/index")
|
39
|
+
|
40
|
+
tr = ScoutApm::TrackedRequest.new(ScoutApm::Agent.instance.context, ScoutApm::FakeStore.new)
|
41
|
+
tr.start_layer(controller_layer)
|
42
|
+
tr.stop_layer
|
43
|
+
|
44
|
+
assert Thread.current[:proc_transaction_duration]
|
45
|
+
end
|
46
|
+
|
47
|
+
# Doesn't respond to +call+.
|
48
|
+
class BrokenCallback
|
49
|
+
end
|
50
|
+
|
51
|
+
# Sets a Thread local so we can verify that the callback ran.
|
52
|
+
class TransactionCallback
|
53
|
+
def call(payload)
|
54
|
+
Thread.current[:transaction_callback_output] = true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
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.11.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Derek Haynes
|
@@ -209,6 +209,8 @@ files:
|
|
209
209
|
- lib/scout_apm/db_query_metric_stats.rb
|
210
210
|
- lib/scout_apm/debug.rb
|
211
211
|
- lib/scout_apm/environment.rb
|
212
|
+
- lib/scout_apm/extensions/config.rb
|
213
|
+
- lib/scout_apm/extensions/transaction_callback_payload.rb
|
212
214
|
- lib/scout_apm/fake_store.rb
|
213
215
|
- lib/scout_apm/framework_integrations/rails_2.rb
|
214
216
|
- lib/scout_apm/framework_integrations/rails_3_or_4.rb
|
@@ -332,6 +334,8 @@ files:
|
|
332
334
|
- test/unit/db_query_metric_set_test.rb
|
333
335
|
- test/unit/db_query_metric_stats_test.rb
|
334
336
|
- test/unit/environment_test.rb
|
337
|
+
- test/unit/extensions/periodic_callbacks_test.rb
|
338
|
+
- test/unit/extensions/transaction_callbacks_test.rb
|
335
339
|
- test/unit/fake_store_test.rb
|
336
340
|
- test/unit/git_revision_test.rb
|
337
341
|
- test/unit/histogram_test.rb
|
@@ -379,12 +383,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
379
383
|
version: '0'
|
380
384
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
381
385
|
requirements:
|
382
|
-
- - "
|
386
|
+
- - ">"
|
383
387
|
- !ruby/object:Gem::Version
|
384
|
-
version:
|
388
|
+
version: 1.3.1
|
385
389
|
requirements: []
|
386
390
|
rubyforge_project: scout_apm
|
387
|
-
rubygems_version: 2.4.
|
391
|
+
rubygems_version: 2.4.6
|
388
392
|
signing_key:
|
389
393
|
specification_version: 4
|
390
394
|
summary: Ruby application performance monitoring
|
@@ -398,6 +402,8 @@ test_files:
|
|
398
402
|
- test/unit/db_query_metric_set_test.rb
|
399
403
|
- test/unit/db_query_metric_stats_test.rb
|
400
404
|
- test/unit/environment_test.rb
|
405
|
+
- test/unit/extensions/periodic_callbacks_test.rb
|
406
|
+
- test/unit/extensions/transaction_callbacks_test.rb
|
401
407
|
- test/unit/fake_store_test.rb
|
402
408
|
- test/unit/git_revision_test.rb
|
403
409
|
- test/unit/histogram_test.rb
|
@@ -429,3 +435,4 @@ test_files:
|
|
429
435
|
- test/unit/utils/backtrace_parser_test.rb
|
430
436
|
- test/unit/utils/numbers_test.rb
|
431
437
|
- test/unit/utils/scm.rb
|
438
|
+
has_rdoc:
|