instana 1.197.0.pre1 → 1.197.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|