scout_apm 3.0.0.pre1 → 3.0.0.pre2
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 +12 -1
- data/lib/scout_apm.rb +3 -0
- data/lib/scout_apm/agent.rb +9 -6
- data/lib/scout_apm/agent/reporting.rb +5 -3
- data/lib/scout_apm/background_job_integrations/delayed_job.rb +47 -1
- data/lib/scout_apm/background_worker.rb +4 -0
- data/lib/scout_apm/config.rb +2 -1
- data/lib/scout_apm/environment.rb +1 -1
- data/lib/scout_apm/histogram.rb +11 -2
- data/lib/scout_apm/instruments/mongoid.rb +14 -1
- data/lib/scout_apm/instruments/percentile_sampler.rb +36 -19
- data/lib/scout_apm/instruments/process/process_cpu.rb +3 -2
- data/lib/scout_apm/instruments/process/process_memory.rb +3 -3
- data/lib/scout_apm/layer_converters/converter_base.rb +213 -0
- data/lib/scout_apm/layer_converters/slow_job_converter.rb +19 -93
- data/lib/scout_apm/layer_converters/slow_request_converter.rb +15 -100
- data/lib/scout_apm/metric_set.rb +6 -0
- data/lib/scout_apm/reporter.rb +53 -15
- data/lib/scout_apm/request_histograms.rb +4 -0
- data/lib/scout_apm/scored_item_set.rb +7 -0
- data/lib/scout_apm/serializers/histograms_serializer_to_json.rb +21 -0
- data/lib/scout_apm/serializers/payload_serializer.rb +9 -3
- data/lib/scout_apm/serializers/payload_serializer_to_json.rb +2 -1
- data/lib/scout_apm/serializers/slow_jobs_serializer_to_json.rb +1 -1
- data/lib/scout_apm/slow_job_record.rb +4 -1
- data/lib/scout_apm/slow_transaction.rb +18 -2
- data/lib/scout_apm/store.rb +42 -11
- data/lib/scout_apm/tracked_request.rb +1 -1
- data/lib/scout_apm/utils/gzip_helper.rb +24 -0
- data/lib/scout_apm/utils/numbers.rb +14 -0
- data/lib/scout_apm/version.rb +2 -2
- data/test/test_helper.rb +10 -0
- data/test/unit/config_test.rb +7 -9
- data/test/unit/histogram_test.rb +14 -0
- data/test/unit/instruments/percentile_sampler_test.rb +137 -0
- data/test/unit/serializers/payload_serializer_test.rb +3 -3
- data/test/unit/store_test.rb +51 -0
- data/test/unit/utils/numbers_test.rb +15 -0
- metadata +10 -4
@@ -2,7 +2,6 @@ module ScoutApm
|
|
2
2
|
module LayerConverters
|
3
3
|
class SlowJobConverter < ConverterBase
|
4
4
|
def initialize(*)
|
5
|
-
@backtraces = []
|
6
5
|
super
|
7
6
|
|
8
7
|
# After call to super, so @request is populated
|
@@ -11,6 +10,8 @@ module ScoutApm
|
|
11
10
|
else
|
12
11
|
-1
|
13
12
|
end
|
13
|
+
|
14
|
+
setup_subscopable_callbacks
|
14
15
|
end
|
15
16
|
|
16
17
|
def name
|
@@ -32,6 +33,7 @@ module ScoutApm
|
|
32
33
|
mem_delta = ScoutApm::Instruments::Process::ProcessMemory.rss_to_mb(request.capture_mem_delta!)
|
33
34
|
|
34
35
|
timing_metrics, allocation_metrics = create_metrics
|
36
|
+
|
35
37
|
unless ScoutApm::Instruments::Allocations::ENABLED
|
36
38
|
allocation_metrics = {}
|
37
39
|
end
|
@@ -47,7 +49,9 @@ module ScoutApm
|
|
47
49
|
allocation_metrics,
|
48
50
|
mem_delta,
|
49
51
|
job_layer.total_allocations,
|
50
|
-
score
|
52
|
+
score,
|
53
|
+
limited?
|
54
|
+
)
|
51
55
|
end
|
52
56
|
|
53
57
|
def queue_layer
|
@@ -58,108 +62,30 @@ module ScoutApm
|
|
58
62
|
@job_layer ||= find_first_layer_of_type("Job")
|
59
63
|
end
|
60
64
|
|
65
|
+
|
66
|
+
# The queue_layer is useful to capture for other reasons, but doesn't
|
67
|
+
# create a MetricMeta/Stat of its own
|
68
|
+
def skip_layer?(layer)
|
69
|
+
super(layer) || layer == queue_layer
|
70
|
+
end
|
71
|
+
|
61
72
|
def create_metrics
|
62
73
|
metric_hash = Hash.new
|
63
74
|
allocation_metric_hash = Hash.new
|
64
75
|
|
65
|
-
|
66
|
-
|
67
|
-
# layers. This lets us push/pop without otherwise keeping track very closely.
|
68
|
-
subscope_layers = []
|
76
|
+
walker.walk do |layer|
|
77
|
+
next if skip_layer?(layer)
|
69
78
|
|
70
|
-
|
71
|
-
if layer.subscopable?
|
72
|
-
subscope_layers.push(layer)
|
73
|
-
end
|
74
|
-
end
|
79
|
+
debug_scoutprof(layer)
|
75
80
|
|
76
|
-
|
77
|
-
|
78
|
-
subscope_layers.pop
|
79
|
-
end
|
81
|
+
store_specific_metric(layer, metric_hash, allocation_metric_hash)
|
82
|
+
store_aggregate_metric(layer, metric_hash, allocation_metric_hash)
|
80
83
|
end
|
81
84
|
|
82
|
-
walker.walk do |layer|
|
83
|
-
# Sometimes we start capturing a layer without knowing if we really
|
84
|
-
# want to make an entry for it. See ActiveRecord instrumentation for
|
85
|
-
# an example. We start capturing before we know if a query is cached
|
86
|
-
# or not, and want to skip any cached queries.
|
87
|
-
next if layer.annotations[:ignorable]
|
88
|
-
|
89
|
-
# The queue_layer is useful to capture for other reasons, but doesn't
|
90
|
-
# create a MetricMeta/Stat of its own
|
91
|
-
next if layer == queue_layer
|
92
|
-
|
93
|
-
meta_options = if subscope_layers.first && layer != subscope_layers.first # Don't scope under ourself.
|
94
|
-
subscope_name = subscope_layers.first.legacy_metric_name
|
95
|
-
{:scope => subscope_name}
|
96
|
-
elsif layer == job_layer # We don't scope the controller under itself
|
97
|
-
{}
|
98
|
-
else
|
99
|
-
{:scope => job_layer.legacy_metric_name}
|
100
|
-
end
|
101
|
-
|
102
|
-
# Specific Metric
|
103
|
-
meta_options.merge!(:desc => layer.desc.to_s) if layer.desc
|
104
|
-
meta = MetricMeta.new(layer.legacy_metric_name, meta_options)
|
105
|
-
meta.extra.merge!(layer.annotations)
|
106
|
-
|
107
|
-
if layer.backtrace
|
108
|
-
bt = ScoutApm::Utils::BacktraceParser.new(layer.backtrace).call
|
109
|
-
if bt.any? # we could walk thru the call stack and not find in-app code
|
110
|
-
meta.backtrace = bt
|
111
|
-
# Why not just call meta.backtrace and call it done? The walker could access a later later that generates the same MetricMeta but doesn't have a backtrace. This could be
|
112
|
-
# lost in the metric_hash if it is replaced by the new key.
|
113
|
-
@backtraces << meta
|
114
|
-
else
|
115
|
-
ScoutApm::Agent.instance.logger.debug { "Unable to capture an app-specific backtrace for #{meta.inspect}\n#{layer.backtrace}" }
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
metric_hash[meta] ||= MetricStats.new( meta_options.has_key?(:scope) )
|
120
|
-
allocation_metric_hash[meta] ||= MetricStats.new( meta_options.has_key?(:scope) )
|
121
|
-
stat = metric_hash[meta]
|
122
|
-
stat.update!(layer.total_call_time, layer.total_exclusive_time)
|
123
|
-
stat = allocation_metric_hash[meta]
|
124
|
-
stat.update!(layer.total_allocations, layer.total_exclusive_allocations)
|
125
|
-
|
126
|
-
# Merged Metric (no specifics, just sum up by type)
|
127
|
-
meta = MetricMeta.new("#{layer.type}/all")
|
128
|
-
metric_hash[meta] ||= MetricStats.new(false)
|
129
|
-
allocation_metric_hash[meta] ||= MetricStats.new(false)
|
130
|
-
stat = metric_hash[meta]
|
131
|
-
stat.update!(layer.total_call_time, layer.total_exclusive_time)
|
132
|
-
stat = allocation_metric_hash[meta]
|
133
|
-
stat.update!(layer.total_allocations, layer.total_exclusive_allocations)
|
134
|
-
|
135
|
-
stat.add_traces(layer.traces.as_json)
|
136
|
-
|
137
|
-
# Debug logging for scoutprof traces
|
138
|
-
if ScoutApm::Agent.instance.config.value('profile')
|
139
|
-
if layer.type =~ %r{^(Controller|Queue|Job)$}.freeze
|
140
|
-
ScoutApm::Agent.instance.logger.debug do
|
141
|
-
traces_inspect = layer.traces.inspect
|
142
|
-
"****** Slow Request #{layer.type} Traces (#{layer.name}, tet: #{layer.total_exclusive_time}, tct: #{layer.total_call_time}), total raw traces: #{layer.traces.cube.total_count}, total clean traces: #{layer.traces.total_count}, skipped gc: #{layer.traces.skipped_in_gc}, skipped handler: #{layer.traces.skipped_in_handler}, skipped registered #{layer.traces.skipped_in_job_registered}, skipped not_running #{layer.traces.skipped_in_not_running}:\n#{traces_inspect}"
|
143
|
-
end
|
144
|
-
end
|
145
|
-
else
|
146
|
-
if layer.type =~ %r{^(Controller|Queue|Job)$}.freeze
|
147
|
-
ScoutApm::Agent.instance.logger.debug "****** Slow Request #{layer.type} Traces: Scoutprof is not enabled"
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end # walker.walk
|
151
|
-
|
152
85
|
metric_hash = attach_backtraces(metric_hash)
|
153
86
|
allocation_metric_hash = attach_backtraces(allocation_metric_hash)
|
154
87
|
|
155
|
-
[metric_hash,allocation_metric_hash]
|
156
|
-
end
|
157
|
-
|
158
|
-
def attach_backtraces(metric_hash)
|
159
|
-
@backtraces.each do |meta_with_backtrace|
|
160
|
-
metric_hash.keys.find { |k| k == meta_with_backtrace }.backtrace = meta_with_backtrace.backtrace
|
161
|
-
end
|
162
|
-
metric_hash
|
88
|
+
[metric_hash, allocation_metric_hash]
|
163
89
|
end
|
164
90
|
end
|
165
91
|
end
|
@@ -2,7 +2,6 @@ module ScoutApm
|
|
2
2
|
module LayerConverters
|
3
3
|
class SlowRequestConverter < ConverterBase
|
4
4
|
def initialize(*)
|
5
|
-
@backtraces = [] # An Array of MetricMetas that have a backtrace
|
6
5
|
super
|
7
6
|
|
8
7
|
# After call to super, so @request is populated
|
@@ -11,6 +10,8 @@ module ScoutApm
|
|
11
10
|
else
|
12
11
|
-1
|
13
12
|
end
|
13
|
+
|
14
|
+
setup_subscopable_callbacks
|
14
15
|
end
|
15
16
|
|
16
17
|
def name
|
@@ -24,8 +25,8 @@ module ScoutApm
|
|
24
25
|
# Unconditionally attempts to convert this into a SlowTransaction object.
|
25
26
|
# Can return nil if the request didn't have any scope_layer.
|
26
27
|
def call
|
27
|
-
|
28
|
-
return nil unless
|
28
|
+
return nil unless request.web?
|
29
|
+
return nil unless scope_layer
|
29
30
|
|
30
31
|
ScoutApm::Agent.instance.slow_request_policy.stored!(request)
|
31
32
|
|
@@ -35,12 +36,13 @@ module ScoutApm
|
|
35
36
|
uri = request.annotations[:uri] || ""
|
36
37
|
|
37
38
|
timing_metrics, allocation_metrics = create_metrics
|
39
|
+
|
38
40
|
unless ScoutApm::Instruments::Allocations::ENABLED
|
39
41
|
allocation_metrics = {}
|
40
42
|
end
|
41
43
|
|
42
44
|
SlowTransaction.new(uri,
|
43
|
-
|
45
|
+
scope_layer.legacy_metric_name,
|
44
46
|
root_layer.total_call_time,
|
45
47
|
timing_metrics,
|
46
48
|
allocation_metrics,
|
@@ -49,119 +51,32 @@ module ScoutApm
|
|
49
51
|
[], # stackprof, now unused.
|
50
52
|
mem_delta,
|
51
53
|
root_layer.total_allocations,
|
52
|
-
@points
|
53
|
-
|
54
|
-
|
55
|
-
# Iterates over the TrackedRequest's MetricMetas that have backtraces and attaches each to correct MetricMeta in the Metric Hash.
|
56
|
-
def attach_backtraces(metric_hash)
|
57
|
-
@backtraces.each do |meta_with_backtrace|
|
58
|
-
metric_hash.keys.find { |k| k == meta_with_backtrace }.backtrace = meta_with_backtrace.backtrace
|
59
|
-
end
|
60
|
-
metric_hash
|
54
|
+
@points,
|
55
|
+
limited?)
|
61
56
|
end
|
62
57
|
|
63
58
|
# Full metrics from this request. These get stored permanently in a SlowTransaction.
|
64
59
|
# Some merging of metrics will happen here, so if a request calls the same
|
65
60
|
# ActiveRecord or View repeatedly, it'll get merged.
|
66
|
-
#
|
61
|
+
#
|
67
62
|
# This returns a 2-element of Metric Hashes (the first element is timing metrics, the second element is allocation metrics)
|
68
63
|
def create_metrics
|
69
64
|
metric_hash = Hash.new
|
70
65
|
allocation_metric_hash = Hash.new
|
71
66
|
|
72
|
-
|
73
|
-
|
74
|
-
# layers. This lets us push/pop without otherwise keeping track very closely.
|
75
|
-
subscope_layers = []
|
67
|
+
walker.walk do |layer|
|
68
|
+
next if skip_layer?(layer)
|
76
69
|
|
77
|
-
|
78
|
-
if layer.subscopable?
|
79
|
-
subscope_layers.push(layer)
|
80
|
-
end
|
81
|
-
end
|
70
|
+
debug_scoutprof(layer)
|
82
71
|
|
83
|
-
|
84
|
-
|
85
|
-
subscope_layers.pop
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
walker.walk do |layer|
|
90
|
-
# Sometimes we start capturing a layer without knowing if we really
|
91
|
-
# want to make an entry for it. See ActiveRecord instrumentation for
|
92
|
-
# an example. We start capturing before we know if a query is cached
|
93
|
-
# or not, and want to skip any cached queries.
|
94
|
-
if layer.annotations[:ignorable]
|
95
|
-
next
|
96
|
-
end
|
97
|
-
|
98
|
-
meta_options = if subscope_layers.first && layer != subscope_layers.first # Don't scope under ourself.
|
99
|
-
subscope_name = subscope_layers.first.legacy_metric_name
|
100
|
-
{:scope => subscope_name}
|
101
|
-
elsif layer == scope_layer # We don't scope the controller under itself
|
102
|
-
{}
|
103
|
-
else
|
104
|
-
{:scope => scope_layer.legacy_metric_name}
|
105
|
-
end
|
106
|
-
|
107
|
-
# Specific Metric
|
108
|
-
meta_options.merge!(:desc => layer.desc.to_s) if layer.desc
|
109
|
-
meta = MetricMeta.new(layer.legacy_metric_name, meta_options)
|
110
|
-
meta.extra.merge!(layer.annotations)
|
111
|
-
if layer.backtrace
|
112
|
-
bt = ScoutApm::Utils::BacktraceParser.new(layer.backtrace).call
|
113
|
-
if bt.any? # we could walk thru the call stack and not find in-app code
|
114
|
-
meta.backtrace = bt
|
115
|
-
# Why not just call meta.backtrace and call it done? The walker
|
116
|
-
# could access a later later that generates the same MetricMeta
|
117
|
-
# but doesn't have a backtrace. This could be lost in the
|
118
|
-
# metric_hash if it is replaced by the new key.
|
119
|
-
@backtraces << meta
|
120
|
-
else
|
121
|
-
ScoutApm::Agent.instance.logger.debug { "Unable to capture an app-specific backtrace for #{meta.inspect}\n#{layer.backtrace}" }
|
122
|
-
end
|
123
|
-
end
|
124
|
-
metric_hash[meta] ||= MetricStats.new( meta_options.has_key?(:scope) )
|
125
|
-
allocation_metric_hash[meta] ||= MetricStats.new( meta_options.has_key?(:scope) )
|
126
|
-
# timing
|
127
|
-
stat = metric_hash[meta]
|
128
|
-
stat.update!(layer.total_call_time, layer.total_exclusive_time)
|
129
|
-
stat.add_traces(layer.traces.as_json)
|
130
|
-
|
131
|
-
# Debug logging for scoutprof traces
|
132
|
-
if ScoutApm::Agent.instance.config.value('profile')
|
133
|
-
if layer.type =~ %r{^(Controller|Queue|Job)$}.freeze
|
134
|
-
ScoutApm::Agent.instance.logger.debug do
|
135
|
-
traces_inspect = layer.traces.inspect
|
136
|
-
"****** Slow Request #{layer.type} Traces (#{layer.name}, tet: #{layer.total_exclusive_time}, tct: #{layer.total_call_time}), total raw traces: #{layer.traces.cube.total_count}, total clean traces: #{layer.traces.total_count}, skipped gc: #{layer.traces.skipped_in_gc}, skipped handler: #{layer.traces.skipped_in_handler}, skipped registered #{layer.traces.skipped_in_job_registered}, skipped not_running #{layer.traces.skipped_in_not_running}:\n#{traces_inspect}"
|
137
|
-
end
|
138
|
-
end
|
139
|
-
else
|
140
|
-
if layer.type =~ %r{^(Controller|Queue|Job)$}.freeze
|
141
|
-
ScoutApm::Agent.instance.logger.debug "****** Slow Request #{layer.type} Traces: Scoutprof is not enabled"
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
# allocations
|
146
|
-
stat = allocation_metric_hash[meta]
|
147
|
-
stat.update!(layer.total_allocations, layer.total_exclusive_allocations)
|
148
|
-
|
149
|
-
# Merged Metric (no specifics, just sum up by type)
|
150
|
-
meta = MetricMeta.new("#{layer.type}/all")
|
151
|
-
metric_hash[meta] ||= MetricStats.new(false)
|
152
|
-
allocation_metric_hash[meta] ||= MetricStats.new(false)
|
153
|
-
# timing
|
154
|
-
stat = metric_hash[meta]
|
155
|
-
stat.update!(layer.total_call_time, layer.total_exclusive_time)
|
156
|
-
# allocations
|
157
|
-
stat = allocation_metric_hash[meta]
|
158
|
-
stat.update!(layer.total_allocations, layer.total_exclusive_allocations)
|
72
|
+
store_specific_metric(layer, metric_hash, allocation_metric_hash)
|
73
|
+
store_aggregate_metric(layer, metric_hash, allocation_metric_hash)
|
159
74
|
end
|
160
75
|
|
161
76
|
metric_hash = attach_backtraces(metric_hash)
|
162
77
|
allocation_metric_hash = attach_backtraces(allocation_metric_hash)
|
163
78
|
|
164
|
-
[metric_hash,allocation_metric_hash]
|
79
|
+
[metric_hash, allocation_metric_hash]
|
165
80
|
end
|
166
81
|
end
|
167
82
|
end
|
data/lib/scout_apm/metric_set.rb
CHANGED
data/lib/scout_apm/reporter.rb
CHANGED
@@ -17,31 +17,38 @@ module ScoutApm
|
|
17
17
|
@instant_key = instant_key
|
18
18
|
end
|
19
19
|
|
20
|
-
# TODO: Parse & return a real response object, not the HTTP Response object
|
21
20
|
def report(payload, headers = {})
|
22
|
-
|
23
|
-
hosts = [:deploy_hook, :instant_trace].include?(type) ? config.value('direct_host') : config.value('host')
|
21
|
+
hosts = determine_hosts
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
23
|
+
if config.value('compress_payload')
|
24
|
+
original_payload_size = payload.length
|
25
|
+
|
26
|
+
payload, compression_headers = compress_payload(payload)
|
27
|
+
headers.merge!(compression_headers)
|
28
|
+
|
29
|
+
compress_payload_size = payload.length
|
30
|
+
ScoutApm::Agent.instance.logger.debug("Compressed Payload: #{payload.inspect}")
|
31
|
+
ScoutApm::Agent.instance.logger.debug("Original Size: #{original_payload_size} Compressed Size: #{compress_payload_size}")
|
31
32
|
end
|
33
|
+
|
34
|
+
post_payload(hosts, payload, headers)
|
32
35
|
end
|
33
36
|
|
34
37
|
def uri(host)
|
38
|
+
encoded_app_name = CGI.escape(Environment.instance.application_name)
|
39
|
+
encoded_name = CGI.escape(config.value('name'))
|
40
|
+
key = config.value('key')
|
41
|
+
|
35
42
|
case type
|
36
43
|
when :checkin
|
37
|
-
URI.parse("#{host}/apps/checkin.scout?key=#{
|
44
|
+
URI.parse("#{host}/apps/checkin.scout?key=#{key}&name=#{encoded_app_name}")
|
38
45
|
when :app_server_load
|
39
|
-
URI.parse("#{host}/apps/app_server_load.scout?key=#{
|
46
|
+
URI.parse("#{host}/apps/app_server_load.scout?key=#{key}&name=#{encoded_app_name}")
|
40
47
|
when :deploy_hook
|
41
|
-
URI.parse("#{host}/apps/deploy.scout?key=#{
|
48
|
+
URI.parse("#{host}/apps/deploy.scout?key=#{key}&name=#{encoded_name}")
|
42
49
|
when :instant_trace
|
43
|
-
URI.parse("#{host}/apps/instant_trace.scout?key=#{
|
44
|
-
end.tap{|u| logger.debug("Posting to #{u
|
50
|
+
URI.parse("#{host}/apps/instant_trace.scout?key=#{key}&name=#{encoded_name}&instant_key=#{instant_key}")
|
51
|
+
end.tap { |u| logger.debug("Posting to #{u}") }
|
45
52
|
end
|
46
53
|
|
47
54
|
def can_report?
|
@@ -106,7 +113,10 @@ module ScoutApm
|
|
106
113
|
# Net::HTTP::Proxy returns a regular Net::HTTP class if the first argument (host) is nil.
|
107
114
|
def http(url)
|
108
115
|
proxy_uri = URI.parse(config.value('proxy').to_s)
|
109
|
-
http = Net::HTTP::Proxy(proxy_uri.host,
|
116
|
+
http = Net::HTTP::Proxy(proxy_uri.host,
|
117
|
+
proxy_uri.port,
|
118
|
+
proxy_uri.user,
|
119
|
+
proxy_uri.password).new(url.host, url.port)
|
110
120
|
if url.is_a?(URI::HTTPS)
|
111
121
|
http.use_ssl = true
|
112
122
|
http.ca_file = CA_FILE
|
@@ -114,5 +124,33 @@ module ScoutApm
|
|
114
124
|
end
|
115
125
|
http
|
116
126
|
end
|
127
|
+
|
128
|
+
def compress_payload(payload)
|
129
|
+
[
|
130
|
+
ScoutApm::Utils::GzipHelper.new.deflate(payload),
|
131
|
+
{ 'Content-Encoding' => 'gzip' }
|
132
|
+
]
|
133
|
+
end
|
134
|
+
|
135
|
+
# Some posts (typically ones under development) bypass the ingestion
|
136
|
+
# pipeline and go directly to the webserver. They use direct_host instead
|
137
|
+
# of host
|
138
|
+
def determine_hosts
|
139
|
+
if [:deploy_hook, :instant_trace].include?(type)
|
140
|
+
config.value('direct_host')
|
141
|
+
else
|
142
|
+
config.value('host')
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def post_payload(hosts, payload, headers)
|
147
|
+
Array(hosts).each do |host|
|
148
|
+
full_uri = uri(host)
|
149
|
+
response = post(full_uri, payload, headers)
|
150
|
+
unless response && response.is_a?(Net::HTTPSuccess)
|
151
|
+
logger.warn "Error on checkin to #{full_uri}: #{response.inspect}"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
117
155
|
end
|
118
156
|
end
|