opentelemetry-sdk 1.0.0.rc1 → 1.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5e0b06b7a072f462eeef975e4342a9e9800fb85794e2625f454d17eb20ef2be
4
- data.tar.gz: a42a11084a981f147bdc5a3c5d21f1a4a1752d5a971819658573cb4964d43f49
3
+ metadata.gz: d43559eaa2be64a3597d078d032c168429702e47bdeaee1ac454dc5e74f9f496
4
+ data.tar.gz: 583f42bb1b6543d6375d3cfc8e4bd2319d5146306f42a73d726ca73f3c01e56d
5
5
  SHA512:
6
- metadata.gz: 670059ca8ef7d7aeba579c6b70a8217ac5e4fa879b39afee715b4ff1852e8643bf87581943b70d949480a728c531d20efc8ed42fa878f0a5291d55f31cc22607
7
- data.tar.gz: 604feaa8d9952cce4a0eff45b743601b85ea2a5f7b03af316c5ae45c6df2fd57a2712d43d417a30a2df44b493fd6c8bc03f8924014a75d2fd29b9bfe513c7adf
6
+ metadata.gz: 14112a30284f0ececabcf75dda91f6634b3748c44ccec52e19c6d42e7fae59979e6ea82ef276d21ea5503d2b4f35821945b62d2b1afc83c5bcb9d4a6a9ce6bf4
7
+ data.tar.gz: 87aaa08db88b9495c86ee1135cdcbfb95827fbbed42edf3280500d86025ff269ee3af95c675e20231267e7b561082cea12df7738db004922468246ad437805fb
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Release History: opentelemetry-sdk
2
2
 
