opentelemetry-sdk 0.11.1 → 0.12.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 640e29efdf46f030e232f9fbb96f43f183438e546b8116eb94f989f83ab06966
4
- data.tar.gz: b6e023f909b6485b2eecd0ef150e4562c659b4d51856f87b226484c1db56b189
3
+ metadata.gz: 718ea2029bb234ea6ed56da8b65923595e275bb4730c3f3ea50bc20c4a01597d
4
+ data.tar.gz: 39e4031d0ef4ff426fe9bd776b4e85a2dd351a77c9dc8e19b80330dc5bf9d544
5
5
  SHA512:
6
- metadata.gz: 5c58bfdb66b128e299ed2742c2327939ef02139c10b825d8ca5fe9a0c241340971e027a53c70de1777c9abf7a3c33e318ef936aa026aa6c4c496d6c0e3132a86
7
- data.tar.gz: c426b41723e57ddcfbe332f4b4e01982056b47813cc9afb05b4385f7bdeacc91544ee2c707bd98ce4824488ab89b407cc7ba73568e6b954cf7d39aed878f476c
6
+ metadata.gz: caa3842133c57ab739e0c21d8e1cd5f9cd58293e1e34055eef6b18fd4ff0869a39edbe87bcbb0fef7e76ea733f9ea0f9ff84663cf70a3a88820b7074c78c156d
7
+ data.tar.gz: f3e8176d0b495ea3784b6f8e2b2676000e35b3db7a1fab7b0890014ff69accd9caa69a00af02b4668964d3837aabd470bdaec78bda0d06ada1a9cfe6f1b000a7
@@ -1,5 +1,13 @@
1
1
  # Release History: opentelemetry-sdk
2
2
 
3
+ ### v0.12.0 / 2020-12-24
4
+
5
+ * ADDED: Structured error handling
6
+ * ADDED: Pluggable ID generation
7
+ * FIXED: BSP dropped span buffer full reporting
8
+ * FIXED: Implement SDK environment variables
9
+ * FIXED: Remove incorrect TODO
10
+
3
11
  ### v0.11.1 / 2020-12-16
4
12
 
5
13
  * FIXED: BSP dropped span buffer full reporting
@@ -18,6 +18,11 @@ module OpenTelemetry
18
18
  module SDK
19
19
  extend self
20
20
 
21
+ # ConfigurationError is an exception type used to wrap configuration errors
22
+ # passed to OpenTelemetry.error_handler. This can be used to distinguish
23
+ # errors reported during SDK configuration.
24
+ ConfigurationError = Class.new(OpenTelemetry::Error)
25
+
21
26
  # Configures SDK and instrumentation
22
27
  #
23
28
  # @yieldparam [Configurator] configurator Yields a configurator to the
@@ -57,6 +62,12 @@ module OpenTelemetry
57
62
  configurator = Configurator.new
58
63
  yield configurator if block_given?
59
64
  configurator.configure
65
+ rescue StandardError
66
+ begin
67
+ raise ConfigurationError
68
+ rescue ConfigurationError => e
69
+ OpenTelemetry.handle_error(exception: e, message: 'unexpected configuration error')
70
+ end
60
71
  end
61
72
  end
62
73
  end
@@ -16,7 +16,7 @@ module OpenTelemetry
16
16
  private_constant :USE_MODE_UNSPECIFIED, :USE_MODE_ONE, :USE_MODE_ALL
17
17
 
18
18
  attr_writer :logger, :http_extractors, :http_injectors, :text_map_extractors,
19
- :text_map_injectors
19
+ :text_map_injectors, :error_handler, :id_generator
20
20
 
21
21
  def initialize
22
22
  @instrumentation_names = []
@@ -28,12 +28,17 @@ module OpenTelemetry
28
28
  @span_processors = []
29
29
  @use_mode = USE_MODE_UNSPECIFIED
30
30
  @resource = Resources::Resource.telemetry_sdk
31
+ @id_generator = OpenTelemetry::Trace
31
32
  end
32
33
 
33
34
  def logger
