instana 1.9.7 → 1.10.0.slimfast
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/agent.rb +19 -19
- data/lib/instana/agent/helpers.rb +2 -2
- data/lib/instana/agent/tasks.rb +2 -2
- data/lib/instana/collectors/gc.rb +1 -1
- data/lib/instana/collectors/memory.rb +1 -1
- data/lib/instana/collectors/thread.rb +1 -1
- data/lib/instana/frameworks/instrumentation/mysql2_adapter.rb +1 -1
- data/lib/instana/frameworks/instrumentation/mysql_adapter.rb +1 -1
- data/lib/instana/helpers.rb +2 -2
- data/lib/instana/instrumentation.rb +1 -1
- data/lib/instana/instrumentation/excon.rb +8 -5
- data/lib/instana/instrumentation/rack.rb +2 -2
- data/lib/instana/instrumentation/resque.rb +3 -3
- data/lib/instana/tracer.rb +92 -117
- data/lib/instana/tracing/processor.rb +18 -133
- data/lib/instana/tracing/span.rb +40 -35
- data/lib/instana/tracing/span_context.rb +3 -1
- data/lib/instana/util.rb +5 -5
- data/lib/instana/version.rb +1 -1
- data/lib/opentracing.rb +1 -1
- data/test/frameworks/rack_test.rb +6 -11
- data/test/frameworks/rails/actioncontroller_test.rb +32 -62
- data/test/frameworks/rails/actionview5_test.rb +91 -132
- data/test/frameworks/rails/activerecord5_test.rb +14 -17
- data/test/instrumentation/dalli_test.rb +51 -72
- data/test/instrumentation/excon_test.rb +70 -94
- data/test/instrumentation/grpc_test.rb +164 -126
- data/test/instrumentation/net-http_test.rb +48 -57
- data/test/instrumentation/redis_test.rb +4 -6
- data/test/instrumentation/resque_test.rb +41 -41
- data/test/instrumentation/rest-client_test.rb +25 -31
- data/test/instrumentation/sidekiq-client_test.rb +12 -20
- data/test/instrumentation/sidekiq-worker_test.rb +48 -63
- data/test/jobs/resque_error_job.rb +7 -1
- data/test/jobs/resque_fast_job.rb +7 -1
- data/test/servers/sidekiq/worker.rb +1 -3
- data/test/test_helper.rb +58 -0
- data/test/tracing/custom_test.rb +11 -19
- data/test/tracing/opentracing_test.rb +48 -156
- data/test/tracing/trace_test.rb +67 -67
- data/test/tracing/tracer_async_test.rb +75 -175
- data/test/tracing/tracer_test.rb +75 -75
- metadata +4 -5
- data/lib/instana/tracing/trace.rb +0 -316
@@ -2,78 +2,43 @@ require 'thread'
|
|
2
2
|
|
3
3
|
module Instana
|
4
4
|
class Processor
|
5
|
-
|
6
5
|
def initialize
|
7
6
|
# The main queue before being reported to the
|
8
|
-
# host agent.
|
7
|
+
# host agent. Spans in this queue are complete
|
9
8
|
# and ready to be sent.
|
10
9
|
@queue = Queue.new
|
11
10
|
|
12
|
-
# The staging queue that holds traces that have completed
|
13
|
-
# but still have outstanding async spans.
|
14
|
-
# Traces that have been in this queue for more than
|
15
|
-
# 5 minutes are discarded.
|
16
|
-
@staging_queue = Set.new
|
17
|
-
|
18
|
-
# No access to the @staging_queue until this lock
|
19
|
-
# is taken.
|
20
|
-
@staging_lock = Mutex.new
|
21
|
-
|
22
11
|
# This is the maximum number of spans we send to the host
|
23
12
|
# agent at once.
|
24
13
|
@batch_size = 3000
|
25
14
|
end
|
26
15
|
|
27
|
-
# Adds a
|
28
|
-
# sent to the host agent
|
16
|
+
# Adds a Set of spans to the queue
|
29
17
|
#
|
30
|
-
# @param [
|
31
|
-
def
|
18
|
+
# @param [spans] - the trace to be added to the queue
|
19
|
+
def add_spans(spans)
|
32
20
|
# Do a quick checkup on our background thread.
|
33
21
|
if ::Instana.agent.collect_thread.nil? || !::Instana.agent.collect_thread.alive?
|
34
22
|
::Instana.agent.spawn_background_thread
|
35
23
|
end
|
36
|
-
|
37
|
-
# ::Instana.logger.debug("Queuing completed trace id: #{trace.id}")
|
38
|
-
@queue.push(trace)
|
24
|
+
spans.each { |span| @queue.push(span)}
|
39
25
|
end
|
40
26
|
|
41
|
-
# Adds a
|
27
|
+
# Adds a span to the span queue
|
42
28
|
#
|
43
|
-
# @param [Trace] the trace to be added to the queue
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
# completed or timed out incompleted traces. Completed traces will
|
51
|
-
# be added to the main @queue. Timed out traces will be discarded
|
52
|
-
#
|
53
|
-
def process_staged
|
54
|
-
@staging_lock.synchronize {
|
55
|
-
if @staging_queue.size > 0
|
56
|
-
@staging_queue.delete_if do |t|
|
57
|
-
if t.complete?
|
58
|
-
::Instana.logger.debug("Moving staged complete trace to main queue: #{t.id}")
|
59
|
-
add(t)
|
60
|
-
true
|
61
|
-
elsif t.discard?
|
62
|
-
::Instana.logger.debug("Discarding trace with uncompleted async spans over 5 mins old. id: #{t.id}")
|
63
|
-
true
|
64
|
-
else
|
65
|
-
false
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
}
|
29
|
+
# @param [Trace] - the trace to be added to the queue
|
30
|
+
def add_span(span)
|
31
|
+
# Do a quick checkup on our background thread.
|
32
|
+
if ::Instana.agent.collect_thread.nil? || !::Instana.agent.collect_thread.alive?
|
33
|
+
::Instana.agent.spawn_background_thread
|
34
|
+
end
|
35
|
+
@queue.push(span)
|
70
36
|
end
|
71
37
|
|
72
38
|
##
|
73
39
|
# send
|
74
40
|
#
|
75
|
-
# Sends all traces in @queue to the host
|
76
|
-
# agent
|
41
|
+
# Sends all traces in @queue to the host agent
|
77
42
|
#
|
78
43
|
# FIXME: Add limits checking here in regards to:
|
79
44
|
# - Max HTTP Post size
|
@@ -83,15 +48,6 @@ module Instana
|
|
83
48
|
def send
|
84
49
|
return if @queue.empty? || ENV.key?('INSTANA_TEST')
|
85
50
|
|
86
|
-
size = @queue.size
|
87
|
-
if size > 200
|
88
|
-
Instana.logger.debug "Trace queue is #{size}"
|
89
|
-
end
|
90
|
-
|
91
|
-
# Scan for any staged but incomplete traces that have now
|
92
|
-
# completed.
|
93
|
-
process_staged
|
94
|
-
|
95
51
|
# Retrieve all spans for queued traces
|
96
52
|
spans = queued_spans
|
97
53
|
|
@@ -117,85 +73,15 @@ module Instana
|
|
117
73
|
spans = []
|
118
74
|
until @queue.empty? do
|
119
75
|
# Non-blocking pop; ignore exception
|
120
|
-
|
121
|
-
|
122
|
-
spans <<
|
76
|
+
span = @queue.pop(true) rescue nil
|
77
|
+
if span
|
78
|
+
spans << span.raw
|
123
79
|
end
|
124
80
|
end
|
125
81
|
spans
|
126
82
|
end
|
127
83
|
|
128
|
-
#
|
129
|
-
# Note that traces retrieved with this method are removed
|
130
|
-
# entirely from the queue.
|
131
|
-
#
|
132
|
-
# @return [Array] An array of [Trace] or empty
|
133
|
-
#
|
134
|
-
def queued_traces
|
135
|
-
return [] if @queue.empty?
|
136
|
-
|
137
|
-
traces = []
|
138
|
-
until @queue.empty? do
|
139
|
-
# Non-blocking pop; ignore exception
|
140
|
-
traces << @queue.pop(true) rescue nil
|
141
|
-
end
|
142
|
-
traces
|
143
|
-
end
|
144
|
-
|
145
|
-
# Retrieves a all staged traces from the staging queue. Staged traces
|
146
|
-
# are traces that have completed but may have outstanding
|
147
|
-
# asynchronous spans.
|
148
|
-
#
|
149
|
-
# @return [Array]
|
150
|
-
#
|
151
|
-
def staged_traces
|
152
|
-
traces = nil
|
153
|
-
@staging_lock.synchronize {
|
154
|
-
traces = @staging_queue.to_a
|
155
|
-
@staging_queue.clear
|
156
|
-
}
|
157
|
-
traces
|
158
|
-
end
|
159
|
-
|
160
|
-
# Retrieves a single staged trace from the staging queue. Staged traces
|
161
|
-
# are traces that have completed but may have outstanding
|
162
|
-
# asynchronous spans.
|
163
|
-
#
|
164
|
-
# @param trace_id [Integer] the Trace ID to be searched for
|
165
|
-
#
|
166
|
-
def staged_trace(trace_id)
|
167
|
-
candidate = nil
|
168
|
-
@staging_lock.synchronize {
|
169
|
-
@staging_queue.each do |trace|
|
170
|
-
if trace.id == trace_id
|
171
|
-
candidate = trace
|
172
|
-
break
|
173
|
-
end
|
174
|
-
end
|
175
|
-
}
|
176
|
-
unless candidate
|
177
|
-
::Instana.logger.debug("Couldn't find staged trace with trace_id: #{trace_id}")
|
178
|
-
end
|
179
|
-
candidate
|
180
|
-
end
|
181
|
-
|
182
|
-
# Get the number traces currently in the queue
|
183
|
-
#
|
184
|
-
# @return [Integer] the queue size
|
185
|
-
#
|
186
|
-
def queue_count
|
187
|
-
@queue.size
|
188
|
-
end
|
189
|
-
|
190
|
-
# Get the number traces currently in the staging queue
|
191
|
-
#
|
192
|
-
# @return [Integer] the queue size
|
193
|
-
#
|
194
|
-
def staged_count
|
195
|
-
@staging_queue.size
|
196
|
-
end
|
197
|
-
|
198
|
-
# Removes all traces from the @queue and @staging_queue. Used in the
|
84
|
+
# Removes all traces from the @queue. Used in the
|
199
85
|
# test suite to reset state.
|
200
86
|
#
|
201
87
|
def clear!
|
@@ -203,7 +89,6 @@ module Instana
|
|
203
89
|
# Non-blocking pop; ignore exception
|
204
90
|
@queue.pop(true) rescue nil
|
205
91
|
end
|
206
|
-
@staging_queue.clear
|
207
92
|
end
|
208
93
|
end
|
209
94
|
end
|
data/lib/instana/tracing/span.rb
CHANGED
@@ -11,13 +11,33 @@ module Instana
|
|
11
11
|
|
12
12
|
attr_accessor :parent
|
13
13
|
attr_accessor :baggage
|
14
|
+
attr_accessor :is_root
|
15
|
+
attr_accessor :context
|
14
16
|
|
15
|
-
def initialize(name,
|
17
|
+
def initialize(name, parent_ctx: nil, start_time: ::Instana::Util.now_in_ms)
|
16
18
|
@data = {}
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
|
20
|
+
if parent_ctx == nil
|
21
|
+
# No parent specified so we're starting a new Trace - this will be the root span
|
22
|
+
id = ::Instana::Util.generate_id
|
23
|
+
@data[:t] = id # Trace ID
|
24
|
+
@data[:s] = id # Span ID
|
25
|
+
is_root = true
|
26
|
+
else
|
27
|
+
if parent_ctx.is_a?(::Instana::Span)
|
28
|
+
@parent = parent_ctx
|
29
|
+
parent_context = parent_ctx.context
|
30
|
+
elsif parent_ctx.is_a?(::Instana::SpanContext)
|
31
|
+
parent_context = parent_ctx
|
32
|
+
end
|
33
|
+
|
34
|
+
@data[:t] = parent_context.trace_id # Trace ID
|
35
|
+
@data[:s] = ::Instana::Util.generate_id # Span ID
|
36
|
+
@data[:p] = parent_context.span_id # Parent ID
|
37
|
+
@baggage = parent_ctx.baggage.dup
|
38
|
+
is_root = false
|
39
|
+
end
|
40
|
+
|
21
41
|
@data[:data] = {}
|
22
42
|
|
23
43
|
# Entity Source
|
@@ -30,8 +50,6 @@ module Instana
|
|
30
50
|
@data[:ts] = start_time
|
31
51
|
end
|
32
52
|
|
33
|
-
@baggage = {}
|
34
|
-
|
35
53
|
if ::Instana.config[:collect_backtraces]
|
36
54
|
# For entry spans, add a backtrace fingerprint
|
37
55
|
add_stack(limit: 2) if ENTRY_SPANS.include?(name)
|
@@ -119,7 +137,7 @@ module Instana
|
|
119
137
|
#
|
120
138
|
def configure_custom(name)
|
121
139
|
@data[:n] = :sdk
|
122
|
-
@data[:k] =
|
140
|
+
@data[:k] = 3
|
123
141
|
@data[:data] = { :sdk => { :name => name.to_sym, :type => :intermediate } }
|
124
142
|
@data[:data][:sdk][:custom] = { :tags => {}, :logs => {} }
|
125
143
|
self
|
@@ -133,12 +151,15 @@ module Instana
|
|
133
151
|
# @return [Span]
|
134
152
|
#
|
135
153
|
def close(end_time = ::Instana::Util.now_in_ms)
|
136
|
-
|
137
154
|
if end_time.is_a?(Time)
|
138
155
|
end_time = ::Instana::Util.time_to_ms(end_time)
|
139
156
|
end
|
140
157
|
|
141
158
|
@data[:d] = end_time - @data[:ts]
|
159
|
+
|
160
|
+
# Add this span to the queue for reporting
|
161
|
+
::Instana.processor.add_span(self)
|
162
|
+
|
142
163
|
self
|
143
164
|
end
|
144
165
|
|
@@ -151,7 +172,7 @@ module Instana
|
|
151
172
|
# @return [Instana::SpanContext]
|
152
173
|
#
|
153
174
|
def context
|
154
|
-
@context ||= ::Instana::SpanContext.new(@data[:t], @data[:s], @baggage)
|
175
|
+
@context ||= ::Instana::SpanContext.new(@data[:t], @data[:s], 1, @baggage)
|
155
176
|
end
|
156
177
|
|
157
178
|
# Retrieve the ID for this span
|
@@ -212,15 +233,6 @@ module Instana
|
|
212
233
|
@data[:d]
|
213
234
|
end
|
214
235
|
|
215
|
-
# Indicates whether this span in the root span
|
216
|
-
# in the Trace
|
217
|
-
#
|
218
|
-
# @return [Boolean]
|
219
|
-
#
|
220
|
-
def is_root?
|
221
|
-
@data[:s] == @data[:t]
|
222
|
-
end
|
223
|
-
|
224
236
|
# Hash accessor to the internal @data hash
|
225
237
|
#
|
226
238
|
def [](key)
|
@@ -283,11 +295,14 @@ module Instana
|
|
283
295
|
if key.to_sym == :'span.kind'
|
284
296
|
case value.to_sym
|
285
297
|
when :server, :consumer
|
286
|
-
@data[:data][:sdk][:type] =
|
298
|
+
@data[:data][:sdk][:type] = :entry
|
299
|
+
@data[:k] = 1
|
287
300
|
when :client, :producer
|
288
|
-
@data[:data][:sdk][:type] =
|
301
|
+
@data[:data][:sdk][:type] = :exit
|
302
|
+
@data[:k] = 2
|
289
303
|
else
|
290
|
-
@data[:data][:sdk][:type] =
|
304
|
+
@data[:data][:sdk][:type] = :intermediate
|
305
|
+
@data[:k] = 3
|
291
306
|
end
|
292
307
|
end
|
293
308
|
else
|
@@ -328,7 +343,7 @@ module Instana
|
|
328
343
|
if @context
|
329
344
|
@context.baggage = @baggage
|
330
345
|
else
|
331
|
-
@context ||= ::Instana::SpanContext.new(@data[:t], @data[:s], @baggage)
|
346
|
+
@context ||= ::Instana::SpanContext.new(@data[:t], @data[:s], 1, @baggage)
|
332
347
|
end
|
333
348
|
self
|
334
349
|
end
|
@@ -370,7 +385,7 @@ module Instana
|
|
370
385
|
set_tags(:log => fields)
|
371
386
|
end
|
372
387
|
rescue StandardError => e
|
373
|
-
Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
388
|
+
Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" }
|
374
389
|
end
|
375
390
|
|
376
391
|
# Finish the {Span}
|
@@ -379,17 +394,7 @@ module Instana
|
|
379
394
|
# @param end_time [Time] custom end time, if not now
|
380
395
|
#
|
381
396
|
def finish(end_time = ::Instana::Util.now_in_ms)
|
382
|
-
|
383
|
-
::Instana.logger.debug "Closing a span that isn't active. This will result in a broken trace: #{self.inspect}"
|
384
|
-
end
|
385
|
-
|
386
|
-
if is_root?
|
387
|
-
# This is the root span for the trace. Call log_end to close
|
388
|
-
# out and queue the trace
|
389
|
-
::Instana.tracer.log_end(name, {}, end_time)
|
390
|
-
else
|
391
|
-
::Instana.tracer.current_trace.end_span({}, end_time)
|
392
|
-
end
|
397
|
+
close(end_time)
|
393
398
|
self
|
394
399
|
end
|
395
400
|
end
|
@@ -8,11 +8,13 @@ module Instana
|
|
8
8
|
#
|
9
9
|
# @param tid [Integer] the trace ID
|
10
10
|
# @param sid [Integer] the span ID
|
11
|
+
# @param level [Integer] default 1
|
11
12
|
# @param baggage [Hash] baggage applied to this trace
|
12
13
|
#
|
13
|
-
def initialize(tid, sid, baggage = nil)
|
14
|
+
def initialize(tid, sid, level = 1, baggage = nil)
|
14
15
|
@trace_id = tid
|
15
16
|
@span_id = sid
|
17
|
+
@level = level
|
16
18
|
@baggage = baggage
|
17
19
|
end
|
18
20
|
|
data/lib/instana/util.rb
CHANGED
@@ -119,8 +119,8 @@ module Instana
|
|
119
119
|
|
120
120
|
data
|
121
121
|
rescue => e
|
122
|
-
::Instana.logger.debug "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
123
|
-
::Instana.logger.debug e.backtrace.join("\r\n")
|
122
|
+
::Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" }
|
123
|
+
::Instana.logger.debug { e.backtrace.join("\r\n") }
|
124
124
|
return data
|
125
125
|
end
|
126
126
|
|
@@ -187,7 +187,7 @@ module Instana
|
|
187
187
|
return File.basename($0)
|
188
188
|
rescue Exception => e
|
189
189
|
Instana.logger.info "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
190
|
-
Instana.logger.debug e.backtrace.join("\r\n")
|
190
|
+
Instana.logger.debug { e.backtrace.join("\r\n") }
|
191
191
|
end
|
192
192
|
|
193
193
|
# Get the current time in milliseconds from the epoch
|
@@ -231,7 +231,7 @@ module Instana
|
|
231
231
|
[id.to_i].pack('q>').unpack('H*')[0].gsub(/^0+/, '')
|
232
232
|
rescue => e
|
233
233
|
Instana.logger.info "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
234
|
-
Instana.logger.debug e.backtrace.join("\r\n")
|
234
|
+
Instana.logger.debug { e.backtrace.join("\r\n") }
|
235
235
|
end
|
236
236
|
|
237
237
|
# Convert a received header value into a valid ID
|
@@ -254,7 +254,7 @@ module Instana
|
|
254
254
|
[header_id].pack("H*").unpack("q>")[0]
|
255
255
|
rescue => e
|
256
256
|
Instana.logger.info "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
|
257
|
-
Instana.logger.debug e.backtrace.join("\r\n")
|
257
|
+
Instana.logger.debug { e.backtrace.join("\r\n") }
|
258
258
|
end
|
259
259
|
end
|
260
260
|
end
|
data/lib/instana/version.rb
CHANGED
data/lib/opentracing.rb
CHANGED
@@ -31,7 +31,6 @@ class RackTest < Minitest::Test
|
|
31
31
|
|
32
32
|
first_span = spans.first
|
33
33
|
assert_equal :rack, first_span[:n]
|
34
|
-
assert_equal :ruby, first_span[:ta]
|
35
34
|
assert first_span.key?(:data)
|
36
35
|
assert first_span[:data].key?(:http)
|
37
36
|
assert_equal "GET", first_span[:data][:http][:method]
|
@@ -78,7 +77,6 @@ class RackTest < Minitest::Test
|
|
78
77
|
assert_equal 1, spans.count
|
79
78
|
first_span = spans.first
|
80
79
|
assert_equal :rack, first_span[:n]
|
81
|
-
assert_equal :ruby, first_span[:ta]
|
82
80
|
assert first_span.key?(:data)
|
83
81
|
assert first_span[:data].key?(:http)
|
84
82
|
assert_equal "POST", first_span[:data][:http][:method]
|
@@ -101,7 +99,6 @@ class RackTest < Minitest::Test
|
|
101
99
|
assert_equal 1, spans.count
|
102
100
|
first_span = spans.first
|
103
101
|
assert_equal :rack, first_span[:n]
|
104
|
-
assert_equal :ruby, first_span[:ta]
|
105
102
|
assert first_span.key?(:data)
|
106
103
|
assert first_span[:data].key?(:http)
|
107
104
|
assert_equal "PUT", first_span[:data][:http][:method]
|
@@ -127,7 +124,6 @@ class RackTest < Minitest::Test
|
|
127
124
|
assert_equal 1, spans.count
|
128
125
|
first_span = spans.first
|
129
126
|
assert_equal :rack, first_span[:n]
|
130
|
-
assert_equal :ruby, first_span[:ta]
|
131
127
|
assert first_span.key?(:data)
|
132
128
|
assert first_span[:data].key?(:http)
|
133
129
|
assert_equal "GET", first_span[:data][:http][:method]
|
@@ -158,14 +154,13 @@ class RackTest < Minitest::Test
|
|
158
154
|
clear_all!
|
159
155
|
get '/mrlobster?blah=2&wilma=1&betty=2;fred=3'
|
160
156
|
|
161
|
-
|
162
|
-
assert_equal 1,
|
157
|
+
spans = ::Instana.processor.queued_spans
|
158
|
+
assert_equal 1, spans.length
|
163
159
|
|
164
|
-
|
165
|
-
refute_nil
|
166
|
-
refute_nil
|
167
|
-
|
168
|
-
assert_equal '/mrlobster', trace.spans.first[:data][:http][:url]
|
160
|
+
refute_nil spans.first.key?(:data)
|
161
|
+
refute_nil spans.first[:data].key?(:http)
|
162
|
+
refute_nil spans.first[:data][:http].key?(:url)
|
163
|
+
assert_equal '/mrlobster', spans.first[:data][:http][:url]
|
169
164
|
|
170
165
|
assert last_response.ok?
|
171
166
|
end
|