3
+ ### v1.0.0.rc2 / 2021-06-23
4
+
5
+ * BREAKING CHANGE: Remove optional parent_context from in_span [729](https://github.com/open-telemetry/opentelemetry-ruby/pull/729)
6
+ * BREAKING CHANGE: Replace Time.now with Process.clock_gettime [717](https://github.com/open-telemetry/opentelemetry-ruby/pull/717)
7
+ * BREAKING CHANGE: Refactor Baggage to remove Noop* [800](https://github.com/open-telemetry/opentelemetry-ruby/pull/800)
8
+ * BREAKING CHANGE: Remove unnecessary readers from SDK Tracer [820](https://github.com/open-telemetry/opentelemetry-ruby/pull/820)
9
+ - Tracer no longer surfaces attribute readers for the name, version, or tracer_provider
10
+ * BREAKING CHANGE: Total order constraint on span.status= [805](https://github.com/open-telemetry/opentelemetry-ruby/pull/805)
11
+
12
+ * ADDED: Add Tracer.non_recording_span to API [799](https://github.com/open-telemetry/opentelemetry-ruby/pull/799)
13
+ * ADDED: Add unnamed tracer warning message [830](https://github.com/open-telemetry/opentelemetry-ruby/pull/830)
14
+ * ADDED: Allow disabling of install messages [831](https://github.com/open-telemetry/opentelemetry-ruby/pull/831)
15
+ * FIXED: Rename cloud.zone to cloud.availability_zone [734](https://github.com/open-telemetry/opentelemetry-ruby/pull/734)
16
+ * FIXED: Improve attribute error messages [742](https://github.com/open-telemetry/opentelemetry-ruby/pull/742)
17
+ * FIXED: Support OTEL_SERVICE_NAME env var [806]https://github.com/open-telemetry/opentelemetry-ruby/pull/806
18
+ * FIXED: Flakey tracer provider test
19
+
3
20
  ### v1.0.0.rc1 / 2021-05-21
4
21
 
5
22
  * BREAKING CHANGE: Remove optional parent_context from in_span
@@ -55,7 +55,7 @@ module OpenTelemetry
55
55
  # Configure everything
56
56
  #
57
57
  # OpenTelemetry::SDK.configure do |c|
58
- # c.logger = Logger.new('/dev/null')
58
+ # c.logger = Logger.new(File::NULL)
59
59
  # c.add_span_processor SpanProcessor.new(SomeExporter.new)
60
60
  # c.use_all
61
61
  # end
@@ -74,6 +74,7 @@ module OpenTelemetry
74
74
  end
75
75
 
76
76
  require 'opentelemetry/sdk/configurator'
77
+ require 'opentelemetry/sdk/forwarding_logger'
77
78
  require 'opentelemetry/sdk/internal'
78
79
  require 'opentelemetry/sdk/instrumentation_library'
79
80
  require 'opentelemetry/sdk/resources'
@@ -15,7 +15,7 @@ module OpenTelemetry
15
15
 
16
16
  private_constant :USE_MODE_UNSPECIFIED, :USE_MODE_ONE, :USE_MODE_ALL
17
17
 
18
- attr_writer :logger, :propagators, :error_handler, :id_generator
18
+ attr_writer :propagators, :error_handler, :id_generator
19
19
 
20
20
  def initialize
21
21
  @instrumentation_names = []
@@ -31,6 +31,15 @@ module OpenTelemetry
31
31
  @logger ||= OpenTelemetry.logger
32
32
  end
33
33
 
34
+ # Accepts a logger and wraps it in the {ForwardingLogger} which allows
35
+ # for controlling the severity level emitted by the OpenTelemetry.logger
36
+ # independently of the supplied logger.
37
+ #
38
+ # @param [Logger] new_logger The logger for OpenTelemetry to use
39
+ def logger=(new_logger)
40
+ @logger = ForwardingLogger.new(new_logger, level: ENV['OTEL_LOG_LEVEL'] || Logger::INFO)
41
+ end
42
+
34
43
  def error_handler
35
44
  @error_handler ||= OpenTelemetry.error_handler
36
45
  end
@@ -112,7 +121,6 @@ module OpenTelemetry
112
121
  def configure
113
122
  OpenTelemetry.logger = logger
114
123
  OpenTelemetry.error_handler = error_handler
115
- OpenTelemetry.baggage = Baggage::Manager.new
116
124
  configure_propagation
117
125
  configure_span_processors
118
126
  tracer_provider.id_generator = @id_generator
@@ -123,7 +131,7 @@ module OpenTelemetry
123
131
  private
124
132
 
125
133
  def tracer_provider
126
- @tracer_provider ||= Trace::TracerProvider.new(@resource)
134
+ @tracer_provider ||= Trace::TracerProvider.new(resource: @resource)
127
135
  end
128
136
 
129
137
  def check_use_mode!(mode)
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module OpenTelemetry
6
+ module SDK
7
+ # The ForwardingLogger provides a wrapper to control the OpenTelemetry
8
+ # log level, while respecting the configured level of the supplied logger.
9
+ # If the OTEL_LOG_LEVEL is set to debug, and the supplied logger is configured
10
+ # with an ERROR log level, only OpenTelemetry logs at the ERROR level or higher
11
+ # will be emitted.
12
+ class ForwardingLogger
13
+ def initialize(logger, level:) # rubocop:disable Metrics/CyclomaticComplexity
14
+ @logger = logger
15
+
16
+ if level.is_a?(Integer)
17
+ @level = level
18
+ else
19
+ case level.to_s.downcase
20
+ when 'debug'
21
+ @level = Logger::DEBUG
22
+ when 'info'
23
+ @level = Logger::INFO
24
+ when 'warn'
25
+ @level = Logger::WARN
26
+ when 'error'
27
+ @level = Logger::ERROR
28
+ when 'fatal'
29
+ @level = Logger::FATAL
30
+ when 'unknown'
31
+ @level = Logger::UNKNOWN
32
+ else
33
+ raise ArgumentError, "invalid log level: #{level}"
34
+ end
35
+ end
36
+ end
37
+
38
+ def add(severity, message = nil, progname = nil)
39
+ return true if severity < @level
40
+
41
+ @logger.add(severity, message, progname)
42
+ end
43
+
44
+ def debug(progname = nil, &block)
45
+ add(Logger::DEBUG, nil, progname, &block)
46
+ end
47
+
48
+ def info(progname = nil, &block)
49
+ add(Logger::INFO, nil, progname, &block)
50
+ end
51
+
52
+ def warn(progname = nil, &block)
53
+ add(Logger::WARN, nil, progname, &block)
54
+ end
55
+
56
+ def error(progname = nil, &block)
57
+ add(Logger::ERROR, nil, progname, &block)
58
+ end
59
+
60
+ def fatal(progname = nil, &block)
61
+ add(Logger::FATAL, nil, progname, &block)
62
+ end
63
+
64
+ def unknown(progname = nil, &block)
65
+ add(Logger::UNKNOWN, nil, progname, &block)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -31,7 +31,7 @@ module OpenTelemetry
31
31
  end
32
32
 
33
33
  def default
34
- @default ||= create(Constants::SERVICE_RESOURCE[:name] => 'unknown_service').merge(process).merge(telemetry_sdk)
34
+ @default ||= create(Constants::SERVICE_RESOURCE[:name] => 'unknown_service').merge(process).merge(telemetry_sdk).merge(service_name_from_env)
35
35
  end
36
36
 
37
37
  def telemetry_sdk
@@ -64,6 +64,13 @@ module OpenTelemetry
64
64
 
65
65
  create(resource_attributes)
66
66
  end
67
+
68
+ private
69
+
70
+ def service_name_from_env
71
+ service_name = ENV['OTEL_SERVICE_NAME']
72
+ create(Constants::SERVICE_RESOURCE[:name] => service_name) unless service_name.nil?
73
+ end
67
74
  end
68
75
 
69
76
  # @api private
@@ -14,12 +14,11 @@ module OpenTelemetry
14
14
  end
15
15
 
16
16
  require 'opentelemetry/sdk/trace/samplers'
17
- require 'opentelemetry/sdk/trace/config'
17
+ require 'opentelemetry/sdk/trace/span_limits'
18
18
  require 'opentelemetry/sdk/trace/event'
19
19
  require 'opentelemetry/sdk/trace/export'
20
- require 'opentelemetry/sdk/trace/multi_span_processor'
21
- require 'opentelemetry/sdk/trace/noop_span_processor'
22
20
  require 'opentelemetry/sdk/trace/span_data'
21
+ require 'opentelemetry/sdk/trace/span_processor'
23
22
  require 'opentelemetry/sdk/trace/span'
24
23
  require 'opentelemetry/sdk/trace/tracer'
25
24
  require 'opentelemetry/sdk/trace/tracer_provider'
@@ -31,6 +31,5 @@ require 'opentelemetry/sdk/trace/export/batch_span_processor'
31
31
  require 'opentelemetry/sdk/trace/export/console_span_exporter'
32
32
  require 'opentelemetry/sdk/trace/export/in_memory_span_exporter'
33
33
  require 'opentelemetry/sdk/trace/export/metrics_reporter'
34
- require 'opentelemetry/sdk/trace/export/multi_span_exporter'
35
- require 'opentelemetry/sdk/trace/export/noop_span_exporter'
34
+ require 'opentelemetry/sdk/trace/export/span_exporter'
36
35
  require 'opentelemetry/sdk/trace/export/simple_span_processor'
@@ -8,24 +8,25 @@ module OpenTelemetry
8
8
  module SDK
9
9
  module Trace
10
10
  module Export
11
- # A noop exporter that demonstrates and documents the SpanExporter
12
- # duck type. SpanExporter allows different tracing services to export
11
+ # SpanExporter describes a duck type. It is not required to subclass this
12
+ # class to provide an implementation of SpanExporter, provided the interface is
13
+ # satisfied. SpanExporter allows different tracing services to export
13
14
  # recorded data for sampled spans in their own format.
14
15
  #
15
16
  # To export data an exporter MUST be registered to the {TracerProvider} using
16
- # a {SimpleSpanProcessor} or a {BatchSpanProcessor}.
17
- class NoopSpanExporter
17
+ # a {SpanProcessor} implementation.
18
+ class SpanExporter
18
19
  def initialize
19
20
  @stopped = false
20
21
  end
21
22
 
22
- # Called to export sampled {Span}s.
23
+ # Called to export sampled {SpanData}s.
23
24
  #
24
- # @param [Enumerable<Span>] spans the list of sampled {Span}s to be
25
+ # @param [Enumerable<SpanData>] span_data the list of sampled {SpanData} to be
25
26
  # exported.
26
27
  # @param [optional Numeric] timeout An optional timeout in seconds.
27
28
  # @return [Integer] the result of the export.
28
- def export(spans, timeout: nil)
29
+ def export(span_data, timeout: nil)
29
30
  return SUCCESS unless @stopped
30
31
 
31
32
  FAILURE
@@ -10,13 +10,13 @@ module OpenTelemetry
10
10
  # Implementation of {OpenTelemetry::Trace::Span} that records trace events.
11
11
  #
12
12
  # This implementation includes reader methods intended to allow access to
13
- # internal state by SpanProcessors (see {NoopSpanProcessor} for the interface).
13
+ # internal state by {SpanProcessor}s.
14
14
  # Instrumentation should use the API provided by {OpenTelemetry::Trace::Span}
15
15
  # and should consider {Span} to be write-only.
16
16
  #
17
17
  # rubocop:disable Metrics/ClassLength
18
18
  class Span < OpenTelemetry::Trace::Span
19
- DEFAULT_STATUS = OpenTelemetry::Trace::Status.new(OpenTelemetry::Trace::Status::UNSET)
19
+ DEFAULT_STATUS = OpenTelemetry::Trace::Status.unset
20
20
  EMPTY_ATTRIBUTES = {}.freeze
21
21
 
22
22
  private_constant :DEFAULT_STATUS, :EMPTY_ATTRIBUTES
@@ -159,7 +159,7 @@ module OpenTelemetry
159
159
  event_attributes = {
160
160
  'exception.type' => exception.class.to_s,
161
161
  'exception.message' => exception.message,
162
- 'exception.stacktrace' => exception.full_message(highlight: false, order: :top)
162
+ 'exception.stacktrace' => exception.full_message(highlight: false, order: :top).encode('UTF-8', invalid: :replace, undef: :replace, replace: '�')
163
163
  }
164
164
  event_attributes.merge!(attributes) unless attributes.nil?
165
165
  add_event('exception', attributes: event_attributes)
@@ -167,20 +167,23 @@ module OpenTelemetry
167
167
 
168
168
  # Sets the Status to the Span
169
169
  #
170
- # If used, this will override the default Span status. Default is OK.
170
+ # If used, this will override the default Span status. Default has code = Status::UNSET.
171
171
  #
172
- # Only the value of the last call will be recorded, and implementations
173
- # are free to ignore previous calls.
172
+ # An attempt to set the status with code == Status::UNSET is ignored.
173
+ # If the status is set with code == Status::OK, any further attempt to set the status
174
+ # is ignored.
174
175
  #
175
176
  # @param [Status] status The new status, which overrides the default Span
176
- # status, which is OK.
177
+ # status, which has code = Status::UNSET.
177
178
  #
178
179
  # @return [void]
179
180
  def status=(status)
181
+ return if status.code == OpenTelemetry::Trace::Status::UNSET
182
+
180
183
  @mutex.synchronize do
181
184
  if @ended
182
185
  OpenTelemetry.logger.warn('Calling status= on an ended Span.')
183
- else
186
+ elsif @status.code != OpenTelemetry::Trace::Status::OK
184
187
  @status = status
185
188
  end
186
189
  end
@@ -235,7 +238,7 @@ module OpenTelemetry
235
238
  @events.freeze
236
239
  @ended = true
237
240
  end
238
- @span_processor.on_finish(self)
241
+ @span_processors.each { |processor| processor.on_finish(self) }
239
242
  self
240
243
  end
241
244
 
@@ -273,14 +276,14 @@ module OpenTelemetry
273
276
  end
274
277
 
275
278
  # @api private
276
- def initialize(context, parent_context, name, kind, parent_span_id, trace_config, span_processor, attributes, links, start_timestamp, resource, instrumentation_library) # rubocop:disable Metrics/AbcSize
279
+ def initialize(context, parent_context, name, kind, parent_span_id, span_limits, span_processors, attributes, links, start_timestamp, resource, instrumentation_library) # rubocop:disable Metrics/AbcSize
277
280
  super(span_context: context)
278
281
  @mutex = Mutex.new
279
282
  @name = name
280
283
  @kind = kind
281
284
  @parent_span_id = parent_span_id.freeze || OpenTelemetry::Trace::INVALID_SPAN_ID
282
- @trace_config = trace_config
283
- @span_processor = span_processor
285
+ @span_limits = span_limits
286
+ @span_processors = span_processors
284
287
  @resource = resource
285
288
  @instrumentation_library = instrumentation_library
286
289
  @ended = false
@@ -293,8 +296,8 @@ module OpenTelemetry
293
296
  @attributes = attributes.nil? ? nil : Hash[attributes] # We need a mutable copy of attributes.
294
297
  trim_span_attributes(@attributes)
295
298
  @events = nil
296
- @links = trim_links(links, trace_config.max_links_count, trace_config.max_attributes_per_link)
297
- @span_processor.on_start(self, parent_context)
299
+ @links = trim_links(links, span_limits.link_count_limit, span_limits.attribute_per_link_count_limit)
300
+ @span_processors.each { |processor| processor.on_start(self, parent_context) }
298
301
  end
299
302
 
300
303
  # TODO: Java implementation overrides finalize to log if a span isn't finished.
@@ -310,7 +313,7 @@ module OpenTelemetry
310
313
  def trim_span_attributes(attrs)
311
314
  return if attrs.nil?
312
315
 
313
- excess = attrs.size - @trace_config.max_attributes_count
316
+ excess = attrs.size - @span_limits.attribute_count_limit
314
317
  excess.times { attrs.shift } if excess.positive?
315
318
  truncate_attribute_values(attrs)
316
319
  nil
@@ -319,51 +322,51 @@ module OpenTelemetry
319
322
  def truncate_attribute_values(attrs)
320
323
  return EMPTY_ATTRIBUTES if attrs.nil?
321
324
 
322
- max_attributes_length = @trace_config.max_attributes_length
323
- attrs.each { |key, value| attrs[key] = OpenTelemetry::Common::Utilities.truncate(value, max_attributes_length) } if max_attributes_length
325
+ attribute_length_limit = @span_limits.attribute_length_limit
326
+ attrs.each { |key, value| attrs[key] = OpenTelemetry::Common::Utilities.truncate(value, attribute_length_limit) } if attribute_length_limit
324
327
  attrs
325
328
  end
326
329
 
327
- def trim_links(links, max_links_count, max_attributes_per_link) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
330
+ def trim_links(links, link_count_limit, attribute_per_link_count_limit) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
328
331
  # Fast path (likely) common cases.
329
332
  return nil if links.nil?
330
333
 
331
- if links.size <= max_links_count &&
332
- links.all? { |link| link.attributes.size <= max_attributes_per_link && Internal.valid_attributes?(name, 'link', link.attributes) }
334
+ if links.size <= link_count_limit &&
335
+ links.all? { |link| link.attributes.size <= attribute_per_link_count_limit && Internal.valid_attributes?(name, 'link', link.attributes) }
333
336
  return links.frozen? ? links : links.clone.freeze
334
337
  end
335
338
 
336
339
  # Slow path: trim attributes for each Link.
337
- links.last(max_links_count).map! do |link|
340
+ links.last(link_count_limit).map! do |link|
338
341
  attrs = Hash[link.attributes] # link.attributes is frozen, so we need an unfrozen copy to adjust.
339
342
  attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
340
- excess = attrs.size - max_attributes_per_link
343
+ excess = attrs.size - attribute_per_link_count_limit
341
344
  excess.times { attrs.shift } if excess.positive?
342
345
  OpenTelemetry::Trace::Link.new(link.span_context, attrs)
343
346
  end.freeze
344
347
  end
345
348
 
346
349
  def append_event(events, event) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
347
- max_events_count = @trace_config.max_events_count
348
- max_attributes_per_event = @trace_config.max_attributes_per_event
350
+ event_count_limit = @span_limits.event_count_limit
351
+ attribute_per_event_count_limit = @span_limits.attribute_per_event_count_limit
349
352
  valid_attributes = Internal.valid_attributes?(name, 'event', event.attributes)
350
353
 
351
354
  # Fast path (likely) common case.
352
- if events.size < max_events_count &&
353
- event.attributes.size <= max_attributes_per_event &&
355
+ if events.size < event_count_limit &&
356
+ event.attributes.size <= attribute_per_event_count_limit &&
354
357
  valid_attributes
355
358
  return events << event
356
359
  end
357
360
 
358
361
  # Slow path.
359
- excess = events.size + 1 - max_events_count
362
+ excess = events.size + 1 - event_count_limit
360
363
  events.shift(excess) if excess.positive?
361
364
 
362
- excess = event.attributes.size - max_attributes_per_event
365
+ excess = event.attributes.size - attribute_per_event_count_limit
363
366
  if excess.positive? || !valid_attributes
364
367
  attrs = Hash[event.attributes] # event.attributes is frozen, so we need an unfrozen copy to adjust.
365
368
  attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
366
- excess = attrs.size - max_attributes_per_event
369
+ excess = attrs.size - attribute_per_event_count_limit
367
370
  excess.times { attrs.shift } if excess.positive?
368
371
  event = Event.new(event.name, attrs.freeze, event.timestamp)
369
372
  end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright The OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
7
+ module OpenTelemetry
8
+ module SDK
9
+ module Trace
10
+ # Class that holds global trace parameters.
11
+ class SpanLimits
12
+ # The global default max number of attributes per {Span}.
13
+ attr_reader :attribute_count_limit
14
+
15
+ # The global default max length of attribute value per {Span}.
16
+ attr_reader :attribute_length_limit
17
+
18
+ # The global default max number of {OpenTelemetry::SDK::Trace::Event}s per {Span}.
19
+ attr_reader :event_count_limit
20
+
21
+ # The global default max number of {OpenTelemetry::Trace::Link} entries per {Span}.
22
+ attr_reader :link_count_limit
23
+
24
+ # The global default max number of attributes per {OpenTelemetry::SDK::Trace::Event}.
25
+ attr_reader :attribute_per_event_count_limit
26
+
27
+ # The global default max number of attributes per {OpenTelemetry::Trace::Link}.
28
+ attr_reader :attribute_per_link_count_limit
29
+
30
+ # Returns a {SpanLimits} with the desired values.
31
+ #
32
+ # @return [SpanLimits] with the desired values.
33
+ # @raise [ArgumentError] if any of the max numbers are not positive.
34
+ def initialize(attribute_count_limit: Integer(ENV.fetch('OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT', 128)), # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
35
+ attribute_length_limit: ENV['OTEL_RUBY_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT'],
36
+ event_count_limit: Integer(ENV.fetch('OTEL_SPAN_EVENT_COUNT_LIMIT', 128)),
37
+ link_count_limit: Integer(ENV.fetch('OTEL_SPAN_LINK_COUNT_LIMIT', 128)),
38
+ attribute_per_event_count_limit: attribute_count_limit,
39
+ attribute_per_link_count_limit: attribute_count_limit)
40
+ raise ArgumentError, 'attribute_count_limit must be positive' unless attribute_count_limit.positive?
41
+ raise ArgumentError, 'attribute_length_limit must not be less than 32' unless attribute_length_limit.nil? || Integer(attribute_length_limit) >= 32
42
+ raise ArgumentError, 'event_count_limit must be positive' unless event_count_limit.positive?
43
+ raise ArgumentError, 'link_count_limit must be positive' unless link_count_limit.positive?
44
+ raise ArgumentError, 'attribute_per_event_count_limit must be positive' unless attribute_per_event_count_limit.positive?
45
+ raise ArgumentError, 'attribute_per_link_count_limit must be positive' unless attribute_per_link_count_limit.positive?
46
+
47
+ @attribute_count_limit = attribute_count_limit
48
+ @attribute_length_limit = attribute_length_limit.nil? ? nil : Integer(attribute_length_limit)
49
+ @event_count_limit = event_count_limit
50
+ @link_count_limit = link_count_limit
51
+ @attribute_per_event_count_limit = attribute_per_event_count_limit
52
+ @attribute_per_link_count_limit = attribute_per_link_count_limit
53
+ end
54
+
55
+ # The default {SpanLimits}.
56
+ DEFAULT = new
57
+ end
58
+ end
59
+ end
60
+ end
@@ -4,17 +4,14 @@
4
4
  #
5
5
  # SPDX-License-Identifier: Apache-2.0
6
6
 
7
- require 'singleton'
8
-
9
7
  module OpenTelemetry
10
8
  module SDK
11
9
  module Trace
12
- # NoopSpanProcessor is a singleton implementation of the duck type
13
- # SpanProcessor that provides synchronous no-op hooks for when a
14
- # {Span} is started or when a {Span} is ended.
15
- class NoopSpanProcessor
16
- include Singleton
17
-
10
+ # SpanProcessor describes a duck type and provides synchronous no-op hooks for when a
11
+ # {Span} is started or when a {Span} is ended. It is not required to subclass this
12
+ # class to provide an implementation of SpanProcessor, provided the interface is
13
+ # satisfied.
14
+ class SpanProcessor
18
15
  # Called when a {Span} is started, if the {Span#recording?}
19
16
  # returns true.
20
17
  #
@@ -9,10 +9,6 @@ module OpenTelemetry
9
9
  module Trace
10
10
  # {Tracer} is the SDK implementation of {OpenTelemetry::Trace::Tracer}.
11
11
  class Tracer < OpenTelemetry::Trace::Tracer
12
- attr_reader :name
13
- attr_reader :version
14
- attr_reader :tracer_provider
15
-
16
12
  # @api private
17
13
  #
18
14
  # Returns a new {Tracer} instance.
@@ -23,8 +19,6 @@ module OpenTelemetry
23
19
  #
24
20
  # @return [Tracer]
25
21
  def initialize(name, version, tracer_provider)
26
- @name = name
27
- @version = version
28
22
  @instrumentation_library = InstrumentationLibrary.new(name, version)
29
23
  @tracer_provider = tracer_provider
30
24
  end
@@ -42,37 +36,7 @@ module OpenTelemetry
42
36
  parent_span_id = parent_span_context.span_id
43
37
  trace_id = parent_span_context.trace_id
44
38
  end
45
- trace_id ||= tracer_provider.id_generator.generate_trace_id
46
- sampler = tracer_provider.active_trace_config.sampler
47
- result = sampler.should_sample?(trace_id: trace_id, parent_context: with_parent, links: links, name: name, kind: kind, attributes: attributes)
48
- internal_create_span(result, name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, with_parent)
49
- end
50
-
51
- private
52
-
53
- def internal_create_span(result, name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, parent_context) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
54
- span_id = tracer_provider.id_generator.generate_span_id
55
- if result.recording? && !tracer_provider.stopped?
56
- trace_flags = result.sampled? ? OpenTelemetry::Trace::TraceFlags::SAMPLED : OpenTelemetry::Trace::TraceFlags::DEFAULT
57
- context = OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id, span_id: span_id, trace_flags: trace_flags, tracestate: result.tracestate)
58
- attributes = attributes&.merge(result.attributes) || result.attributes
59
- Span.new(
60
- context,
61
- parent_context,
62
- name,
63
- kind,
64
- parent_span_id,
65
- tracer_provider.active_trace_config,
66
- tracer_provider.active_span_processor,
67
- attributes,
68
- links,
69
- start_timestamp,
70
- tracer_provider.resource,
71
- @instrumentation_library
72
- )
73
- else
74
- OpenTelemetry::Trace::Span.new(span_context: OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id, span_id: span_id, tracestate: result.tracestate))
75
- end
39
+ @tracer_provider.internal_create_span(name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, with_parent, @instrumentation_library)
76
40
  end
77
41
  end
78
42
  end
@@ -8,24 +8,35 @@ module OpenTelemetry
8
8
  module SDK
9
9
  module Trace
10
10
  # {TracerProvider} is the SDK implementation of {OpenTelemetry::Trace::TracerProvider}.
11
- class TracerProvider < OpenTelemetry::Trace::TracerProvider
11
+ class TracerProvider < OpenTelemetry::Trace::TracerProvider # rubocop:disable Metrics/ClassLength
12
12
  Key = Struct.new(:name, :version)
13
13
  private_constant(:Key)
14
14
 
15
- attr_accessor :active_trace_config, :id_generator
16
- attr_reader :active_span_processor, :stopped, :resource
17
- alias stopped? stopped
15
+ attr_accessor :span_limits, :id_generator, :sampler
16
+ attr_reader :resource
18
17
 
19
18
  # Returns a new {TracerProvider} instance.
20
19
  #
20
+ # @param [optional Sampler] sampler The sampling policy for new spans
21
+ # @param [optional Resource] resource The resource to associate with spans
22
+ # created by Tracers created by this TracerProvider
23
+ # @param [optional IDGenerator] id_generator The trace and span ID generation
24
+ # policy
25
+ # @param [optional SpanLimits] span_limits The limits to apply to attribute,
26
+ # event and link counts for Spans created by Tracers created by this
27
+ # TracerProvider
28
+ #
21
29
  # @return [TracerProvider]
22
- def initialize(resource = OpenTelemetry::SDK::Resources::Resource.create)
30
+ def initialize(sampler: sampler_from_environment(Samplers.parent_based(root: Samplers::ALWAYS_ON)),
31
+ resource: OpenTelemetry::SDK::Resources::Resource.create,
32
+ id_generator: OpenTelemetry::Trace,
33
+ span_limits: SpanLimits::DEFAULT)
23
34
  @mutex = Mutex.new
24
35
  @registry = {}
25
- @active_span_processor = NoopSpanProcessor.instance
26
- @active_trace_config = Config::TraceConfig::DEFAULT
27
- @id_generator = OpenTelemetry::Trace
28
- @registered_span_processors = []
36
+ @span_processors = []
37
+ @span_limits = span_limits
38
+ @sampler = sampler
39
+ @id_generator = id_generator
29
40
  @stopped = false
30
41
  @resource = resource
31
42
  end
@@ -39,6 +50,7 @@ module OpenTelemetry
39
50
  def tracer(name = nil, version = nil)
40
51
  name ||= ''
41
52
  version ||= ''
53
+ OpenTelemetry.logger.warn 'calling TracerProvider#tracer without providing a tracer name.' if name.empty?
42
54
  @mutex.synchronize { @registry[Key.new(name, version)] ||= Tracer.new(name, version, self) }
43
55
  end
44
56
 
@@ -52,14 +64,24 @@ module OpenTelemetry
52
64
  # After this is called all the newly created {Span}s will be no-op.
53
65
  #
54
66
  # @param [optional Numeric] timeout An optional timeout in seconds.
67
+ # @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
68
+ # a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
55
69
  def shutdown(timeout: nil)
56
70
  @mutex.synchronize do
57
71
  if @stopped
58
72
  OpenTelemetry.logger.warn('calling Tracer#shutdown multiple times.')
59
- return
73
+ return Export::FAILURE
74
+ end
75
+
76
+ start_time = OpenTelemetry::Common::Utilities.timeout_timestamp
77
+ results = @span_processors.map do |processor|
78
+ remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
79
+ break [Export::TIMEOUT] if remaining_timeout&.zero?
80
+
81
+ processor.shutdown(timeout: remaining_timeout)
60
82
  end
61
- @active_span_processor.shutdown(timeout: timeout)
62
83
  @stopped = true
84
+ results.max || Export::SUCCESS
63
85
  end
64
86
  end
65
87
 
@@ -78,7 +100,14 @@ module OpenTelemetry
78
100
  @mutex.synchronize do
79
101
  return Export::SUCCESS if @stopped
80
102
 
81
- @active_span_processor.force_flush(timeout: timeout)
103
+ start_time = OpenTelemetry::Common::Utilities.timeout_timestamp
104
+ results = @span_processors.map do |processor|
105
+ remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
106
+ return Export::TIMEOUT if remaining_timeout&.zero?
107
+
108
+ processor.force_flush(timeout: remaining_timeout)
109
+ end
110
+ results.max || Export::SUCCESS
82
111
  end
83
112
  end
84
113
 
@@ -91,13 +120,53 @@ module OpenTelemetry
91
120
  OpenTelemetry.logger.warn('calling Tracer#add_span_processor after shutdown.')
92
121
  return
93
122
  end
94
- @registered_span_processors << span_processor
95
- @active_span_processor = if @registered_span_processors.size == 1
96
- span_processor
97
- else
98
- MultiSpanProcessor.new(@registered_span_processors.dup)
99
- end
123
+ @span_processors = @span_processors.dup.push(span_processor)
124
+ end
125
+ end
126
+
127
+ # @api private
128
+ def internal_create_span(name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, parent_context, instrumentation_library) # rubocop:disable Metrics/MethodLength
129
+ trace_id ||= @id_generator.generate_trace_id
130
+ result = @sampler.should_sample?(trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes)
131
+ span_id = @id_generator.generate_span_id
132
+ if result.recording? && !@stopped
133
+ trace_flags = result.sampled? ? OpenTelemetry::Trace::TraceFlags::SAMPLED : OpenTelemetry::Trace::TraceFlags::DEFAULT
134
+ context = OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id, span_id: span_id, trace_flags: trace_flags, tracestate: result.tracestate)
135
+ attributes = attributes&.merge(result.attributes) || result.attributes
136
+ Span.new(
137
+ context,
138
+ parent_context,
139
+ name,
140
+ kind,
141
+ parent_span_id,
142
+ @span_limits,
143
+ @span_processors,
144
+ attributes,
145
+ links,
146
+ start_timestamp,
147
+ @resource,
148
+ instrumentation_library
149
+ )
150
+ else
151
+ OpenTelemetry::Trace.non_recording_span(OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id, span_id: span_id, tracestate: result.tracestate))
152
+ end
153
+ end
154
+
155
+ private
156
+
157
+ def sampler_from_environment(default_sampler) # rubocop:disable Metrics/CyclomaticComplexity
158
+ case ENV['OTEL_TRACES_SAMPLER']
159
+ when 'always_on' then Samplers::ALWAYS_ON
160
+ when 'always_off' then Samplers::ALWAYS_OFF
161
+ when 'traceidratio' then Samplers.trace_id_ratio_based(Float(ENV.fetch('OTEL_TRACES_SAMPLER_ARG', 1.0)))
162
+ when 'parentbased_always_on' then Samplers.parent_based(root: Samplers::ALWAYS_ON)
163
+ when 'parentbased_always_off' then Samplers.parent_based(root: Samplers::ALWAYS_OFF)
164
+ when 'parentbased_traceidratio' then Samplers.parent_based(root: Samplers.trace_id_ratio_based(Float(ENV.fetch('OTEL_TRACES_SAMPLER_ARG', 1.0))))
165
+ else default_sampler
100
166
  end
167
+ rescue StandardError => e
168
+ OpenTelemetry.handle_error(exception: e, message: "installing default sampler #{default_sampler.description}")
169
+ default_sampler
101
170
  end
102
171
  end
103
172
  end
@@ -7,6 +7,6 @@
7
7
  module OpenTelemetry
8
8
  module SDK
9
9
  ## Current OpenTelemetry version
10
- VERSION = '1.0.0.rc1'
10
+ VERSION = '1.0.0.rc2'
11
11
  end
12
12
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc1
4
+ version: 1.0.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-21 00:00:00.000000000 Z
11
+ date: 2021-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opentelemetry-api
@@ -16,42 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.0.0.rc1
19
+ version: 1.0.0.rc2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.0.0.rc1
26
+ version: 1.0.0.rc2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: opentelemetry-common
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.18.0
33
+ version: 0.19.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.18.0
40
+ version: 0.19.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: opentelemetry-instrumentation-base
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.18.0
47
+ version: 0.18.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.18.0
54
+ version: 0.18.1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -192,25 +192,21 @@ files:
192
192
  - lib/opentelemetry-sdk.rb
193
193
  - lib/opentelemetry/sdk.rb
194
194
  - lib/opentelemetry/sdk/configurator.rb
195
+ - lib/opentelemetry/sdk/forwarding_logger.rb
195
196
  - lib/opentelemetry/sdk/instrumentation_library.rb
196
197
  - lib/opentelemetry/sdk/internal.rb
197
198
  - lib/opentelemetry/sdk/resources.rb
198
199
  - lib/opentelemetry/sdk/resources/constants.rb
199
200
  - lib/opentelemetry/sdk/resources/resource.rb
200
201
  - lib/opentelemetry/sdk/trace.rb
201
- - lib/opentelemetry/sdk/trace/config.rb
202
- - lib/opentelemetry/sdk/trace/config/trace_config.rb
203
202
  - lib/opentelemetry/sdk/trace/event.rb
204
203
  - lib/opentelemetry/sdk/trace/export.rb
205
204
  - lib/opentelemetry/sdk/trace/export/batch_span_processor.rb
206
205
  - lib/opentelemetry/sdk/trace/export/console_span_exporter.rb
207
206
  - lib/opentelemetry/sdk/trace/export/in_memory_span_exporter.rb
208
207
  - lib/opentelemetry/sdk/trace/export/metrics_reporter.rb
209
- - lib/opentelemetry/sdk/trace/export/multi_span_exporter.rb
210
- - lib/opentelemetry/sdk/trace/export/noop_span_exporter.rb
211
208
  - lib/opentelemetry/sdk/trace/export/simple_span_processor.rb
212
- - lib/opentelemetry/sdk/trace/multi_span_processor.rb
213
- - lib/opentelemetry/sdk/trace/noop_span_processor.rb
209
+ - lib/opentelemetry/sdk/trace/export/span_exporter.rb
214
210
  - lib/opentelemetry/sdk/trace/samplers.rb
215
211
  - lib/opentelemetry/sdk/trace/samplers/constant_sampler.rb
216
212
  - lib/opentelemetry/sdk/trace/samplers/decision.rb
@@ -219,6 +215,8 @@ files:
219
215
  - lib/opentelemetry/sdk/trace/samplers/trace_id_ratio_based.rb
220
216
  - lib/opentelemetry/sdk/trace/span.rb
221
217
  - lib/opentelemetry/sdk/trace/span_data.rb
218
+ - lib/opentelemetry/sdk/trace/span_limits.rb
219
+ - lib/opentelemetry/sdk/trace/span_processor.rb
222
220
  - lib/opentelemetry/sdk/trace/tracer.rb
223
221
  - lib/opentelemetry/sdk/trace/tracer_provider.rb
224
222
  - lib/opentelemetry/sdk/version.rb
@@ -226,10 +224,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby
226
224
  licenses:
227
225
  - Apache-2.0
228
226
  metadata:
229
- changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v1.0.0.rc1/file.CHANGELOG.html
227
+ changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v1.0.0.rc2/file.CHANGELOG.html
230
228
  source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/sdk
231
229
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby/issues
232
- documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v1.0.0.rc1
230
+ documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v1.0.0.rc2
233
231
  post_install_message:
234
232
  rdoc_options: []
235
233
  require_paths:
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright The OpenTelemetry Authors
4
- #
5
- # SPDX-License-Identifier: Apache-2.0
6
-
7
- module OpenTelemetry
8
- module SDK
9
- module Trace
10
- # The Config module contains the configuration logic for the
11
- # OpenTelemetry SDK.
12
- module Config
13
- end
14
- end
15
- end
16
- end
17
-
18
- require 'opentelemetry/sdk/trace/config/trace_config'
@@ -1,85 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright The OpenTelemetry Authors
4
- #
5
- # SPDX-License-Identifier: Apache-2.0
6
-
7
- module OpenTelemetry
8
- module SDK
9
- module Trace
10
- module Config
11
- # Class that holds global trace parameters.
12
- class TraceConfig
13
- # The global default sampler (see {Samplers}).
14
- attr_reader :sampler
15
-
16
- # The global default max number of attributes per {Span}.
17
- attr_reader :max_attributes_count
18
-
19
- # The global default max length of attribute value per {Span}.
20
- attr_reader :max_attributes_length
21
-
22
- # The global default max number of {OpenTelemetry::SDK::Trace::Event}s per {Span}.
23
- attr_reader :max_events_count
24
-
25
- # The global default max number of {OpenTelemetry::Trace::Link} entries per {Span}.
26
- attr_reader :max_links_count
27
-
28
- # The global default max number of attributes per {OpenTelemetry::SDK::Trace::Event}.
29
- attr_reader :max_attributes_per_event
30
-
31
- # The global default max number of attributes per {OpenTelemetry::Trace::Link}.
32
- attr_reader :max_attributes_per_link
33
-
34
- # Returns a {TraceConfig} with the desired values.
35
- #
36
- # @return [TraceConfig] with the desired values.
37
- # @raise [ArgumentError] if any of the max numbers are not positive.
38
- def initialize(sampler: sampler_from_environment(Samplers.parent_based(root: Samplers::ALWAYS_ON)), # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
39
- max_attributes_count: Integer(ENV.fetch('OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT', 128)),
40
- max_attributes_length: ENV['OTEL_RUBY_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT'],
41
- max_events_count: Integer(ENV.fetch('OTEL_SPAN_EVENT_COUNT_LIMIT', 128)),
42
- max_links_count: Integer(ENV.fetch('OTEL_SPAN_LINK_COUNT_LIMIT', 128)),
43
- max_attributes_per_event: max_attributes_count,
44
- max_attributes_per_link: max_attributes_count)
45
- raise ArgumentError, 'max_attributes_count must be positive' unless max_attributes_count.positive?
46
- raise ArgumentError, 'max_attributes_length must not be less than 32' unless max_attributes_length.nil? || Integer(max_attributes_length) >= 32
47
- raise ArgumentError, 'max_events_count must be positive' unless max_events_count.positive?
48
- raise ArgumentError, 'max_links_count must be positive' unless max_links_count.positive?
49
- raise ArgumentError, 'max_attributes_per_event must be positive' unless max_attributes_per_event.positive?
50
- raise ArgumentError, 'max_attributes_per_link must be positive' unless max_attributes_per_link.positive?
51
-
52
- @sampler = sampler
53
- @max_attributes_count = max_attributes_count
54
- @max_attributes_length = max_attributes_length.nil? ? nil : Integer(max_attributes_length)
55
- @max_events_count = max_events_count
56
- @max_links_count = max_links_count
57
- @max_attributes_per_event = max_attributes_per_event
58
- @max_attributes_per_link = max_attributes_per_link
59
- end
60
-
61
- # TODO: from_proto
62
- private
63
-
64
- def sampler_from_environment(default_sampler) # rubocop:disable Metrics/CyclomaticComplexity
65
- case ENV['OTEL_TRACES_SAMPLER']
66
- when 'always_on' then Samplers::ALWAYS_ON
67
- when 'always_off' then Samplers::ALWAYS_OFF
68
- when 'traceidratio' then Samplers.trace_id_ratio_based(Float(ENV.fetch('OTEL_TRACES_SAMPLER_ARG', 1.0)))
69
- when 'parentbased_always_on' then Samplers.parent_based(root: Samplers::ALWAYS_ON)
70
- when 'parentbased_always_off' then Samplers.parent_based(root: Samplers::ALWAYS_OFF)
71
- when 'parentbased_traceidratio' then Samplers.parent_based(root: Samplers.trace_id_ratio_based(Float(ENV.fetch('OTEL_TRACES_SAMPLER_ARG', 1.0))))
72
- else default_sampler
73
- end
74
- rescue StandardError => e
75
- OpenTelemetry.handle_error(exception: e, message: "installing default sampler #{default_sampler.description}")
76
- default_sampler
77
- end
78
-
79
- # The default {TraceConfig}.
80
- DEFAULT = new
81
- end
82
- end
83
- end
84
- end
85
- end
@@ -1,76 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright The OpenTelemetry Authors
4
- #
5
- # SPDX-License-Identifier: Apache-2.0
6
-
7
- module OpenTelemetry
8
- module SDK
9
- module Trace
10
- module Export
11
- # Implementation of the SpanExporter duck type that simply forwards all
12
- # received spans to a collection of SpanExporters.
13
- #
14
- # Can be used to export to multiple backends using the same
15
- # SpanProcessor like a {SimpleSpanProcessor} or a
16
- # {BatchSpanProcessor}.
17
- class MultiSpanExporter
18
- def initialize(span_exporters)
19
- @span_exporters = span_exporters.clone.freeze
20
- end
21
-
22
- # Called to export sampled {Span}s.
23
- #
24
- # @param [Enumerable<Span>] spans the list of sampled {Span}s to be
25
- # exported.
26
- # @param [optional Numeric] timeout An optional timeout in seconds.
27
- # @return [Integer] the result of the export.
28
- def export(spans, timeout: nil)
29
- start_time = OpenTelemetry::Common::Utilities.timeout_timestamp
30
- results = @span_exporters.map do |span_exporter|
31
- span_exporter.export(spans, timeout: OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time))
32
- rescue => e # rubocop:disable Style/RescueStandardError
33
- OpenTelemetry.logger.warn("exception raised by export - #{e}")
34
- FAILURE
35
- end
36
- results.uniq.max || SUCCESS
37
- end
38
-
39
- # Called when {TracerProvider#force_flush} is called, if this exporter is
40
- # registered to a {TracerProvider} object.
41
- #
42
- # @param [optional Numeric] timeout An optional timeout in seconds.
43
- # @return [Integer] SUCCESS if no error occurred, FAILURE if a
44
- # non-specific failure occurred, TIMEOUT if a timeout occurred.
45
- def force_flush(timeout: nil)
46
- start_time = OpenTelemetry::Common::Utilities.timeout_timestamp
47
- results = @span_exporters.map do |processor|
48
- remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
49
- return TIMEOUT if remaining_timeout&.zero?
50
-
51
- processor.force_flush(timeout: remaining_timeout)
52
- end
53
- results.uniq.max || SUCCESS
54
- end
55
-
56
- # Called when {TracerProvider#shutdown} is called, if this exporter is
57
- # registered to a {TracerProvider} object.
58
- #
59
- # @param [optional Numeric] timeout An optional timeout in seconds.
60
- # @return [Integer] SUCCESS if no error occurred, FAILURE if a
61
- # non-specific failure occurred, TIMEOUT if a timeout occurred.
62
- def shutdown(timeout: nil)
63
- start_time = OpenTelemetry::Common::Utilities.timeout_timestamp
64
- results = @span_exporters.map do |processor|
65
- remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
66
- return TIMEOUT if remaining_timeout&.zero?
67
-
68
- processor.shutdown(timeout: remaining_timeout)
69
- end
70
- results.uniq.max || SUCCESS
71
- end
72
- end
73
- end
74
- end
75
- end
76
- end
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright The OpenTelemetry Authors
4
- #
5
- # SPDX-License-Identifier: Apache-2.0
6
-
7
- module OpenTelemetry
8
- module SDK
9
- module Trace
10
- # Implementation of the SpanProcessor duck type that simply forwards all
11
- # received events to a list of SpanProcessors.
12
- class MultiSpanProcessor
13
- # Creates a new {MultiSpanProcessor}.
14
- #
15
- # @param [Enumerable<SpanProcessor>] span_processors a collection of
16
- # SpanProcessors.
17
- # @return [MultiSpanProcessor]
18
- def initialize(span_processors)
19
- @span_processors = span_processors.to_a.freeze
20
- end
21
-
22
- # Called when a {Span} is started, if the {Span#recording?}
23
- # returns true.
24
- #
25
- # This method is called synchronously on the execution thread, should
26
- # not throw or block the execution thread.
27
- #
28
- # @param [Span] span the {Span} that just started.
29
- # @param [Context] parent_context the parent {Context} of the newly
30
- # started span.
31
- def on_start(span, parent_context)
32
- @span_processors.each { |processor| processor.on_start(span, parent_context) }
33
- end
34
-
35
- # Called when a {Span} is ended, if the {Span#recording?}
36
- # returns true.
37
- #
38
- # This method is called synchronously on the execution thread, should
39
- # not throw or block the execution thread.
40
- #
41
- # @param [Span] span the {Span} that just ended.
42
- def on_finish(span)
43
- @span_processors.each { |processor| processor.on_finish(span) }
44
- end
45
-
46
- # Export all ended spans to the configured `Exporter` that have not yet
47
- # been exported.
48
- #
49
- # This method should only be called in cases where it is absolutely
50
- # necessary, such as when using some FaaS providers that may suspend
51
- # the process after an invocation, but before the `Processor` exports
52
- # the completed spans.
53
- #
54
- # @param [optional Numeric] timeout An optional timeout in seconds.
55
- # @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
56
- # a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
57
- def force_flush(timeout: nil)
58
- start_time = OpenTelemetry::Common::Utilities.timeout_timestamp
59
- results = @span_processors.map do |processor|
60
- remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
61
- return Export::TIMEOUT if remaining_timeout&.zero?
62
-
63
- processor.force_flush(timeout: remaining_timeout)
64
- end
65
- results.uniq.max
66
- end
67
-
68
- # Called when {TracerProvider#shutdown} is called.
69
- #
70
- # @param [optional Numeric] timeout An optional timeout in seconds.
71
- # @return [Integer] Export::SUCCESS if no error occurred, Export::FAILURE if
72
- # a non-specific failure occurred, Export::TIMEOUT if a timeout occurred.
73
- def shutdown(timeout: nil)
74
- start_time = OpenTelemetry::Common::Utilities.timeout_timestamp
75
- results = @span_processors.map do |processor|
76
- remaining_timeout = OpenTelemetry::Common::Utilities.maybe_timeout(timeout, start_time)
77
- return Export::TIMEOUT if remaining_timeout&.zero?
78
-
79
- processor.shutdown(timeout: remaining_timeout)
80
- end
81
- results.uniq.max
82
- end
83
- end
84
- end
85
- end
86
- end