34
35
  @logger ||= OpenTelemetry.logger
35
36
  end
36
37
 
38
+ def error_handler
39
+ @error_handler ||= OpenTelemetry.error_handler
40
+ end
41
+
37
42
  # Accepts a resource object that is merged with the default telemetry sdk
38
43
  # resource. The use of this method is optional, and is provided as means
39
44
  # to include additional resource information.
@@ -110,9 +115,11 @@ module OpenTelemetry
110
115
  # - install instrumentation
111
116
  def configure
112
117
  OpenTelemetry.logger = logger
118
+ OpenTelemetry.error_handler = error_handler
113
119
  OpenTelemetry.baggage = Baggage::Manager.new
114
120
  configure_propagation
115
121
  configure_span_processors
122
+ tracer_provider.id_generator = @id_generator
116
123
  OpenTelemetry.tracer_provider = tracer_provider
117
124
  install_instrumentation
118
125
  end
@@ -45,7 +45,17 @@ module OpenTelemetry
45
45
  end
46
46
 
47
47
  def valid_attributes?(attrs)
48
- attrs.nil? || attrs.all? { |k, v| valid_key?(k) && valid_value?(v) }
48
+ attrs.nil? || attrs.all? do |k, v|
49
+ if !valid_key?(k)
50
+ OpenTelemetry.handle_error(message: "invalid attribute key type #{v.class}")
51
+ false
52
+ elsif !valid_value?(v)
53
+ OpenTelemetry.handle_error(message: "invalid attribute value type #{v.class}")
54
+ false
55
+ else
56
+ true
57
+ end
58
+ end
49
59
  end
50
60
  end
51
61
  end
@@ -22,7 +22,7 @@ module OpenTelemetry
22
22
  def create(attributes = {})
23
23
  frozen_attributes = attributes.each_with_object({}) do |(k, v), memo|
24
24
  raise ArgumentError, 'attribute keys must be strings' unless k.is_a?(String)
25
- raise ArgumentError, 'attribute values must be strings, integers, floats, or booleans' unless Internal.valid_value?(v)
25
+ raise ArgumentError, 'attribute values must be (array of) strings, integers, floats, or booleans' unless Internal.valid_value?(v)
26
26
 
27
27
  memo[-k] = v.freeze
28
28
  end.freeze
@@ -10,20 +10,6 @@ module OpenTelemetry
10
10
  module Config
11
11
  # Class that holds global trace parameters.
12
12
  class TraceConfig
13
- DEFAULT_SAMPLER = Samplers.parent_based(root: Samplers::ALWAYS_ON)
14
- DEFAULT_MAX_ATTRIBUTES_COUNT = 32
15
- DEFAULT_MAX_EVENTS_COUNT = 128
16
- DEFAULT_MAX_LINKS_COUNT = 32
17
- DEFAULT_MAX_ATTRIBUTES_PER_EVENT = 32
18
- DEFAULT_MAX_ATTRIBUTES_PER_LINK = 32
19
-
20
- private_constant(:DEFAULT_SAMPLER,
21
- :DEFAULT_MAX_ATTRIBUTES_COUNT,
22
- :DEFAULT_MAX_EVENTS_COUNT,
23
- :DEFAULT_MAX_LINKS_COUNT,
24
- :DEFAULT_MAX_ATTRIBUTES_PER_EVENT,
25
- :DEFAULT_MAX_ATTRIBUTES_PER_LINK)
26
-
27
13
  # The global default sampler (see {Samplers}).
28
14
  attr_reader :sampler
29
15
 
@@ -46,12 +32,12 @@ module OpenTelemetry
46
32
  #
47
33
  # @return [TraceConfig] with the desired values.
48
34
  # @raise [ArgumentError] if any of the max numbers are not positive.
