instana 1.195.4 → 1.197.0.pre1
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/.rubocop.yml +6 -2
- data/Rakefile +1 -1
- data/instana.gemspec +3 -7
- data/lib/instana.rb +3 -0
- data/lib/instana/activator.rb +2 -0
- data/lib/instana/backend/agent.rb +60 -0
- data/lib/instana/backend/gc_snapshot.rb +41 -0
- data/lib/instana/backend/host_agent.rb +57 -0
- data/lib/instana/backend/host_agent_activation_observer.rb +87 -0
- data/lib/instana/backend/host_agent_lookup.rb +57 -0
- data/lib/instana/backend/host_agent_reporting_observer.rb +106 -0
- data/lib/instana/backend/process_info.rb +64 -0
- data/lib/instana/backend/request_client.rb +84 -0
- data/lib/instana/backend/serverless_agent.rb +118 -0
- data/lib/instana/base.rb +8 -27
- data/lib/instana/config.rb +7 -21
- data/lib/instana/logger_delegator.rb +31 -0
- data/lib/instana/{opentracing → open_tracing}/carrier.rb +0 -0
- data/lib/instana/open_tracing/instana_tracer.rb +99 -0
- data/lib/instana/secrets.rb +6 -2
- data/lib/instana/setup.rb +20 -11
- data/lib/instana/snapshot/deltable.rb +25 -0
- data/lib/instana/snapshot/docker_container.rb +151 -0
- data/lib/instana/snapshot/fargate_container.rb +88 -0
- data/lib/instana/snapshot/fargate_process.rb +67 -0
- data/lib/instana/snapshot/fargate_task.rb +72 -0
- data/lib/instana/snapshot/ruby_process.rb +48 -0
- data/lib/instana/tracer.rb +25 -143
- data/lib/instana/tracing/processor.rb +4 -22
- data/lib/instana/tracing/span.rb +26 -35
- data/lib/instana/tracing/span_context.rb +1 -1
- data/lib/instana/util.rb +4 -67
- data/lib/instana/version.rb +1 -1
- data/lib/opentracing.rb +26 -3
- data/test/backend/agent_test.rb +54 -0
- data/test/backend/gc_snapshot_test.rb +11 -0
- data/test/backend/host_agent_activation_observer_test.rb +65 -0
- data/test/backend/host_agent_lookup_test.rb +78 -0
- data/test/backend/host_agent_reporting_observer_test.rb +192 -0
- data/test/backend/host_agent_test.rb +32 -0
- data/test/backend/process_info_test.rb +63 -0
- data/test/backend/request_client_test.rb +61 -0
- data/test/backend/serverless_agent_test.rb +73 -0
- data/test/config_test.rb +10 -0
- data/test/instana_test.rb +11 -4
- data/test/instrumentation/rack_instrumented_request_test.rb +3 -2
- data/test/instrumentation/rack_test.rb +2 -14
- data/test/secrets_test.rb +41 -22
- data/test/snapshot/deltable_test.rb +17 -0
- data/test/snapshot/docker_container_test.rb +82 -0
- data/test/snapshot/fargate_container_test.rb +82 -0
- data/test/snapshot/fargate_process_test.rb +35 -0
- data/test/snapshot/fargate_task_test.rb +49 -0
- data/test/snapshot/ruby_process_test.rb +14 -0
- data/test/support/mock_timer.rb +20 -0
- data/test/test_helper.rb +15 -3
- data/test/tracing/custom_test.rb +1 -3
- data/test/tracing/id_management_test.rb +4 -0
- data/test/tracing/opentracing_test.rb +15 -2
- data/test/tracing/processor_test.rb +58 -0
- data/test/tracing/span_context_test.rb +22 -0
- data/test/tracing/span_test.rb +127 -0
- data/test/tracing/tracer_async_test.rb +29 -0
- data/test/tracing/tracer_test.rb +82 -16
- data/test/util_test.rb +10 -0
- metadata +72 -45
- data/lib/instana/agent.rb +0 -508
- data/lib/instana/agent/helpers.rb +0 -87
- data/lib/instana/agent/hooks.rb +0 -44
- data/lib/instana/agent/tasks.rb +0 -51
- data/lib/instana/collector.rb +0 -119
- data/lib/instana/collectors/gc.rb +0 -60
- data/lib/instana/collectors/memory.rb +0 -37
- data/lib/instana/collectors/thread.rb +0 -33
- data/lib/instana/eum/eum-test.js.erb +0 -17
- data/lib/instana/eum/eum.js.erb +0 -17
- data/lib/instana/helpers.rb +0 -47
- data/lib/instana/opentracing/tracer.rb +0 -21
- data/lib/instana/thread_local.rb +0 -18
- data/lib/oj_check.rb +0 -19
- data/test/agent/agent_test.rb +0 -151
data/lib/instana/agent.rb
DELETED
@@ -1,508 +0,0 @@
|
|
1
|
-
# (c) Copyright IBM Corp. 2021
|
2
|
-
# (c) Copyright Instana Inc. 2016
|
3
|
-
|
4
|
-
require 'net/http'
|
5
|
-
require 'socket'
|
6
|
-
require 'sys/proctable'
|
7
|
-
require 'timers'
|
8
|
-
require 'uri'
|
9
|
-
require 'thread'
|
10
|
-
|
11
|
-
require 'instana/agent/helpers'
|
12
|
-
require 'instana/agent/hooks'
|
13
|
-
require 'instana/agent/tasks'
|
14
|
-
|
15
|
-
include Sys
|
16
|
-
|
17
|
-
module Instana
|
18
|
-
OJ_OPTIONS = {:mode => :strict}
|
19
|
-
|
20
|
-
class Agent
|
21
|
-
include AgentHelpers
|
22
|
-
include AgentHooks
|
23
|
-
include AgentTasks
|
24
|
-
|
25
|
-
attr_accessor :state
|
26
|
-
attr_accessor :agent_uuid
|
27
|
-
attr_accessor :process
|
28
|
-
attr_accessor :collect_thread
|
29
|
-
attr_accessor :thread_spawn_lock
|
30
|
-
attr_accessor :extra_headers
|
31
|
-
attr_reader :secret_values
|
32
|
-
|
33
|
-
attr_accessor :testmode
|
34
|
-
|
35
|
-
LOCALHOST = '127.0.0.1'.freeze
|
36
|
-
MIME_JSON = 'application/json'.freeze
|
37
|
-
DISCOVERY_PATH = 'com.instana.plugin.ruby.discovery'.freeze
|
38
|
-
METRICS_PATH = "com.instana.plugin.ruby.%s"
|
39
|
-
TRACES_PATH = "com.instana.plugin.ruby/traces.%s"
|
40
|
-
|
41
|
-
def initialize
|
42
|
-
@testmode = ENV.key?('INSTANA_TEST')
|
43
|
-
|
44
|
-
# Supported two states (unannounced & announced)
|
45
|
-
@state = :unannounced
|
46
|
-
|
47
|
-
# Timestamp of the last successful response from
|
48
|
-
# entity data reporting.
|
49
|
-
@entity_last_seen = Time.now
|
50
|
-
|
51
|
-
# Used to track the last time the collect timer was run.
|
52
|
-
@last_collect_run = Time.now
|
53
|
-
|
54
|
-
# Two timers, one for each state (unannounced & announced)
|
55
|
-
@timers = ::Timers::Group.new
|
56
|
-
@announce_timer = nil
|
57
|
-
@pending_timer = nil
|
58
|
-
@collect_timer = nil
|
59
|
-
|
60
|
-
@thread_spawn_lock = Mutex.new
|
61
|
-
|
62
|
-
# Detect platform flags
|
63
|
-
@is_linux = (RbConfig::CONFIG['host_os'] =~ /linux/i) ? true : false
|
64
|
-
@is_osx = (RUBY_PLATFORM =~ /darwin/i) ? true : false
|
65
|
-
|
66
|
-
# In case we're running in Docker, have the default gateway available
|
67
|
-
# to check in case we're running in bridged network mode
|
68
|
-
if @is_linux && File.exist?("/sbin/ip")
|
69
|
-
@default_gateway = `/sbin/ip route | awk '/default/ { print $3 }'`.chomp
|
70
|
-
else
|
71
|
-
@default_gateway = nil
|
72
|
-
end
|
73
|
-
|
74
|
-
# Re-useable HTTP client for communication with
|
75
|
-
# the host agent.
|
76
|
-
@httpclient = nil
|
77
|
-
|
78
|
-
# Collect initial process info - repeat prior to announce
|
79
|
-
# in `announce_sensor` in case of process rename, after fork etc.
|
80
|
-
@process = ::Instana::Util.collect_process_info
|
81
|
-
|
82
|
-
# The agent UUID returned from the host agent
|
83
|
-
@agent_uuid = nil
|
84
|
-
|
85
|
-
# This will hold info on the discovered agent host
|
86
|
-
@discovered = nil
|
87
|
-
|
88
|
-
# The agent may pass down custom headers for this sensor to capture
|
89
|
-
@extra_headers = nil
|
90
|
-
|
91
|
-
# The values considered sensitive and removed from http query parameters
|
92
|
-
# and database connection strings
|
93
|
-
@secret_values = nil
|
94
|
-
end
|
95
|
-
|
96
|
-
# Spawns the background thread and calls start. This method is separated
|
97
|
-
# out for those who wish to control which thread the background agent will
|
98
|
-
# run in.
|
99
|
-
#
|
100
|
-
# This method can be overridden with the following:
|
101
|
-
#
|
102
|
-
# module Instana
|
103
|
-
# class Agent
|
104
|
-
# def spawn_background_thread
|
105
|
-
# # start thread
|
106
|
-
# start
|
107
|
-
# end
|
108
|
-
# end
|
109
|
-
# end
|
110
|
-
#
|
111
|
-
def spawn_background_thread
|
112
|
-
@thread_spawn_lock.synchronize {
|
113
|
-
if @collect_thread && @collect_thread.alive?
|
114
|
-
::Instana.logger.info "[instana] Collect thread already started & alive. Not spawning another."
|
115
|
-
else
|
116
|
-
@collect_thread = Thread.new do
|
117
|
-
start
|
118
|
-
end
|
119
|
-
end
|
120
|
-
}
|
121
|
-
end
|
122
|
-
|
123
|
-
# Sets up periodic timers and starts the agent in a background thread.
|
124
|
-
#
|
125
|
-
# There are three possible states for the agent:
|
126
|
-
# - :unannounced
|
127
|
-
# - :announced
|
128
|
-
# - :ready
|
129
|
-
def setup
|
130
|
-
if ENV.key?('INSTANA_DISABLE')
|
131
|
-
::Instana.logger.info "Instana gem disabled via environment variable (INSTANA_DISABLE). Going to sit in a corner..."
|
132
|
-
end
|
133
|
-
|
134
|
-
# The announce timer
|
135
|
-
# We attempt to announce this ruby sensor to the host agent.
|
136
|
-
# In case of failure, we try again in 30 seconds.
|
137
|
-
@announce_timer = @timers.now_and_every(30) do
|
138
|
-
if @state == :unannounced && !ENV.key?('INSTANA_DISABLE')
|
139
|
-
if host_agent_available? && announce_sensor
|
140
|
-
transition_to(:announced)
|
141
|
-
::Instana.logger.debug "Announce successful. Waiting on ready. (#{@state} pid:#{Process.pid} #{@process[:name]})"
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
# The pending timer
|
147
|
-
# Handles the time between successful announce and when the host agent METRICS_PATH and TRACES_PATH
|
148
|
-
# no longer return 404s and are truly ready to accept data.
|
149
|
-
@pending_timer = @timers.now_and_every(1) do
|
150
|
-
path = sprintf(METRICS_PATH, @process[:report_pid])
|
151
|
-
uri = URI.parse("http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/#{path}")
|
152
|
-
req = Net::HTTP::Post.new(uri)
|
153
|
-
req.body = Oj.dump({}, OJ_OPTIONS)
|
154
|
-
|
155
|
-
response = make_host_agent_request(req)
|
156
|
-
if response && (response.code.to_i == 200)
|
157
|
-
transition_to(:ready)
|
158
|
-
::Instana.logger.info "Host agent available. We're in business. (#{@state} pid:#{Process.pid} #{@process[:name]})"
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
# The collect timer
|
163
|
-
# If we are in announced state, send metric data (only delta reporting)
|
164
|
-
# every ::Instana.config[:collector][:interval] seconds.
|
165
|
-
@collect_timer = @timers.every(::Instana.config[:collector][:interval]) do
|
166
|
-
# Make sure that this block doesn't get called more often than the interval. This can
|
167
|
-
# happen on high CPU load and a back up of timer runs. If we are called before `interval`
|
168
|
-
# then we just skip.
|
169
|
-
unless (Time.now - @last_collect_run) < ::Instana.config[:collector][:interval]
|
170
|
-
@last_collect_run = Time.now
|
171
|
-
if @state == :ready
|
172
|
-
if !::Instana.collector.collect_and_report
|
173
|
-
# If report has been failing for more than 1 minute,
|
174
|
-
# fall back to unannounced state
|
175
|
-
if (Time.now - @entity_last_seen) > 60
|
176
|
-
::Instana.logger.warn "Host agent offline for >1 min. Going to sit in a corner..."
|
177
|
-
transition_to(:unannounced)
|
178
|
-
end
|
179
|
-
end
|
180
|
-
::Instana.processor.send
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
# Starts the timer loop for the timers that were initialized
|
187
|
-
# in the setup method. This is blocking and should only be
|
188
|
-
# called from an already initialized background thread.
|
189
|
-
#
|
190
|
-
def start
|
191
|
-
if !ENV.key?('INSTANA_DISABLE') && !host_agent_available?
|
192
|
-
if !ENV.key?("INSTANA_QUIET")
|
193
|
-
::Instana.logger.info "Instana host agent not available. Will retry periodically. (Set env INSTANA_QUIET=1 to shut these messages off)"
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
while true
|
198
|
-
if @state == :unannounced
|
199
|
-
@announce_timer.resume
|
200
|
-
@pending_timer.pause
|
201
|
-
@collect_timer.pause
|
202
|
-
elsif @state == :announced
|
203
|
-
@announce_timer.pause
|
204
|
-
@pending_timer.resume
|
205
|
-
@collect_timer.pause
|
206
|
-
elsif @state == :ready
|
207
|
-
@announce_timer.pause
|
208
|
-
@pending_timer.pause
|
209
|
-
@collect_timer.resume
|
210
|
-
end
|
211
|
-
@timers.wait
|
212
|
-
end
|
213
|
-
rescue Exception => e
|
214
|
-
::Instana.logger.warn { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" }
|
215
|
-
::Instana.logger.debug { e.backtrace.join("\r\n") }
|
216
|
-
ensure
|
217
|
-
if @state == :ready
|
218
|
-
# Pause the timers so they don't fire while we are reporting traces
|
219
|
-
@announce_timer.pause
|
220
|
-
@pending_timer.pause
|
221
|
-
@collect_timer.pause
|
222
|
-
|
223
|
-
::Instana.logger.debug { "#{Thread.current}: Agent exiting. Reporting final spans (if any)." }
|
224
|
-
::Instana.processor.send
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
# Collect process ID, name and arguments to notify
|
229
|
-
# the host agent.
|
230
|
-
#
|
231
|
-
def announce_sensor
|
232
|
-
unless @discovered
|
233
|
-
::Instana.logger.debug("#{__method__} called but discovery hasn't run yet!")
|
234
|
-
return false
|
235
|
-
end
|
236
|
-
|
237
|
-
# Always re-collect process info before announce in case the process name has been
|
238
|
-
# re-written (looking at you puma!)
|
239
|
-
@process = ::Instana::Util.collect_process_info
|
240
|
-
|
241
|
-
announce_payload = {}
|
242
|
-
announce_payload[:name] = @process[:name]
|
243
|
-
announce_payload[:args] = @process[:arguments]
|
244
|
-
|
245
|
-
socket = nil
|
246
|
-
if @is_linux && !@testmode
|
247
|
-
# We create an open socket to the host agent in case we are running in a container
|
248
|
-
# and the real pid needs to be detected.
|
249
|
-
socket = TCPSocket.open @discovered[:agent_host], @discovered[:agent_port]
|
250
|
-
|
251
|
-
announce_payload[:fd] = socket.fileno
|
252
|
-
announce_payload[:inode] = File.readlink("/proc/self/fd/#{socket.fileno}")
|
253
|
-
announce_payload[:cpuSetFileContent] = get_cpuset_contents
|
254
|
-
|
255
|
-
sched_pid = get_sched_pid
|
256
|
-
announce_payload[:pid] = sched_pid
|
257
|
-
|
258
|
-
if running_in_container?
|
259
|
-
if sched_pid != Process.pid
|
260
|
-
# In container: sched reveals true PID
|
261
|
-
announce_payload[:pidFromParentNS] = true
|
262
|
-
else
|
263
|
-
# In container: sched told us nothing
|
264
|
-
announce_payload[:pidFromParentNS] = false
|
265
|
-
end
|
266
|
-
else
|
267
|
-
# Not in a container
|
268
|
-
announce_payload[:pidFromParentNS] = true
|
269
|
-
end
|
270
|
-
|
271
|
-
else
|
272
|
-
announce_payload[:pid] = Process.pid
|
273
|
-
announce_payload[:pidFromParentNS] = true
|
274
|
-
end
|
275
|
-
|
276
|
-
uri = URI.parse("http://#{@discovered[:agent_host]}:#{@discovered[:agent_port]}/#{DISCOVERY_PATH}")
|
277
|
-
req = Net::HTTP::Put.new(uri)
|
278
|
-
req.body = Oj.dump(announce_payload, OJ_OPTIONS)
|
279
|
-
|
280
|
-
#::Instana.logger.debug("Announce payload: #{announce_payload}")
|
281
|
-
#::Instana.logger.debug { "Announce: http://#{@discovered[:agent_host]}:#{@discovered[:agent_port]}/#{DISCOVERY_PATH} - payload: #{req.body}" }
|
282
|
-
|
283
|
-
response = make_host_agent_request(req, open_timeout=3, read_timeout=3, debug=true)
|
284
|
-
|
285
|
-
if response && (response.code.to_i == 200)
|
286
|
-
data = Oj.load(response.body, OJ_OPTIONS)
|
287
|
-
@process[:report_pid] = data['pid']
|
288
|
-
@agent_uuid = data['agentUuid']
|
289
|
-
@secret_values = data['secrets']
|
290
|
-
|
291
|
-
if data.key?('extraHeaders')
|
292
|
-
@extra_headers = data['extraHeaders']
|
293
|
-
end
|
294
|
-
true
|
295
|
-
else
|
296
|
-
false
|
297
|
-
end
|
298
|
-
rescue => e
|
299
|
-
Instana.logger.info { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" }
|
300
|
-
Instana.logger.debug { e.backtrace.join("\r\n") }
|
301
|
-
return false
|
302
|
-
ensure
|
303
|
-
socket.close if socket && !socket.closed?
|
304
|
-
end
|
305
|
-
|
306
|
-
# Method to report metrics data to the host agent.
|
307
|
-
#
|
308
|
-
# @param paylod [Hash] The collection of metrics to report.
|
309
|
-
#
|
310
|
-
# @return [Boolean] true on success, false otherwise
|
311
|
-
#
|
312
|
-
def report_metrics(payload)
|
313
|
-
if @state != :ready && !@testmode
|
314
|
-
::Instana.logger.debug "report_metrics called but agent not in ready state."
|
315
|
-
return false
|
316
|
-
end
|
317
|
-
|
318
|
-
path = sprintf(METRICS_PATH, @process[:report_pid])
|
319
|
-
uri = URI.parse("http://#{@discovered[:agent_host]}:#{@discovered[:agent_port]}/#{path}")
|
320
|
-
req = Net::HTTP::Post.new(uri)
|
321
|
-
|
322
|
-
req.body = Oj.dump(payload, OJ_OPTIONS)
|
323
|
-
response = make_host_agent_request(req)
|
324
|
-
|
325
|
-
if response
|
326
|
-
if response.body && response.body.length > 2
|
327
|
-
# The host agent returned something indicating that is has a request for us that we
|
328
|
-
# need to process.
|
329
|
-
handle_agent_tasks(response.body)
|
330
|
-
end
|
331
|
-
|
332
|
-
if response.code.to_i == 200
|
333
|
-
@entity_last_seen = Time.now
|
334
|
-
return true
|
335
|
-
end
|
336
|
-
|
337
|
-
end
|
338
|
-
false
|
339
|
-
rescue => e
|
340
|
-
Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" }
|
341
|
-
Instana.logger.debug { e.backtrace.join("\r\n") }
|
342
|
-
end
|
343
|
-
|
344
|
-
# Accept and report spans to the host agent.
|
345
|
-
#
|
346
|
-
# @param spans [Array] An array of [Span]
|
347
|
-
# @return [Boolean]
|
348
|
-
#
|
349
|
-
def report_spans(spans)
|
350
|
-
if @state != :ready && !@testmode
|
351
|
-
::Instana.logger.debug "report_spans called but agent not in ready state."
|
352
|
-
return false
|
353
|
-
end
|
354
|
-
|
355
|
-
::Instana.logger.debug "Reporting #{spans.length} spans"
|
356
|
-
|
357
|
-
path = sprintf(TRACES_PATH, @process[:report_pid])
|
358
|
-
uri = URI.parse("http://#{@discovered[:agent_host]}:#{@discovered[:agent_port]}/#{path}")
|
359
|
-
req = Net::HTTP::Post.new(uri)
|
360
|
-
|
361
|
-
opts = OJ_OPTIONS.merge({omit_nil: true})
|
362
|
-
|
363
|
-
req.body = Oj.dump(spans, opts)
|
364
|
-
response = make_host_agent_request(req)
|
365
|
-
|
366
|
-
if response
|
367
|
-
last_trace_response = response.code.to_i
|
368
|
-
|
369
|
-
if [200, 204].include?(last_trace_response)
|
370
|
-
return true
|
371
|
-
end
|
372
|
-
end
|
373
|
-
false
|
374
|
-
rescue => e
|
375
|
-
Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" }
|
376
|
-
Instana.logger.debug { e.backtrace.join("\r\n") }
|
377
|
-
end
|
378
|
-
|
379
|
-
# Check that the host agent is available and can be contacted. This will
|
380
|
-
# first check localhost and if not, then attempt on the default gateway
|
381
|
-
# for docker in bridged mode.
|
382
|
-
#
|
383
|
-
def host_agent_available?
|
384
|
-
@discovered ||= run_discovery
|
385
|
-
|
386
|
-
if @discovered
|
387
|
-
return true
|
388
|
-
end
|
389
|
-
false
|
390
|
-
rescue => e
|
391
|
-
Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" }
|
392
|
-
Instana.logger.debug { e.backtrace.join("\r\n") } unless @testmode
|
393
|
-
return false
|
394
|
-
end
|
395
|
-
|
396
|
-
# Runs a discovery process to determine where we can contact the host agent. This is usually just
|
397
|
-
# localhost but in docker can be found on the default gateway. Another option is the INSTANA_AGENT_HOST
|
398
|
-
# environment variable. This also allows for manual configuration via ::Instana.config[:agent_host/port].
|
399
|
-
#
|
400
|
-
# @return [Hash] a hash with :agent_host, :agent_port values or empty hash
|
401
|
-
#
|
402
|
-
def run_discovery
|
403
|
-
discovered = {}
|
404
|
-
|
405
|
-
::Instana.logger.debug { "#{__method__}: Running agent discovery..." }
|
406
|
-
|
407
|
-
# Try default location or manually configured (if so)
|
408
|
-
uri = URI.parse("http://#{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}/")
|
409
|
-
req = Net::HTTP::Get.new(uri)
|
410
|
-
|
411
|
-
::Instana.logger.debug { "#{__method__}: Trying #{::Instana.config[:agent_host]}:#{::Instana.config[:agent_port]}" }
|
412
|
-
|
413
|
-
response = make_host_agent_request(req)
|
414
|
-
|
415
|
-
if response && (response.code.to_i == 200)
|
416
|
-
discovered[:agent_host] = ::Instana.config[:agent_host]
|
417
|
-
discovered[:agent_port] = ::Instana.config[:agent_port]
|
418
|
-
::Instana.logger.debug { "#{__method__}: Found #{discovered[:agent_host]}:#{discovered[:agent_port]}" }
|
419
|
-
return discovered
|
420
|
-
end
|
421
|
-
|
422
|
-
return nil unless @is_linux
|
423
|
-
|
424
|
-
# We are potentially running on Docker in bridged networking mode.
|
425
|
-
# Attempt to contact default gateway
|
426
|
-
uri = URI.parse("http://#{@default_gateway}:#{::Instana.config[:agent_port]}/")
|
427
|
-
req = Net::HTTP::Get.new(uri)
|
428
|
-
|
429
|
-
::Instana.logger.debug { "#{__method__}: Trying default gateway #{@default_gateway}:#{::Instana.config[:agent_port]}" }
|
430
|
-
|
431
|
-
response = make_host_agent_request(req)
|
432
|
-
|
433
|
-
if response && (response.code.to_i == 200)
|
434
|
-
discovered[:agent_host] = @default_gateway
|
435
|
-
discovered[:agent_port] = ::Instana.config[:agent_port]
|
436
|
-
::Instana.logger.debug { "#{__method__}: Found #{discovered[:agent_host]}:#{discovered[:agent_port]}" }
|
437
|
-
return discovered
|
438
|
-
end
|
439
|
-
|
440
|
-
nil
|
441
|
-
end
|
442
|
-
|
443
|
-
private
|
444
|
-
|
445
|
-
# Handles any/all steps required in the transtion
|
446
|
-
# between states.
|
447
|
-
#
|
448
|
-
# @param state [Symbol] Can be 1 of 2 possible states:
|
449
|
-
# `:announced`, `:unannounced`
|
450
|
-
#
|
451
|
-
def transition_to(state)
|
452
|
-
::Instana.logger.debug("Transitioning to #{state}")
|
453
|
-
case state
|
454
|
-
when :ready
|
455
|
-
# announced
|
456
|
-
@state = :ready
|
457
|
-
|
458
|
-
# Reset the entity timer
|
459
|
-
@entity_last_seen = Time.now
|
460
|
-
when :announced
|
461
|
-
# announce successful; set state
|
462
|
-
@state = :announced
|
463
|
-
|
464
|
-
# Reset the entity timer
|
465
|
-
@entity_last_seen = Time.now
|
466
|
-
when :unannounced
|
467
|
-
@state = :unannounced
|
468
|
-
# Reset our HTTP client
|
469
|
-
@httpclient = nil
|
470
|
-
else
|
471
|
-
::Instana.logger.debug "Uknown agent state: #{state}"
|
472
|
-
end
|
473
|
-
::Instana.collector.reset_snapshot_timer!
|
474
|
-
true
|
475
|
-
end
|
476
|
-
|
477
|
-
# Centralization of the net/http communications
|
478
|
-
# with the host agent. Pass in a prepared <req>
|
479
|
-
# of type Net::HTTP::Get|Put|Head
|
480
|
-
#
|
481
|
-
# @param req [Net::HTTP::Req] A prepared Net::HTTP request object of the type
|
482
|
-
# you wish to make (Get, Put, Post etc.)
|
483
|
-
#
|
484
|
-
def make_host_agent_request(req, open_timeout=1, read_timeout=1, debug=false)
|
485
|
-
req['Accept'] = MIME_JSON
|
486
|
-
req['Content-Type'] = MIME_JSON
|
487
|
-
|
488
|
-
if @state == :unannounced
|
489
|
-
@httpclient = Net::HTTP.new(req.uri.hostname, req.uri.port)
|
490
|
-
@httpclient.open_timeout = open_timeout
|
491
|
-
@httpclient.read_timeout = read_timeout
|
492
|
-
end
|
493
|
-
|
494
|
-
response = @httpclient.request(req)
|
495
|
-
|
496
|
-
if debug
|
497
|
-
::Instana.logger.debug "#{req.method}->#{req.uri} body:(#{req.body}) Response:#{response} body:(#{response.body})"
|
498
|
-
end
|
499
|
-
|
500
|
-
response
|
501
|
-
rescue Errno::ECONNREFUSED
|
502
|
-
return nil
|
503
|
-
rescue => e
|
504
|
-
Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message} (to #{req.uri})" }
|
505
|
-
return nil
|
506
|
-
end
|
507
|
-
end
|
508
|
-
end
|