opentelemetry-sdk 0.5.1
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 +7 -0
- data/.yardopts +9 -0
- data/CHANGELOG.md +1 -0
- data/LICENSE +201 -0
- data/README.md +73 -0
- data/lib/opentelemetry-sdk.rb +7 -0
- data/lib/opentelemetry/sdk.rb +69 -0
- data/lib/opentelemetry/sdk/configurator.rb +171 -0
- data/lib/opentelemetry/sdk/correlation_context.rb +16 -0
- data/lib/opentelemetry/sdk/correlation_context/builder.rb +40 -0
- data/lib/opentelemetry/sdk/correlation_context/manager.rb +87 -0
- data/lib/opentelemetry/sdk/instrumentation_library.rb +13 -0
- data/lib/opentelemetry/sdk/internal.rb +52 -0
- data/lib/opentelemetry/sdk/resources.rb +16 -0
- data/lib/opentelemetry/sdk/resources/constants.rb +124 -0
- data/lib/opentelemetry/sdk/resources/resource.rb +84 -0
- data/lib/opentelemetry/sdk/trace.rb +24 -0
- data/lib/opentelemetry/sdk/trace/config.rb +18 -0
- data/lib/opentelemetry/sdk/trace/config/trace_config.rb +77 -0
- data/lib/opentelemetry/sdk/trace/export.rb +30 -0
- data/lib/opentelemetry/sdk/trace/export/batch_span_processor.rb +144 -0
- data/lib/opentelemetry/sdk/trace/export/console_span_exporter.rb +40 -0
- data/lib/opentelemetry/sdk/trace/export/in_memory_span_exporter.rb +86 -0
- data/lib/opentelemetry/sdk/trace/export/multi_span_exporter.rb +58 -0
- data/lib/opentelemetry/sdk/trace/export/noop_span_exporter.rb +42 -0
- data/lib/opentelemetry/sdk/trace/export/simple_span_processor.rb +72 -0
- data/lib/opentelemetry/sdk/trace/multi_span_processor.rb +62 -0
- data/lib/opentelemetry/sdk/trace/noop_span_processor.rb +50 -0
- data/lib/opentelemetry/sdk/trace/samplers.rb +90 -0
- data/lib/opentelemetry/sdk/trace/samplers/constant_sampler.rb +33 -0
- data/lib/opentelemetry/sdk/trace/samplers/decision.rb +26 -0
- data/lib/opentelemetry/sdk/trace/samplers/parent_or_else.rb +43 -0
- data/lib/opentelemetry/sdk/trace/samplers/probability_sampler.rb +64 -0
- data/lib/opentelemetry/sdk/trace/samplers/result.rb +55 -0
- data/lib/opentelemetry/sdk/trace/span.rb +336 -0
- data/lib/opentelemetry/sdk/trace/span_data.rb +34 -0
- data/lib/opentelemetry/sdk/trace/tracer.rb +78 -0
- data/lib/opentelemetry/sdk/trace/tracer_provider.rb +84 -0
- data/lib/opentelemetry/sdk/version.rb +12 -0
- metadata +207 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
module OpenTelemetry
|
8
|
+
module SDK
|
9
|
+
module Trace
|
10
|
+
module Samplers
|
11
|
+
# The Result class represents an arbitrary sampling result. It has
|
12
|
+
# boolean values for the sampling decision and whether to record
|
13
|
+
# events, and a collection of attributes to be attached to a sampled
|
14
|
+
# root span.
|
15
|
+
class Result
|
16
|
+
EMPTY_HASH = {}.freeze
|
17
|
+
DECISIONS = [Decision::RECORD, Decision::NOT_RECORD, Decision::RECORD_AND_SAMPLED].freeze
|
18
|
+
private_constant(:EMPTY_HASH, :DECISIONS)
|
19
|
+
|
20
|
+
# Returns a frozen hash of attributes to be attached span.
|
21
|
+
#
|
22
|
+
# @return [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}]
|
23
|
+
attr_reader :attributes
|
24
|
+
|
25
|
+
# Returns a new sampling result with the specified decision and
|
26
|
+
# attributes.
|
27
|
+
#
|
28
|
+
# @param [Symbol] decision Whether or not a span should be sampled
|
29
|
+
# and/or record events.
|
30
|
+
# @param [optional Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}]
|
31
|
+
# attributes A frozen or freezable hash containing attributes to be
|
32
|
+
# attached to the span.
|
33
|
+
def initialize(decision:, attributes: nil)
|
34
|
+
@decision = decision
|
35
|
+
@attributes = attributes.freeze || EMPTY_HASH
|
36
|
+
end
|
37
|
+
|
38
|
+
# Returns true if this span should be sampled.
|
39
|
+
#
|
40
|
+
# @return [Boolean] sampling decision
|
41
|
+
def sampled?
|
42
|
+
@decision == Decision::RECORD_AND_SAMPLED
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns true if this span should record events, attributes, status, etc.
|
46
|
+
#
|
47
|
+
# @return [Boolean] recording decision
|
48
|
+
def recording?
|
49
|
+
@decision != Decision::NOT_RECORD
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,336 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
module OpenTelemetry
|
8
|
+
module SDK
|
9
|
+
module Trace
|
10
|
+
# Implementation of {OpenTelemetry::Trace::Span} that records trace events.
|
11
|
+
#
|
12
|
+
# This implementation includes reader methods intended to allow access to
|
13
|
+
# internal state by SpanProcessors (see {NoopSpanProcessor} for the interface).
|
14
|
+
# Instrumentation should use the API provided by {OpenTelemetry::Trace::Span}
|
15
|
+
# and should consider {Span} to be write-only.
|
16
|
+
#
|
17
|
+
# rubocop:disable Metrics/ClassLength
|
18
|
+
class Span < OpenTelemetry::Trace::Span
|
19
|
+
# The following readers are intended for the use of SpanProcessors and
|
20
|
+
# should not be considered part of the public interface for instrumentation.
|
21
|
+
attr_reader :name, :status, :kind, :parent_span_id, :start_timestamp, :end_timestamp, :links, :library_resource, :instrumentation_library
|
22
|
+
|
23
|
+
# Return a frozen copy of the current attributes. This is intended for
|
24
|
+
# use of SpanProcesses and should not be considered part of the public
|
25
|
+
# interface for instrumentation.
|
26
|
+
#
|
27
|
+
# @return [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] may be nil.
|
28
|
+
def attributes
|
29
|
+
# Don't bother synchronizing. Access by SpanProcessors is expected to
|
30
|
+
# be serialized.
|
31
|
+
@attributes&.clone.freeze
|
32
|
+
end
|
33
|
+
|
34
|
+
# Return a frozen copy of the current events. This is intended for use
|
35
|
+
# of SpanProcessors and should not be considered part of the public
|
36
|
+
# interface for instrumentation.
|
37
|
+
#
|
38
|
+
# @return [Array<Event>] may be nil.
|
39
|
+
def events
|
40
|
+
# Don't bother synchronizing. Access by SpanProcessors is expected to
|
41
|
+
# be serialized.
|
42
|
+
@events&.clone.freeze
|
43
|
+
end
|
44
|
+
|
45
|
+
# Return the flag whether this span is recording events
|
46
|
+
#
|
47
|
+
# @return [Boolean] true if this Span is active and recording information
|
48
|
+
# like events with the #add_event operation and attributes using
|
49
|
+
# #set_attribute.
|
50
|
+
def recording?
|
51
|
+
true
|
52
|
+
end
|
53
|
+
|
54
|
+
# Set attribute
|
55
|
+
#
|
56
|
+
# Note that the OpenTelemetry project
|
57
|
+
# {https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-semantic-conventions.md
|
58
|
+
# documents} certain "standard attributes" that have prescribed semantic
|
59
|
+
# meanings.
|
60
|
+
#
|
61
|
+
# @param [String] key
|
62
|
+
# @param [String, Boolean, Numeric] value
|
63
|
+
#
|
64
|
+
# @return [self] returns itself
|
65
|
+
def set_attribute(key, value)
|
66
|
+
super
|
67
|
+
@mutex.synchronize do
|
68
|
+
if @ended
|
69
|
+
OpenTelemetry.logger.warn('Calling set_attribute on an ended Span.')
|
70
|
+
else
|
71
|
+
@attributes ||= {}
|
72
|
+
@attributes[key] = value
|
73
|
+
trim_span_attributes(@attributes)
|
74
|
+
@total_recorded_attributes += 1
|
75
|
+
end
|
76
|
+
end
|
77
|
+
self
|
78
|
+
end
|
79
|
+
|
80
|
+
# Add an Event to a {Span}. This can be accomplished eagerly or lazily.
|
81
|
+
# Lazy evaluation is useful when the event attributes are expensive to
|
82
|
+
# build and where the cost can be avoided for an unsampled {Span}.
|
83
|
+
#
|
84
|
+
# Eager example:
|
85
|
+
#
|
86
|
+
# span.add_event(name: 'event', attributes: {'eager' => true})
|
87
|
+
#
|
88
|
+
# Lazy example:
|
89
|
+
#
|
90
|
+
# span.add_event { OpenTelemetry::Trace::Event.new(name: 'event', attributes: {'eager' => false}) }
|
91
|
+
#
|
92
|
+
# Note that the OpenTelemetry project
|
93
|
+
# {https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-semantic-conventions.md
|
94
|
+
# documents} certain "standard event names and keys" which have
|
95
|
+
# prescribed semantic meanings.
|
96
|
+
#
|
97
|
+
# @param [optional String] name Optional name of the event. This is
|
98
|
+
# required if a block is not given.
|
99
|
+
# @param [optional Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] attributes
|
100
|
+
# One or more key:value pairs, where the keys must be strings and the
|
101
|
+
# values may be string, boolean or numeric type. This argument should
|
102
|
+
# only be used when passing in a name.
|
103
|
+
# @param [optional Time] timestamp Optional timestamp for the event.
|
104
|
+
# This argument should only be used when passing in a name.
|
105
|
+
#
|
106
|
+
# @return [self] returns itself
|
107
|
+
def add_event(name: nil, attributes: nil, timestamp: nil)
|
108
|
+
super
|
109
|
+
event = block_given? ? yield : OpenTelemetry::Trace::Event.new(name: name, attributes: attributes, timestamp: timestamp || Time.now)
|
110
|
+
|
111
|
+
@mutex.synchronize do
|
112
|
+
if @ended
|
113
|
+
OpenTelemetry.logger.warn('Calling add_event on an ended Span.')
|
114
|
+
else
|
115
|
+
@events ||= []
|
116
|
+
@events = append_event(@events, event)
|
117
|
+
@total_recorded_events += 1
|
118
|
+
end
|
119
|
+
end
|
120
|
+
self
|
121
|
+
end
|
122
|
+
|
123
|
+
# Record an error during the execution of this span. Multiple errors
|
124
|
+
# can be recorded on a span.
|
125
|
+
#
|
126
|
+
# @param [Exception] error The error to be recorded
|
127
|
+
#
|
128
|
+
# @return [void]
|
129
|
+
def record_error(error)
|
130
|
+
add_event(name: 'error',
|
131
|
+
attributes: {
|
132
|
+
'error.type' => error.class.to_s,
|
133
|
+
'error.message' => error.message,
|
134
|
+
'error.stack' => error.backtrace.join("\n")
|
135
|
+
})
|
136
|
+
end
|
137
|
+
|
138
|
+
# Sets the Status to the Span
|
139
|
+
#
|
140
|
+
# If used, this will override the default Span status. Default is OK.
|
141
|
+
#
|
142
|
+
# Only the value of the last call will be recorded, and implementations
|
143
|
+
# are free to ignore previous calls.
|
144
|
+
#
|
145
|
+
# @param [Status] status The new status, which overrides the default Span
|
146
|
+
# status, which is OK.
|
147
|
+
#
|
148
|
+
# @return [void]
|
149
|
+
def status=(status)
|
150
|
+
super
|
151
|
+
@mutex.synchronize do
|
152
|
+
if @ended
|
153
|
+
OpenTelemetry.logger.warn('Calling status= on an ended Span.')
|
154
|
+
else
|
155
|
+
@status = status
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Updates the Span name
|
161
|
+
#
|
162
|
+
# Upon this update, any sampling behavior based on Span name will depend
|
163
|
+
# on the implementation.
|
164
|
+
#
|
165
|
+
# @param [String] new_name The new operation name, which supersedes
|
166
|
+
# whatever was passed in when the Span was started
|
167
|
+
#
|
168
|
+
# @return [void]
|
169
|
+
def name=(new_name)
|
170
|
+
super
|
171
|
+
@mutex.synchronize do
|
172
|
+
if @ended
|
173
|
+
OpenTelemetry.logger.warn('Calling name= on an ended Span.')
|
174
|
+
else
|
175
|
+
@name = new_name
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
# Finishes the Span
|
181
|
+
#
|
182
|
+
# Implementations MUST ignore all subsequent calls to {#finish} (there
|
183
|
+
# might be exceptions when Tracer is streaming event and has no mutable
|
184
|
+
# state associated with the Span).
|
185
|
+
#
|
186
|
+
# Call to {#finish} MUST not have any effects on child spans. Those may
|
187
|
+
# still be running and can be ended later.
|
188
|
+
#
|
189
|
+
# This API MUST be non-blocking*.
|
190
|
+
#
|
191
|
+
# (*) not actually non-blocking. In particular, it synchronizes on an
|
192
|
+
# internal mutex, which will typically be uncontended, and
|
193
|
+
# {Export::BatchSpanProcessor} will also synchronize on a mutex, if that
|
194
|
+
# processor is used.
|
195
|
+
#
|
196
|
+
# @param [Time] end_timestamp optional end timestamp for the span.
|
197
|
+
#
|
198
|
+
# @return [self] returns itself
|
199
|
+
def finish(end_timestamp: nil)
|
200
|
+
@mutex.synchronize do
|
201
|
+
if @ended
|
202
|
+
OpenTelemetry.logger.warn('Calling finish on an ended Span.')
|
203
|
+
return self
|
204
|
+
end
|
205
|
+
@end_timestamp = end_timestamp || Time.now
|
206
|
+
@attributes.freeze
|
207
|
+
@events.freeze
|
208
|
+
@ended = true
|
209
|
+
end
|
210
|
+
@span_processor.on_finish(self)
|
211
|
+
self
|
212
|
+
end
|
213
|
+
|
214
|
+
# @api private
|
215
|
+
#
|
216
|
+
# Returns a SpanData containing a snapshot of the Span fields. It is
|
217
|
+
# assumed that the Span has been finished, and that no further
|
218
|
+
# modifications will be made to the Span.
|
219
|
+
#
|
220
|
+
# This method should be called *only* from a SpanProcessor prior to
|
221
|
+
# calling the SpanExporter.
|
222
|
+
#
|
223
|
+
# @return [SpanData]
|
224
|
+
def to_span_data
|
225
|
+
SpanData.new(
|
226
|
+
@name,
|
227
|
+
@kind,
|
228
|
+
@status,
|
229
|
+
@parent_span_id,
|
230
|
+
@child_count,
|
231
|
+
@total_recorded_attributes,
|
232
|
+
@total_recorded_events,
|
233
|
+
@total_recorded_links,
|
234
|
+
@start_timestamp,
|
235
|
+
@end_timestamp,
|
236
|
+
@attributes,
|
237
|
+
@links,
|
238
|
+
@events,
|
239
|
+
@library_resource,
|
240
|
+
@instrumentation_library,
|
241
|
+
context.span_id,
|
242
|
+
context.trace_id,
|
243
|
+
context.trace_flags,
|
244
|
+
context.tracestate
|
245
|
+
)
|
246
|
+
end
|
247
|
+
|
248
|
+
# @api private
|
249
|
+
def initialize(context, name, kind, parent_span_id, trace_config, span_processor, attributes, links, start_timestamp, library_resource, instrumentation_library) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
250
|
+
super(span_context: context)
|
251
|
+
@mutex = Mutex.new
|
252
|
+
@name = name
|
253
|
+
@kind = kind
|
254
|
+
@parent_span_id = parent_span_id.freeze || OpenTelemetry::Trace::INVALID_SPAN_ID
|
255
|
+
@trace_config = trace_config
|
256
|
+
@span_processor = span_processor
|
257
|
+
@library_resource = library_resource
|
258
|
+
@instrumentation_library = instrumentation_library
|
259
|
+
@ended = false
|
260
|
+
@status = nil
|
261
|
+
@child_count = 0
|
262
|
+
@total_recorded_events = 0
|
263
|
+
@total_recorded_links = links&.size || 0
|
264
|
+
@total_recorded_attributes = attributes&.size || 0
|
265
|
+
@start_timestamp = start_timestamp
|
266
|
+
@end_timestamp = nil
|
267
|
+
@attributes = attributes.nil? ? nil : Hash[attributes] # We need a mutable copy of attributes.
|
268
|
+
trim_span_attributes(@attributes)
|
269
|
+
@events = nil
|
270
|
+
@links = trim_links(links, trace_config.max_links_count, trace_config.max_attributes_per_link)
|
271
|
+
@span_processor.on_start(self)
|
272
|
+
end
|
273
|
+
|
274
|
+
# TODO: Java implementation overrides finalize to log if a span isn't finished.
|
275
|
+
|
276
|
+
private
|
277
|
+
|
278
|
+
def trim_span_attributes(attrs)
|
279
|
+
return if attrs.nil?
|
280
|
+
|
281
|
+
excess = attrs.size - @trace_config.max_attributes_count
|
282
|
+
# TODO: with Ruby 2.5, replace with the more efficient
|
283
|
+
# attrs.shift(excess) if excess.positive?
|
284
|
+
excess.times { attrs.shift } if excess.positive?
|
285
|
+
nil
|
286
|
+
end
|
287
|
+
|
288
|
+
def trim_links(links, max_links_count, max_attributes_per_link) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
289
|
+
# Fast path (likely) common cases.
|
290
|
+
return nil if links.nil?
|
291
|
+
|
292
|
+
if links.size <= max_links_count &&
|
293
|
+
links.all? { |link| link.attributes.size <= max_attributes_per_link && Internal.valid_attributes?(link.attributes) }
|
294
|
+
return links.frozen? ? links : links.clone.freeze
|
295
|
+
end
|
296
|
+
|
297
|
+
# Slow path: trim attributes for each Link.
|
298
|
+
links.last(max_links_count).map! do |link|
|
299
|
+
attrs = Hash[link.attributes] # link.attributes is frozen, so we need an unfrozen copy to adjust.
|
300
|
+
attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
|
301
|
+
excess = attrs.size - max_attributes_per_link
|
302
|
+
excess.times { attrs.shift } if excess.positive?
|
303
|
+
OpenTelemetry::Trace::Link.new(link.context, attrs)
|
304
|
+
end.freeze
|
305
|
+
end
|
306
|
+
|
307
|
+
def append_event(events, event) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
308
|
+
max_events_count = @trace_config.max_events_count
|
309
|
+
max_attributes_per_event = @trace_config.max_attributes_per_event
|
310
|
+
|
311
|
+
# Fast path (likely) common case.
|
312
|
+
if events.size < max_events_count &&
|
313
|
+
event.attributes.size <= max_attributes_per_event &&
|
314
|
+
Internal.valid_attributes?(event.attributes)
|
315
|
+
return events << event
|
316
|
+
end
|
317
|
+
|
318
|
+
# Slow path.
|
319
|
+
excess = events.size + 1 - max_events_count
|
320
|
+
events.shift(excess) if excess.positive?
|
321
|
+
|
322
|
+
excess = event.attributes.size - max_attributes_per_event
|
323
|
+
if excess.positive? || !Internal.valid_attributes?(event.attributes)
|
324
|
+
attrs = Hash[event.attributes] # event.attributes is frozen, so we need an unfrozen copy to adjust.
|
325
|
+
attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
|
326
|
+
excess = attrs.size - max_attributes_per_event
|
327
|
+
excess.times { attrs.shift } if excess.positive?
|
328
|
+
event = OpenTelemetry::Trace::Event.new(name: event.name, attributes: attrs, timestamp: event.timestamp)
|
329
|
+
end
|
330
|
+
events << event
|
331
|
+
end
|
332
|
+
end
|
333
|
+
# rubocop:enable Metrics/ClassLength
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
module OpenTelemetry
|
8
|
+
module SDK
|
9
|
+
# The Trace module contains the OpenTelemetry tracing reference
|
10
|
+
# implementation.
|
11
|
+
module Trace
|
12
|
+
# SpanData is a Struct containing {Span} data for export.
|
13
|
+
SpanData = Struct.new(:name,
|
14
|
+
:kind,
|
15
|
+
:status,
|
16
|
+
:parent_span_id,
|
17
|
+
:child_count,
|
18
|
+
:total_recorded_attributes,
|
19
|
+
:total_recorded_events,
|
20
|
+
:total_recorded_links,
|
21
|
+
:start_timestamp,
|
22
|
+
:end_timestamp,
|
23
|
+
:attributes,
|
24
|
+
:links,
|
25
|
+
:events,
|
26
|
+
:library_resource,
|
27
|
+
:instrumentation_library,
|
28
|
+
:span_id,
|
29
|
+
:trace_id,
|
30
|
+
:trace_flags,
|
31
|
+
:tracestate)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2020 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
module OpenTelemetry
|
8
|
+
module SDK
|
9
|
+
module Trace
|
10
|
+
# {Tracer} is the SDK implementation of {OpenTelemetry::Trace::Tracer}.
|
11
|
+
class Tracer < OpenTelemetry::Trace::Tracer
|
12
|
+
attr_reader :name
|
13
|
+
attr_reader :version
|
14
|
+
attr_reader :tracer_provider
|
15
|
+
|
16
|
+
# @api private
|
17
|
+
#
|
18
|
+
# Returns a new {Tracer} instance.
|
19
|
+
#
|
20
|
+
# @param [String] name Instrumentation package name
|
21
|
+
# @param [String] version Instrumentation package version
|
22
|
+
# @param [TracerProvider] tracer_provider TracerProvider that initialized the tracer
|
23
|
+
#
|
24
|
+
# @return [Tracer]
|
25
|
+
def initialize(name, version, tracer_provider)
|
26
|
+
@name = name
|
27
|
+
@version = version
|
28
|
+
@instrumentation_library = InstrumentationLibrary.new(name, version)
|
29
|
+
@tracer_provider = tracer_provider
|
30
|
+
end
|
31
|
+
|
32
|
+
def start_root_span(name, attributes: nil, links: nil, start_timestamp: nil, kind: nil)
|
33
|
+
start_span(name, with_parent_context: Context.empty, attributes: attributes, links: links, start_timestamp: start_timestamp, kind: kind)
|
34
|
+
end
|
35
|
+
|
36
|
+
def start_span(name, with_parent: nil, with_parent_context: nil, attributes: nil, links: nil, start_timestamp: nil, kind: nil)
|
37
|
+
name ||= 'empty'
|
38
|
+
|
39
|
+
parent_span_context = with_parent&.context || active_span_context(with_parent_context)
|
40
|
+
parent_span_context = nil unless parent_span_context.valid?
|
41
|
+
parent_span_id = parent_span_context&.span_id
|
42
|
+
tracestate = parent_span_context&.tracestate
|
43
|
+
trace_id = parent_span_context&.trace_id
|
44
|
+
trace_id ||= OpenTelemetry::Trace.generate_trace_id
|
45
|
+
span_id = OpenTelemetry::Trace.generate_span_id
|
46
|
+
sampler = tracer_provider.active_trace_config.sampler
|
47
|
+
result = sampler.should_sample?(trace_id: trace_id, parent_context: parent_span_context, links: links, name: name, kind: kind, attributes: attributes)
|
48
|
+
internal_create_span(result, name, kind, trace_id, span_id, parent_span_id, attributes, links, start_timestamp, tracestate)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def internal_create_span(result, name, kind, trace_id, span_id, parent_span_id, attributes, links, start_timestamp, tracestate) # rubocop:disable Metrics/AbcSize
|
54
|
+
if result.recording? && !tracer_provider.stopped?
|
55
|
+
trace_flags = result.sampled? ? OpenTelemetry::Trace::TraceFlags::SAMPLED : OpenTelemetry::Trace::TraceFlags::DEFAULT
|
56
|
+
context = OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id, trace_flags: trace_flags, tracestate: tracestate)
|
57
|
+
attributes = attributes&.merge(result.attributes) || result.attributes
|
58
|
+
Span.new(
|
59
|
+
context,
|
60
|
+
name,
|
61
|
+
kind,
|
62
|
+
parent_span_id,
|
63
|
+
tracer_provider.active_trace_config,
|
64
|
+
tracer_provider.active_span_processor,
|
65
|
+
attributes,
|
66
|
+
links,
|
67
|
+
start_timestamp || Time.now,
|
68
|
+
tracer_provider.resource,
|
69
|
+
@instrumentation_library
|
70
|
+
)
|
71
|
+
else
|
72
|
+
OpenTelemetry::Trace::Span.new(span_context: OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id))
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|