49
- def initialize(sampler: DEFAULT_SAMPLER,
50
- max_attributes_count: DEFAULT_MAX_ATTRIBUTES_COUNT,
51
- max_events_count: DEFAULT_MAX_EVENTS_COUNT,
52
- max_links_count: DEFAULT_MAX_LINKS_COUNT,
53
- max_attributes_per_event: DEFAULT_MAX_ATTRIBUTES_PER_EVENT,
54
- max_attributes_per_link: DEFAULT_MAX_ATTRIBUTES_PER_LINK)
35
+ def initialize(sampler: sampler_from_environment(Samplers.parent_based(root: Samplers::ALWAYS_ON)),
36
+ max_attributes_count: Integer(ENV.fetch('OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT', 1000)),
37
+ max_events_count: Integer(ENV.fetch('OTEL_SPAN_EVENT_COUNT_LIMIT', 1000)),
38
+ max_links_count: Integer(ENV.fetch('OTEL_SPAN_LINK_COUNT_LIMIT', 1000)),
39
+ max_attributes_per_event: max_attributes_count,
40
+ max_attributes_per_link: max_attributes_count)
55
41
  raise ArgumentError, 'max_attributes_count must be positive' unless max_attributes_count.positive?
56
42
  raise ArgumentError, 'max_events_count must be positive' unless max_events_count.positive?
57
43
  raise ArgumentError, 'max_links_count must be positive' unless max_links_count.positive?
@@ -67,6 +53,22 @@ module OpenTelemetry
67
53
  end
68
54
 
69
55
  # TODO: from_proto
56
+ private
57
+
58
+ def sampler_from_environment(default_sampler) # rubocop:disable Metrics/CyclomaticComplexity
59
+ case ENV['OTEL_TRACE_SAMPLER']
60
+ when 'always_on' then Samplers::ALWAYS_ON
61
+ when 'always_off' then Samplers::ALWAYS_OFF
62
+ when 'traceidratio' then Samplers.trace_id_ratio_based(Float(ENV['OTEL_TRACE_SAMPLER_ARG']))
63
+ when 'parentbased_always_on' then Samplers.parent_based(root: Samplers::ALWAYS_ON)
64
+ when 'parentbased_always_off' then Samplers.parent_based(root: Samplers::ALWAYS_OFF)
65
+ when 'parentbased_traceidratio' then Samplers.parent_based(root: Samplers.trace_id_ratio_based(Float(ENV['OTEL_TRACE_SAMPLER_ARG'])))
66
+ else default_sampler
67
+ end
68
+ rescue StandardError => e
69
+ OpenTelemetry.handle_error(exception: e, message: "installing default sampler #{default_sampler.description}")
70
+ default_sampler
71
+ end
70
72
 
71
73
  # The default {TraceConfig}.
72
74
  DEFAULT = new
@@ -78,8 +78,10 @@ module OpenTelemetry
78
78
  lock do
79
79
  reset_on_fork
80
80
  n = spans.size + 1 - max_queue_size
81
- spans.shift(n) if n.positive?
82
- report_dropped_spans(n, reason: 'buffer-full')
81
+ if n.positive?
82
+ spans.shift(n)
83
+ report_dropped_spans(n, reason: 'buffer-full')
84
+ end
83
85
  spans << span
84
86
  @condition.signal if spans.size > batch_size
85
87
  end
@@ -187,7 +189,7 @@ module OpenTelemetry
187
189
  @metrics_reporter.add_to_counter('otel.bsp.export.success')
188
190
  @metrics_reporter.add_to_counter('otel.bsp.exported_spans', increment: batch.size)
189
191
  else
190
- OpenTelemetry.logger.error("Unable to export #{batch.size} spans")
192
+ OpenTelemetry.handle_error(message: "Unable to export #{batch.size} spans")
191
193
  @metrics_reporter.add_to_counter('otel.bsp.export.failure')
192
194
  report_dropped_spans(batch.size, reason: 'export-failure')
193
195
  end
@@ -57,7 +57,7 @@ module OpenTelemetry
57
57
 
58
58
  @span_exporter&.export([span.to_span_data])
59
59
  rescue => e # rubocop:disable Style/RescueStandardError
60
- OpenTelemetry.logger.error("unexpected error in span.on_finish - #{e}")
60
+ OpenTelemetry.handle_error(exception: e, message: 'unexpected error in span.on_finish')
61
61
  end
