instana 1.197.0.pre1 → 1.197.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/lib/instana/backend/host_agent.rb +27 -10
- data/lib/instana/backend/host_agent_activation_observer.rb +17 -7
- data/lib/instana/backend/request_client.rb +4 -15
- data/lib/instana/backend/serverless_agent.rb +1 -1
- data/lib/instana/config.rb +1 -1
- data/lib/instana/instrumentation/excon.rb +7 -5
- data/lib/instana/instrumentation/instrumented_request.rb +62 -7
- data/lib/instana/instrumentation/net-http.rb +7 -5
- data/lib/instana/instrumentation/rack.rb +12 -7
- data/lib/instana/tracing/processor.rb +11 -1
- data/lib/instana/tracing/span.rb +8 -2
- data/lib/instana/tracing/span_context.rb +14 -9
- data/lib/instana/util.rb +4 -2
- data/lib/instana/version.rb +1 -1
- data/test/backend/host_agent_activation_observer_test.rb +16 -9
- data/test/backend/host_agent_test.rb +17 -2
- data/test/backend/request_client_test.rb +0 -22
- data/test/instrumentation/rack_instrumented_request_test.rb +2 -0
- data/test/test_helper.rb +1 -1
- data/test/tracing/span_context_test.rb +1 -2
- data/test/tracing/span_test.rb +9 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 518b5595452badfeb017ea91f89907026f1d21ee0945982dbeb0f1d55662a45a
|
4
|
+
data.tar.gz: 46e3a5473d6e804a54f7e756739e4f34439db51e4e825770763d2647b59eefa8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0025b1437bd30313df97306835a228083e6d6dbd6253e109d9ba67d85f7ce4b03c677ccfbaff9fa3084f5968add9d01ac9dcd60a1d5338b54c37cebf5d3b306
|
7
|
+
data.tar.gz: 7d1fadb443f1ce0304bd4944198300ed0a2043ea9154dbd7fe50b89ed0a101bddd6da7f9086901eac3dc9c95e799a4eb29118fe6c7c8f153908bbb0b75b03788
|
@@ -5,22 +5,29 @@ module Instana
|
|
5
5
|
module Backend
|
6
6
|
# @since 1.197.0
|
7
7
|
class HostAgent
|
8
|
-
|
8
|
+
attr_reader :future
|
9
|
+
|
10
|
+
def initialize(discovery: Concurrent::Atom.new(nil), logger: ::Instana.logger)
|
9
11
|
@discovery = discovery
|
10
|
-
@
|
12
|
+
@logger = logger
|
13
|
+
@future = nil
|
11
14
|
end
|
12
15
|
|
13
|
-
def setup
|
16
|
+
def setup; end
|
17
|
+
|
18
|
+
def spawn_background_thread
|
14
19
|
return if ENV.key?('INSTANA_TEST')
|
15
20
|
|
16
|
-
@
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
@future = Concurrent::Promises.future do
|
22
|
+
client = until_not_nil { HostAgentLookup.new.call }
|
23
|
+
@discovery.delete_observers
|
24
|
+
@discovery
|
25
|
+
.with_observer(HostAgentActivationObserver.new(client, @discovery))
|
26
|
+
.with_observer(HostAgentReportingObserver.new(client, @discovery))
|
21
27
|
|
22
|
-
|
23
|
-
|
28
|
+
@discovery.swap { nil }
|
29
|
+
client
|
30
|
+
end
|
24
31
|
end
|
25
32
|
|
26
33
|
# @return [Boolean] true if the agent able to send spans to the backend
|
@@ -48,6 +55,16 @@ module Instana
|
|
48
55
|
|
49
56
|
private
|
50
57
|
|
58
|
+
def until_not_nil
|
59
|
+
loop do
|
60
|
+
result = yield
|
61
|
+
return result unless result.nil?
|
62
|
+
|
63
|
+
@logger.debug("Waiting on a connection to the agent.")
|
64
|
+
sleep(1)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
51
68
|
def discovery_value
|
52
69
|
v = @discovery.value
|
53
70
|
v || {}
|
@@ -12,20 +12,23 @@ module Instana
|
|
12
12
|
|
13
13
|
# @param [RequestClient] client used to make requests to the backend
|
14
14
|
# @param [Concurrent::Atom] discovery object used to store discovery response in
|
15
|
-
def initialize(client, discovery, wait_time:
|
15
|
+
def initialize(client, discovery, wait_time: 1, logger: ::Instana.logger, max_wait_tries: 60, proc_table: Sys::ProcTable, socket_proc: default_socket_proc) # rubocop:disable Metrics/ParameterLists
|
16
16
|
@client = client
|
17
17
|
@discovery = discovery
|
18
18
|
@wait_time = wait_time
|
19
19
|
@logger = logger
|
20
20
|
@max_wait_tries = max_wait_tries
|
21
21
|
@proc_table = proc_table
|
22
|
+
@socket_proc = socket_proc
|
22
23
|
end
|
23
24
|
|
24
25
|
def update(_time, _old_version, new_version)
|
25
26
|
return unless new_version.nil?
|
26
27
|
|
28
|
+
socket = @socket_proc.call(@client)
|
29
|
+
|
27
30
|
try_forever_with_backoff do
|
28
|
-
payload = discovery_payload
|
31
|
+
payload = discovery_payload(socket)
|
29
32
|
discovery_response = @client.send_request('PUT', DISCOVERY_URL, payload)
|
30
33
|
|
31
34
|
raise DiscoveryError, "Discovery response was #{discovery_response.code} with `#{payload}`." unless discovery_response.ok?
|
@@ -36,11 +39,13 @@ module Instana
|
|
36
39
|
@logger.debug("Agent ready.")
|
37
40
|
@discovery.swap { discovery }
|
38
41
|
end
|
42
|
+
|
43
|
+
socket.close
|
39
44
|
end
|
40
45
|
|
41
46
|
private
|
42
47
|
|
43
|
-
def discovery_payload
|
48
|
+
def discovery_payload(socket)
|
44
49
|
proc_table = @proc_table.ps(pid: Process.pid)
|
45
50
|
process = ProcessInfo.new(proc_table)
|
46
51
|
|
@@ -52,9 +57,10 @@ module Instana
|
|
52
57
|
cpuSetFileContent: process.cpuset
|
53
58
|
}
|
54
59
|
|
55
|
-
|
56
|
-
|
57
|
-
payload[:
|
60
|
+
inode_path = "/proc/self/fd/#{socket.fileno}"
|
61
|
+
if socket.fileno && File.exist?(inode_path)
|
62
|
+
payload[:fd] = socket.fileno
|
63
|
+
payload[:inode] = File.readlink(inode_path)
|
58
64
|
end
|
59
65
|
|
60
66
|
payload.compact
|
@@ -76,12 +82,16 @@ module Instana
|
|
76
82
|
def try_forever_with_backoff
|
77
83
|
yield
|
78
84
|
rescue DiscoveryError, Net::OpenTimeout => e
|
79
|
-
@logger.
|
85
|
+
@logger.warn(e)
|
80
86
|
sleep(@wait_time)
|
81
87
|
retry
|
82
88
|
rescue StandardError => e
|
83
89
|
@logger.error(%(#{e}\n#{e.backtrace.join("\n")}))
|
84
90
|
end
|
91
|
+
|
92
|
+
def default_socket_proc
|
93
|
+
->(c) { TCPSocket.new(c.host, c.port) }
|
94
|
+
end
|
85
95
|
end
|
86
96
|
end
|
87
97
|
end
|
@@ -18,6 +18,8 @@ module Instana
|
|
18
18
|
# Convince wrapper around {Net::HTTP}.
|
19
19
|
# @since 1.197.0
|
20
20
|
class RequestClient
|
21
|
+
attr_reader :host, :port
|
22
|
+
|
21
23
|
class Response < SimpleDelegator
|
22
24
|
# @return [Hash] the decoded json response
|
23
25
|
def json
|
@@ -31,6 +33,8 @@ module Instana
|
|
31
33
|
end
|
32
34
|
|
33
35
|
def initialize(host, port, use_ssl: false)
|
36
|
+
@host = host
|
37
|
+
@port = port
|
34
38
|
@client = Net::HTTP.start(host, port, use_ssl: use_ssl)
|
35
39
|
end
|
36
40
|
|
@@ -57,21 +61,6 @@ module Instana
|
|
57
61
|
Response.new(response)
|
58
62
|
end
|
59
63
|
|
60
|
-
# @return [Integer, NilClass] the fileno of the Net::HTTP socket or nil if it can't be identified
|
61
|
-
def fileno
|
62
|
-
socket = @client.instance_variable_get('@socket')
|
63
|
-
io = socket && socket.instance_variable_get('@io')
|
64
|
-
io && io.fileno
|
65
|
-
end
|
66
|
-
|
67
|
-
# @return [String] the inode asscoated with the Net::HTTP socket or nil if it can't be identified
|
68
|
-
def inode
|
69
|
-
path = "/proc/self/fd/#{fileno}"
|
70
|
-
return unless File.exist?(path) && fileno
|
71
|
-
|
72
|
-
File.readlink(path)
|
73
|
-
end
|
74
|
-
|
75
64
|
private
|
76
65
|
|
77
66
|
def encode_body(data)
|
data/lib/instana/config.rb
CHANGED
@@ -51,7 +51,7 @@ module Instana
|
|
51
51
|
@config[:sanitize_sql] = true
|
52
52
|
|
53
53
|
# W3 Trace Context Support
|
54
|
-
@config[:w3_trace_correlation] = ENV
|
54
|
+
@config[:w3_trace_correlation] = ENV['INSTANA_DISABLE_W3C_TRACE_CORRELATION'].nil?
|
55
55
|
|
56
56
|
@config[:action_controller] = { :enabled => true }
|
57
57
|
@config[:action_view] = { :enabled => true }
|
@@ -24,14 +24,16 @@ module Instana
|
|
24
24
|
end
|
25
25
|
|
26
26
|
# Set request headers; encode IDs as hexadecimal strings
|
27
|
-
datum[:headers]['X-Instana-
|
28
|
-
datum[:headers]['X-Instana-S'] = t_context.span_id_header
|
27
|
+
datum[:headers]['X-Instana-L'] = t_context.level.to_s
|
29
28
|
|
30
|
-
if
|
31
|
-
datum[:headers]['
|
32
|
-
datum[:headers]['
|
29
|
+
if t_context.active?
|
30
|
+
datum[:headers]['X-Instana-T'] = t_context.trace_id_header
|
31
|
+
datum[:headers]['X-Instana-S'] = t_context.span_id_header
|
33
32
|
end
|
34
33
|
|
34
|
+
datum[:headers]['Traceparent'] = t_context.trace_parent_header
|
35
|
+
datum[:headers]['Tracestate'] = t_context.trace_state_header unless t_context.trace_state_header.empty?
|
36
|
+
|
35
37
|
@stack.request_call(datum)
|
36
38
|
end
|
37
39
|
|
@@ -18,16 +18,33 @@ module Instana
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def incoming_context
|
21
|
-
context = if
|
21
|
+
context = if !correlation_data.empty?
|
22
|
+
{}
|
23
|
+
elsif @env['HTTP_X_INSTANA_T']
|
22
24
|
context_from_instana_headers
|
23
|
-
elsif @env['HTTP_TRACEPARENT']
|
25
|
+
elsif @env['HTTP_TRACEPARENT']
|
24
26
|
context_from_trace_parent
|
27
|
+
elsif @env['HTTP_TRACESTATE']
|
28
|
+
context_from_trace_state
|
25
29
|
else
|
26
30
|
{}
|
27
31
|
end
|
28
32
|
|
29
33
|
context[:level] = @env['HTTP_X_INSTANA_L'][0] if @env['HTTP_X_INSTANA_L']
|
30
34
|
|
35
|
+
unless ::Instana.config[:w3_trace_correlation]
|
36
|
+
trace_state = parse_trace_state
|
37
|
+
|
38
|
+
if context[:from_w3] && trace_state.empty?
|
39
|
+
context.delete(:span_id)
|
40
|
+
context[:from_w3] = false
|
41
|
+
elsif context[:from_w3] && !trace_state.empty?
|
42
|
+
context[:trace_id] = trace_state[:t]
|
43
|
+
context[:span_id] = trace_state[:p]
|
44
|
+
context[:from_w3] = false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
31
48
|
context
|
32
49
|
end
|
33
50
|
|
@@ -69,19 +86,43 @@ module Instana
|
|
69
86
|
end
|
70
87
|
|
71
88
|
def continuing_from_trace_parent?
|
72
|
-
incoming_context
|
89
|
+
incoming_context[:from_w3]
|
73
90
|
end
|
74
91
|
|
75
92
|
def synthetic?
|
76
93
|
@env.has_key?('HTTP_X_INSTANA_SYNTHETIC') && @env['HTTP_X_INSTANA_SYNTHETIC'].eql?('1')
|
77
94
|
end
|
78
95
|
|
96
|
+
def long_instana_id?
|
97
|
+
::Instana::Util.header_to_id(@env['HTTP_X_INSTANA_T']).length == 32
|
98
|
+
end
|
99
|
+
|
100
|
+
def external_trace_id?
|
101
|
+
continuing_from_trace_parent? || long_instana_id?
|
102
|
+
end
|
103
|
+
|
104
|
+
def external_trace_id
|
105
|
+
incoming_context[:long_instana_id] || incoming_context[:external_trace_id]
|
106
|
+
end
|
107
|
+
|
79
108
|
private
|
80
109
|
|
81
110
|
def context_from_instana_headers
|
111
|
+
sanitized_t = ::Instana::Util.header_to_id(@env['HTTP_X_INSTANA_T'])
|
112
|
+
sanitized_s = ::Instana::Util.header_to_id(@env['HTTP_X_INSTANA_S'])
|
113
|
+
external_trace_id = if @env['HTTP_TRACEPARENT']
|
114
|
+
context_from_trace_parent[:external_trace_id]
|
115
|
+
elsif long_instana_id?
|
116
|
+
sanitized_t
|
117
|
+
end
|
118
|
+
|
82
119
|
{
|
83
|
-
|
84
|
-
|
120
|
+
span_id: sanitized_s,
|
121
|
+
trace_id: long_instana_id? ? sanitized_t[16..-1] : sanitized_t, # rubocop:disable Style/SlicingWithRange, Lint/RedundantCopDisableDirective
|
122
|
+
long_instana_id: long_instana_id? ? sanitized_t : nil,
|
123
|
+
external_trace_id: external_trace_id,
|
124
|
+
external_state: @env['HTTP_TRACESTATE'],
|
125
|
+
from_w3: false
|
85
126
|
}.compact
|
86
127
|
end
|
87
128
|
|
@@ -90,14 +131,28 @@ module Instana
|
|
90
131
|
matches = @env['HTTP_TRACEPARENT'].match(W3_TRACE_PARENT_FORMAT)
|
91
132
|
return {} unless matches
|
92
133
|
|
134
|
+
trace_id = ::Instana::Util.header_to_id(matches['trace'][16..-1]) # rubocop:disable Style/SlicingWithRange, Lint/RedundantCopDisableDirective
|
135
|
+
span_id = ::Instana::Util.header_to_id(matches['parent'])
|
136
|
+
|
93
137
|
{
|
94
138
|
external_trace_id: matches['trace'],
|
95
139
|
external_state: @env['HTTP_TRACESTATE'],
|
96
|
-
trace_id:
|
97
|
-
span_id:
|
140
|
+
trace_id: trace_id,
|
141
|
+
span_id: span_id,
|
142
|
+
from_w3: true
|
98
143
|
}
|
99
144
|
end
|
100
145
|
|
146
|
+
def context_from_trace_state
|
147
|
+
state = parse_trace_state
|
148
|
+
|
149
|
+
{
|
150
|
+
trace_id: state[:t],
|
151
|
+
span_id: state[:p],
|
152
|
+
from_w3: false
|
153
|
+
}.compact
|
154
|
+
end
|
155
|
+
|
101
156
|
def parse_trace_state
|
102
157
|
return {} unless @env.has_key?('HTTP_TRACESTATE')
|
103
158
|
token = @env['HTTP_TRACESTATE']
|
@@ -19,14 +19,16 @@ module Instana
|
|
19
19
|
|
20
20
|
# Set request headers; encode IDs as hexadecimal strings
|
21
21
|
t_context = ::Instana.tracer.context
|
22
|
-
request['X-Instana-
|
23
|
-
request['X-Instana-S'] = t_context.span_id_header
|
22
|
+
request['X-Instana-L'] = t_context.level.to_s
|
24
23
|
|
25
|
-
if
|
26
|
-
request['
|
27
|
-
request['
|
24
|
+
if t_context.active?
|
25
|
+
request['X-Instana-T'] = t_context.trace_id_header
|
26
|
+
request['X-Instana-S'] = t_context.span_id_header
|
28
27
|
end
|
29
28
|
|
29
|
+
request['Traceparent'] = t_context.trace_parent_header
|
30
|
+
request['Tracestate'] = t_context.trace_state_header unless t_context.trace_state_header.empty?
|
31
|
+
|
30
32
|
# Collect up KV info now in case any exception is raised
|
31
33
|
kv_payload = { :http => {} }
|
32
34
|
kv_payload[:http][:method] = request.method
|
@@ -12,7 +12,6 @@ module Instana
|
|
12
12
|
|
13
13
|
def call(env)
|
14
14
|
req = InstrumentedRequest.new(env)
|
15
|
-
return @app.call(env) if req.skip_trace?
|
16
15
|
kvs = {
|
17
16
|
http: req.request_tags,
|
18
17
|
service: ENV['INSTANA_SERVICE_NAME']
|
@@ -34,12 +33,16 @@ module Instana
|
|
34
33
|
|
35
34
|
if req.continuing_from_trace_parent?
|
36
35
|
current_span[:tp] = true
|
37
|
-
|
36
|
+
end
|
37
|
+
|
38
|
+
if req.external_trace_id?
|
39
|
+
current_span[:lt] = req.external_trace_id
|
38
40
|
end
|
39
41
|
|
40
42
|
if req.synthetic?
|
41
43
|
current_span[:sy] = true
|
42
44
|
end
|
45
|
+
|
43
46
|
# In case some previous middleware returned a string status, make sure that we're dealing with
|
44
47
|
# an integer. In Ruby nil.to_i, "asdfasdf".to_i will always return 0 from Ruby versions 1.8.7 and newer.
|
45
48
|
# So if an 0 status is reported here, it indicates some other issue (e.g. no status from previous middleware)
|
@@ -70,15 +73,17 @@ module Instana
|
|
70
73
|
if ::Instana.tracer.tracing?
|
71
74
|
if headers
|
72
75
|
# Set response headers; encode as hex string
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
+
if trace_context.active?
|
77
|
+
headers['X-Instana-T'] = trace_context.trace_id_header
|
78
|
+
headers['X-Instana-S'] = trace_context.span_id_header
|
79
|
+
headers['X-Instana-L'] = '1'
|
76
80
|
|
77
|
-
if ::Instana.config[:w3_trace_correlation]
|
78
|
-
headers['Traceparent'] = trace_context.trace_parent_header
|
79
81
|
headers['Tracestate'] = trace_context.trace_state_header
|
82
|
+
else
|
83
|
+
headers['X-Instana-L'] = '0'
|
80
84
|
end
|
81
85
|
|
86
|
+
headers['Traceparent'] = trace_context.trace_parent_header
|
82
87
|
headers['Server-Timing'] = "intid;desc=#{trace_context.trace_id_header}"
|
83
88
|
end
|
84
89
|
|
@@ -5,7 +5,7 @@ require 'thread'
|
|
5
5
|
|
6
6
|
module Instana
|
7
7
|
class Processor
|
8
|
-
def initialize
|
8
|
+
def initialize(logger: ::Instana.logger)
|
9
9
|
# The main queue before being reported to the
|
10
10
|
# host agent. Spans in this queue are complete
|
11
11
|
# and ready to be sent.
|
@@ -14,12 +14,22 @@ module Instana
|
|
14
14
|
# This is the maximum number of spans we send to the host
|
15
15
|
# agent at once.
|
16
16
|
@batch_size = 3000
|
17
|
+
@logger = logger
|
18
|
+
@pid = $PROCESS_ID
|
17
19
|
end
|
18
20
|
|
19
21
|
# Adds a span to the span queue
|
20
22
|
#
|
21
23
|
# @param [Trace] - the trace to be added to the queue
|
22
24
|
def add_span(span)
|
25
|
+
# :nocov:
|
26
|
+
if @pid != $PROCESS_ID
|
27
|
+
@logger.info("Proces `#{@pid}` has forked into #{$PROCESS_ID}. Resetting discovery.")
|
28
|
+
::Instana.agent.spawn_background_thread
|
29
|
+
@pid = $PROCESS_ID
|
30
|
+
end
|
31
|
+
# :nocov:
|
32
|
+
|
23
33
|
@queue.push(span)
|
24
34
|
end
|
25
35
|
|
data/lib/instana/tracing/span.rb
CHANGED
@@ -28,9 +28,15 @@ module Instana
|
|
28
28
|
if parent_ctx.is_a?(::Instana::SpanContext)
|
29
29
|
@is_root = false
|
30
30
|
|
31
|
-
|
31
|
+
# If we have a parent trace, link to it
|
32
|
+
if parent_ctx.trace_id
|
33
|
+
@data[:t] = parent_ctx.trace_id # Trace ID
|
34
|
+
@data[:p] = parent_ctx.span_id # Parent ID
|
35
|
+
else
|
36
|
+
@data[:t] = ::Instana::Util.generate_id
|
37
|
+
end
|
38
|
+
|
32
39
|
@data[:s] = ::Instana::Util.generate_id # Span ID
|
33
|
-
@data[:p] = parent_ctx.span_id # Parent ID
|
34
40
|
|
35
41
|
@baggage = parent_ctx.baggage.dup
|
36
42
|
@level = parent_ctx.level
|
@@ -31,19 +31,22 @@ module Instana
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def trace_parent_header
|
34
|
-
|
35
|
-
|
36
|
-
trace = (@baggage[:external_trace_id] || @trace_id).rjust(32, '0')
|
37
|
-
parent = @span_id.rjust(16, '0')
|
34
|
+
trace = (@baggage[:external_trace_id] || trace_id_header).rjust(32, '0')
|
35
|
+
parent = span_id_header.rjust(16, '0')
|
38
36
|
flags = @level == 1 ? "01" : "00"
|
39
37
|
|
40
38
|
"00-#{trace}-#{parent}-#{flags}"
|
41
39
|
end
|
42
40
|
|
43
41
|
def trace_state_header
|
44
|
-
|
42
|
+
external_state = @baggage[:external_state] || ''
|
43
|
+
state = external_state.split(/,/)
|
44
|
+
|
45
|
+
if @level == 1
|
46
|
+
state = state.reject { |s| s.start_with?('in=') }
|
47
|
+
state.unshift("in=#{trace_id_header};#{span_id_header}")
|
48
|
+
end
|
45
49
|
|
46
|
-
state = ["in=#{trace_id_header};#{span_id_header}", @baggage[:external_state]]
|
47
50
|
state.compact.join(',')
|
48
51
|
end
|
49
52
|
|
@@ -51,10 +54,12 @@ module Instana
|
|
51
54
|
{ :trace_id => @trace_id, :span_id => @span_id }
|
52
55
|
end
|
53
56
|
|
54
|
-
private
|
55
|
-
|
56
57
|
def valid?
|
57
|
-
@baggage && @trace_id &&
|
58
|
+
@baggage && @trace_id && !@trace_id.emtpy?
|
59
|
+
end
|
60
|
+
|
61
|
+
def active?
|
62
|
+
@level == 1
|
58
63
|
end
|
59
64
|
end
|
60
65
|
end
|
data/lib/instana/util.rb
CHANGED
@@ -156,8 +156,10 @@ module Instana
|
|
156
156
|
#
|
157
157
|
# @return [String]
|
158
158
|
#
|
159
|
-
def header_to_id(
|
160
|
-
|
159
|
+
def header_to_id(given)
|
160
|
+
return '' unless given.is_a?(String)
|
161
|
+
return '' unless given.match(/\A[a-z\d]{16,32}\z/i)
|
162
|
+
given
|
161
163
|
end
|
162
164
|
end
|
163
165
|
end
|
data/lib/instana/version.rb
CHANGED
@@ -4,6 +4,10 @@
|
|
4
4
|
require 'test_helper'
|
5
5
|
|
6
6
|
class HostAgentActivationObserverTest < Minitest::Test
|
7
|
+
def setup
|
8
|
+
@socket_proc = ->(_c) { OpenStruct.new(fileno: 0) }
|
9
|
+
end
|
10
|
+
|
7
11
|
def test_standard_discovery
|
8
12
|
stub_request(:put, "http://10.10.10.10:9292/com.instana.plugin.ruby.discovery")
|
9
13
|
.and_timeout
|
@@ -17,7 +21,7 @@ class HostAgentActivationObserverTest < Minitest::Test
|
|
17
21
|
client = Instana::Backend::RequestClient.new('10.10.10.10', 9292)
|
18
22
|
discovery = Concurrent::Atom.new(nil)
|
19
23
|
|
20
|
-
subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, wait_time: 0, logger: Logger.new('/dev/null'), max_wait_tries: 1)
|
24
|
+
subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, wait_time: 0, logger: Logger.new('/dev/null'), max_wait_tries: 1, socket_proc: @socket_proc)
|
21
25
|
|
22
26
|
subject.update(nil, nil, nil)
|
23
27
|
assert_equal({'pid' => 1234}, discovery.value)
|
@@ -31,15 +35,18 @@ class HostAgentActivationObserverTest < Minitest::Test
|
|
31
35
|
.and_return(status: 200, body: '{"ok": true}')
|
32
36
|
|
33
37
|
client = Instana::Backend::RequestClient.new('10.10.10.10', 9292)
|
34
|
-
# This is the cleanest way to fake it so it works across all test environments
|
35
|
-
client.define_singleton_method(:fileno) { '0' }
|
36
|
-
client.define_singleton_method(:inode) { '0' }
|
37
|
-
|
38
38
|
discovery = Concurrent::Atom.new(nil)
|
39
39
|
|
40
|
-
subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, wait_time: 0, logger: Logger.new('/dev/null'), max_wait_tries: 1)
|
40
|
+
subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, wait_time: 0, logger: Logger.new('/dev/null'), max_wait_tries: 1, socket_proc: @socket_proc)
|
41
41
|
|
42
|
-
|
42
|
+
FakeFS.with_fresh do
|
43
|
+
FakeFS::FileSystem.clone('test/support/proc', '/proc')
|
44
|
+
FakeFS::FileSystem.clone('test/support/proc/0', "/proc/#{Process.pid}")
|
45
|
+
Dir.mkdir('/proc/self/fd')
|
46
|
+
File.symlink('/proc/self/sched', "/proc/self/fd/0")
|
47
|
+
|
48
|
+
subject.update(nil, nil, nil)
|
49
|
+
end
|
43
50
|
|
44
51
|
assert_equal({'pid' => 1234}, discovery.value)
|
45
52
|
end
|
@@ -48,7 +55,7 @@ class HostAgentActivationObserverTest < Minitest::Test
|
|
48
55
|
client = Instana::Backend::RequestClient.new('10.10.10.10', 9292)
|
49
56
|
discovery = Concurrent::Atom.new(nil)
|
50
57
|
|
51
|
-
subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, wait_time: 0, logger: Logger.new('/dev/null'), proc_table: nil)
|
58
|
+
subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, wait_time: 0, logger: Logger.new('/dev/null'), proc_table: nil, socket_proc: @socket_proc)
|
52
59
|
|
53
60
|
subject.update(nil, nil, nil)
|
54
61
|
assert_nil discovery.value
|
@@ -58,7 +65,7 @@ class HostAgentActivationObserverTest < Minitest::Test
|
|
58
65
|
client = Instana::Backend::RequestClient.new('10.10.10.10', 9292)
|
59
66
|
discovery = Concurrent::Atom.new(nil)
|
60
67
|
|
61
|
-
subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery)
|
68
|
+
subject = Instana::Backend::HostAgentActivationObserver.new(client, discovery, socket_proc: @socket_proc)
|
62
69
|
assert_nil subject.update(nil, nil, true)
|
63
70
|
assert_nil discovery.value
|
64
71
|
end
|
@@ -4,19 +4,34 @@
|
|
4
4
|
require 'test_helper'
|
5
5
|
|
6
6
|
class HostAgentTest < Minitest::Test
|
7
|
-
def
|
7
|
+
def test_spawn_background_thread
|
8
8
|
ENV['INSTANA_TEST'] = nil
|
9
9
|
::Instana.config[:agent_host] = '10.10.10.10'
|
10
10
|
|
11
|
+
if File.exist?('/sbin/ip')
|
12
|
+
addr = `/sbin/ip route | awk '/default/ { print $3 }'`.strip
|
13
|
+
stub_request(:get, "http://#{addr}:42699/")
|
14
|
+
.to_timeout
|
15
|
+
end
|
16
|
+
|
11
17
|
stub_request(:get, "http://10.10.10.10:42699/")
|
18
|
+
.to_timeout.times(3).then
|
12
19
|
.to_return(status: 200, body: "", headers: {})
|
13
20
|
|
14
21
|
discovery = Minitest::Mock.new
|
22
|
+
discovery.expect(:delete_observers, discovery, [])
|
15
23
|
discovery.expect(:with_observer, discovery, [Instana::Backend::HostAgentActivationObserver])
|
16
24
|
discovery.expect(:with_observer, discovery, [Instana::Backend::HostAgentReportingObserver])
|
25
|
+
discovery.expect(:swap, discovery, [])
|
17
26
|
|
18
27
|
subject = Instana::Backend::HostAgent.new(discovery: discovery)
|
19
|
-
|
28
|
+
|
29
|
+
FakeFS.with_fresh do
|
30
|
+
FakeFS::FileSystem.clone('test/support/ecs', '/proc')
|
31
|
+
subject.spawn_background_thread
|
32
|
+
end
|
33
|
+
|
34
|
+
subject.future.value!
|
20
35
|
|
21
36
|
discovery.verify
|
22
37
|
ensure
|
@@ -36,26 +36,4 @@ class RequestClientTest < Minitest::Test
|
|
36
36
|
|
37
37
|
refute response.ok?
|
38
38
|
end
|
39
|
-
|
40
|
-
def test_fileno
|
41
|
-
subject = Instana::Backend::RequestClient.new('example.com', 9292)
|
42
|
-
assert_nil subject.fileno
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_inode
|
46
|
-
subject = Instana::Backend::RequestClient.new('example.com', 9292)
|
47
|
-
subject.define_singleton_method(:fileno) { '0' } # This is the cleanest way to fake it so it works across all test environments
|
48
|
-
FakeFS.with_fresh do
|
49
|
-
FakeFS::FileSystem.clone('test/support/proc', '/proc')
|
50
|
-
Dir.mkdir('/proc/self/fd')
|
51
|
-
File.symlink('/proc/self/sched', '/proc/self/fd/0')
|
52
|
-
|
53
|
-
assert_equal '/proc/self/sched', subject.inode
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_inode_no_proc
|
58
|
-
subject = Instana::Backend::RequestClient.new('example.com', 9292)
|
59
|
-
assert_nil subject.inode
|
60
|
-
end
|
61
39
|
end
|
@@ -29,6 +29,7 @@ class RackInstrumentedRequestTest < Minitest::Test
|
|
29
29
|
expected = {
|
30
30
|
trace_id: id,
|
31
31
|
span_id: id,
|
32
|
+
from_w3: false,
|
32
33
|
level: '1'
|
33
34
|
}
|
34
35
|
|
@@ -47,6 +48,7 @@ class RackInstrumentedRequestTest < Minitest::Test
|
|
47
48
|
external_state: nil,
|
48
49
|
trace_id: 'a3ce929d0e0e4736',
|
49
50
|
span_id: '00f067aa0ba902b7',
|
51
|
+
from_w3: true,
|
50
52
|
level: '1'
|
51
53
|
}
|
52
54
|
|
data/test/test_helper.rb
CHANGED
@@ -45,7 +45,7 @@ require 'fakefs/safe'
|
|
45
45
|
require 'webmock/minitest'
|
46
46
|
# Webmock: Whitelist local IPs
|
47
47
|
WebMock.disable_net_connect!(
|
48
|
-
allow: ->(uri) { %w[localhost 127.0.0.1 172.17.0.1 172.0.12.100].include?(uri.host) }
|
48
|
+
allow: ->(uri) { %w[localhost 127.0.0.1 172.17.0.1 172.0.12.100].include?(uri.host) && ENV.key?('APPRAISAL_INITIALIZED') }
|
49
49
|
)
|
50
50
|
|
51
51
|
Dir['test/support/*.rb'].each { |f| load(f) }
|
@@ -11,8 +11,7 @@ class SpanContextTest < Minitest::Test
|
|
11
11
|
|
12
12
|
def test_invalid
|
13
13
|
subject = Instana::SpanContext.new(nil, nil)
|
14
|
-
|
15
|
-
assert subject.trace_state_header.empty?
|
14
|
+
refute subject.valid?
|
16
15
|
end
|
17
16
|
|
18
17
|
def test_flags_level_zero
|
data/test/tracing/span_test.rb
CHANGED
@@ -46,6 +46,15 @@ class SpanTest < Minitest::Test
|
|
46
46
|
assert_equal 'test', span.trace_id
|
47
47
|
end
|
48
48
|
|
49
|
+
def test_span_from_contetx_invalid
|
50
|
+
context = Instana::SpanContext.new(nil, nil, 1)
|
51
|
+
span = Instana::Span.new(:test, parent_ctx: context)
|
52
|
+
|
53
|
+
assert_nil span.parent_id
|
54
|
+
refute_equal context.span_id, span.trace_id
|
55
|
+
assert_equal 1, span.context.level
|
56
|
+
end
|
57
|
+
|
49
58
|
def test_span_collect_backtraces
|
50
59
|
Instana.config[:collect_backtraces] = true
|
51
60
|
span = Instana::Span.new(:excon)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: instana
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.197.0.
|
4
|
+
version: 1.197.0.pre2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Giacomo Lombardo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|