62
62
 
63
63
  # Export all ended spans to the configured `Exporter` that have not yet
@@ -19,12 +19,20 @@ module OpenTelemetry
19
19
  @description = description
20
20
  end
21
21
 
22
+ def ==(other)
23
+ @decision == other.decision && @description == other.description
24
+ end
25
+
22
26
  # @api private
23
27
  #
24
28
  # See {Samplers}.
25
29
  def should_sample?(trace_id:, parent_context:, links:, name:, kind:, attributes:)
26
30
  Result.new(decision: @decision, tracestate: OpenTelemetry::Trace.current_span(parent_context).context.tracestate)
27
31
  end
32
+
33
+ protected
34
+
35
+ attr_reader :decision
28
36
  end
29
37
  end
30
38
  end
@@ -26,6 +26,14 @@ module OpenTelemetry
26
26
  @local_parent_not_sampled = local_parent_not_sampled
27
27
  end
28
28
 
29
+ def ==(other)
30
+ @root == other.root &&
31
+ @remote_parent_sampled == other.remote_parent_sampled &&
32
+ @remote_parent_not_sampled == other.remote_parent_not_sampled &&
33
+ @local_parent_sampled == other.local_parent_sampled &&
34
+ @local_parent_not_sampled == other.local_parent_not_sampled
35
+ end
36
+
29
37
  # @api private
30
38
  #
31
39
  # See {Samplers}.
@@ -47,6 +55,10 @@ module OpenTelemetry
47
55
  end
48
56
  delegate.should_sample?(trace_id: trace_id, parent_context: parent_context, links: links, name: name, kind: kind, attributes: attributes)
49
57
  end
58
+
59
+ protected
60
+
61
+ attr_reader :root, :remote_parent_sampled, :remote_parent_not_sampled, :local_parent_sampled, :local_parent_not_sampled
50
62
  end
51
63
  end
52
64
  end
@@ -20,6 +20,10 @@ module OpenTelemetry
20
20
  @description = format('TraceIdRatioBased{%.6f}', probability)
21
21
  end
22
22
 
23
+ def ==(other)
24
+ @description == other.description
25
+ end
26
+
23
27
  # @api private
24
28
  #
25
29
  # See {Samplers}.
@@ -199,7 +199,7 @@ module OpenTelemetry
199
199
  return self
200
200
  end
201
201
  @end_timestamp = end_timestamp || Time.now
202
- @attributes.freeze
202
+ @attributes = validated_attributes(@attributes).freeze
203
203
  @events.freeze
204
204
  @ended = true
205
205
  end
@@ -269,12 +269,16 @@ module OpenTelemetry
269
269
 
270
270
  private
271
271
 
272
+ def validated_attributes(attrs)
273
+ return attrs if Internal.valid_attributes?(attrs)
274
+
275
+ attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
276
+ end
277
+
272
278
  def trim_span_attributes(attrs)
273
279
  return if attrs.nil?
274
280
 
275
281
  excess = attrs.size - @trace_config.max_attributes_count
276
- # TODO: with Ruby 2.5, replace with the more efficient
277
- # attrs.shift(excess) if excess.positive?
278
282
  excess.times { attrs.shift } if excess.positive?
279
283
  nil
280
284
  end
@@ -301,11 +305,12 @@ module OpenTelemetry
301
305
  def append_event(events, event) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
302
306
  max_events_count = @trace_config.max_events_count
303
307
  max_attributes_per_event = @trace_config.max_attributes_per_event
308
+ valid_attributes = Internal.valid_attributes?(event.attributes)
304
309
 
305
310
  # Fast path (likely) common case.
306
311
  if events.size < max_events_count &&
307
312
  event.attributes.size <= max_attributes_per_event &&
308
- Internal.valid_attributes?(event.attributes)
313
+ valid_attributes
309
314
  return events << event
310
315
  end
311
316
 
@@ -314,7 +319,7 @@ module OpenTelemetry
314
319
  events.shift(excess) if excess.positive?
315
320
 
316
321
  excess = event.attributes.size - max_attributes_per_event
317
- if excess.positive? || !Internal.valid_attributes?(event.attributes)
322
+ if excess.positive? || !valid_attributes
318
323
  attrs = Hash[event.attributes] # event.attributes is frozen, so we need an unfrozen copy to adjust.
319
324
  attrs.keep_if { |key, value| Internal.valid_key?(key) && Internal.valid_value?(value) }
320
325
  excess = attrs.size - max_attributes_per_event
@@ -42,7 +42,7 @@ module OpenTelemetry
42
42
  parent_span_id = parent_span_context.span_id
43
43
  trace_id = parent_span_context.trace_id
44
44
  end
45
- trace_id ||= OpenTelemetry::Trace.generate_trace_id
45
+ trace_id ||= tracer_provider.id_generator.generate_trace_id
46
46
  sampler = tracer_provider.active_trace_config.sampler
47
47
  result = sampler.should_sample?(trace_id: trace_id, parent_context: with_parent, links: links, name: name, kind: kind, attributes: attributes)
48
48
  internal_create_span(result, name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, with_parent)
@@ -50,10 +50,11 @@ module OpenTelemetry
50
50
 
51
51
  private
52
52
 
53
- def internal_create_span(result, name, kind, trace_id, parent_span_id, attributes, links, start_timestamp, parent_context) # rubocop:disable Metrics/AbcSize
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
54
55
  if result.recording? && !tracer_provider.stopped?
55
56
  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: result.tracestate)
57
+ context = OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id, span_id: span_id, trace_flags: trace_flags, tracestate: result.tracestate)
57
58
  attributes = attributes&.merge(result.attributes) || result.attributes
58
59
  Span.new(
59
60
  context,
@@ -70,7 +71,7 @@ module OpenTelemetry
70
71
  @instrumentation_library
71
72
  )
72
73
  else
73
- OpenTelemetry::Trace::Span.new(span_context: OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id))
74
+ OpenTelemetry::Trace::Span.new(span_context: OpenTelemetry::Trace::SpanContext.new(trace_id: trace_id, span_id: span_id, tracestate: result.tracestate))
74
75
  end
75
76
  end
76
77
  end
@@ -12,7 +12,7 @@ module OpenTelemetry
12
12
  Key = Struct.new(:name, :version)
13
13
  private_constant(:Key)
14
14
 
15
- attr_accessor :active_trace_config
15
+ attr_accessor :active_trace_config, :id_generator
16
16
  attr_reader :active_span_processor, :stopped, :resource
17
17
  alias stopped? stopped
18
18
 
@@ -24,6 +24,7 @@ module OpenTelemetry
24
24
  @registry = {}
25
25
  @active_span_processor = NoopSpanProcessor.instance
26
26
  @active_trace_config = Config::TraceConfig::DEFAULT
27
+ @id_generator = OpenTelemetry::Trace
27
28
  @registered_span_processors = []
28
29
  @stopped = false
29
30
  @resource = resource
@@ -7,6 +7,6 @@
7
7
  module OpenTelemetry
8
8
  module SDK
9
9
  ## Current OpenTelemetry version
10
- VERSION = '0.11.1'
10
+ VERSION = '0.12.0'
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: 0.11.1
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-16 00:00:00.000000000 Z
11
+ date: 2020-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opentelemetry-api
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.11.0
19
+ version: 0.12.0
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: 0.11.0
26
+ version: 0.12.0
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.11.0
33
+ version: 0.12.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.11.0
40
+ version: 0.12.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -201,10 +201,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby
201
201
  licenses:
202
202
  - Apache-2.0
203
203
  metadata:
204
- changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v0.11.1/file.CHANGELOG.html
204
+ changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v0.12.0/file.CHANGELOG.html
205
205
  source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/master/sdk
206
206
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby/issues
207
- documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v0.11.1
207
+ documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-sdk/v0.12.0
208
208
  post_install_message:
209
209
  rdoc_options: []
210
210
  require_paths: