opentelemetry-api 1.10.1 → 1.11.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 577b4d995e92df80c49e13b5995b56235170108a93fdf101b38e2de820412bee
4
- data.tar.gz: 7d01b537dba1d74c3f151729511ce30c881382f7f3984fef38409678eb329aee
3
+ metadata.gz: 8f644a53d810a077cc3a490e49b8f4ae2b232557a51ff7764c5c137c4cf9065d
4
+ data.tar.gz: 5a8ce03439efaff86ae15ad66271700819b3331b94294b7e10b2a1bb8d89febe
5
5
  SHA512:
6
- metadata.gz: 4ee45cb43c2e7ab4adb6ed95902d9921f63ce2cef8e4afdbea6ff24ece293f59f954a3f628d5a1d02c2a00367a2916e8034f4e2a2c5733d94603074cd1943822
7
- data.tar.gz: 64e63c75db2dc7a5c7c5e0018aa4eff78d019d394026679c83fa07beb918999a037da5f3fe4b87c9b1ae5c61fc53bb8f4917c8a11949ee829cda96da54a32a10
6
+ metadata.gz: 64d8b2489ba3f982966be8edabaaf0d9ffb1b1e28657a5991f1abc84c06fb1228be7bee58a1d2cd432ff392a6abde2e54b6acfae7dc218b2f76f06e1d0166854
7
+ data.tar.gz: 1b2482b2cf3e8a6649b96a8f67c8e6fdd4da6c1ceaec08f7acd44b294763e55f0f9f6fc399738dabe476db61094a49c5bd98383d0f395d768d70b6ea63ac7ca7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Release History: opentelemetry-api
2
2
 
3
+ ### v1.11.1 / 2026-09-15
4
+
5
+ * FIXED: Enforce W3C Baggage limits on the extract path (#2298)
6
+ * DOCS: Document custom error handlers (#2264)
7
+
8
+ ### v1.11.0 / 2026-07-21
9
+
10
+ * ADDED: Add attributes support to instrumentation scope for tracers (#2094)
11
+
3
12
  ### v1.10.1 / 2026-07-08
4
13
 
5
14
  * DOCS: Update source for gemspec links to RubyDoc (#2123)
@@ -55,17 +55,10 @@ module OpenTelemetry
55
55
  header = getter.get(carrier, BAGGAGE_KEY)
56
56
  return context if header.nil? || header.empty?
57
57
 
58
- entries = header.gsub(/\s/, '').split(',')
58
+ entries = split_entries(header)
59
59
 
60
60
  OpenTelemetry::Baggage.build(context: context) do |builder|
61
- entries.each do |entry|
62
- # Note metadata is currently unused in OpenTelemetry, but is part
63
- # the W3C spec where it's referred to as properties. We preserve
64
- # the properties (as-is) so that they can be propagated elsewhere.
65
- kv, meta = entry.split(';', 2)
66
- k, v = kv.split('=').map! { |part| URI.decode_uri_component(part) }
67
- builder.set_value(k, v, metadata: meta)
68
- end
61
+ decode_entries(entries, builder)
69
62
  end
70
63
  rescue StandardError => e
71
64
  OpenTelemetry.logger.debug "Error extracting W3C baggage: #{e.message}"
@@ -82,6 +75,38 @@ module OpenTelemetry
82
75
 
83
76
  private
84
77
 
78
+ def split_entries(header)
79
+ return header.split(',') if header.bytesize <= MAX_TOTAL_LENGTH
80
+
81
+ window = header.byteslice(0, MAX_TOTAL_LENGTH + 1)
82
+ last_separator = window.byterindex(',')
83
+ return [] unless last_separator
84
+
85
+ window.byteslice(0, last_separator).split(',')
86
+ end
87
+
88
+ def decode_entries(entries, builder)
89
+ decoded_length = 0
90
+ decoded_count = 0
91
+ entries.each do |raw_entry|
92
+ break unless decoded_count < MAX_ENTRIES
93
+
94
+ entry = raw_entry.gsub(/\s/, '')
95
+ next if entry.empty?
96
+ next unless entry.bytesize <= MAX_ENTRY_LENGTH &&
97
+ entry.bytesize + decoded_length <= MAX_TOTAL_LENGTH
98
+
99
+ # Note metadata is currently unused in OpenTelemetry, but is part
100
+ # the W3C spec where it's referred to as properties. We preserve
101
+ # the properties (as-is) so that they can be propagated elsewhere.
102
+ kv, meta = entry.split(';', 2)
103
+ k, v = kv.split('=').map! { |part| URI.decode_uri_component(part) }
104
+ builder.set_value(k, v, metadata: meta)
105
+ decoded_length += entry.bytesize + 1
106
+ decoded_count += 1
107
+ end
108
+ end
109
+
85
110
  def encode(baggage)
86
111
  result = +''
87
112
  encoded_count = 0
@@ -15,7 +15,7 @@ module OpenTelemetry # rubocop:disable Style/Documentation
15
15
  EMPTY_ENTRIES = {}.freeze
16
16
  private_constant :EMPTY_ENTRIES
17
17
 
18
- DetachError = Class.new(OpenTelemetry::Error)
18
+ DetachError = Class.new(OpenTelemetry::Error) # rubocop:disable Style/EmptyClassDefinition
19
19
 
20
20
  class << self
21
21
  # Returns a key used to index a value in a Context
@@ -67,6 +67,7 @@ module OpenTelemetry # rubocop:disable Style/Documentation
67
67
  #
68
68
  # @param [Context] ctx The context to be made active
69
69
  # @yield [context] Yields context to the block
70
+ # @yieldparam [Context] context The active context
70
71
  def with_current(ctx)
71
72
  token = attach(ctx)
72
73
  yield ctx
@@ -79,9 +80,10 @@ module OpenTelemetry # rubocop:disable Style/Documentation
79
80
 
80
81
  # @param [String] key The lookup key
81
82
  # @param [Object] value The object stored under key
82
- # @param [Callable] Block to execute in a new context
83
83
  # @yield [context, value] Yields the newly created context and value to
84
84
  # the block
85
+ # @yieldparam [Context] context The newly created context
86
+ # @yieldparam [Object] value The object stored under key
85
87
  def with_value(key, value)
86
88
  ctx = current.set_value(key, value)
87
89
  token = attach(ctx)
@@ -93,12 +95,12 @@ module OpenTelemetry # rubocop:disable Style/Documentation
93
95
  # Execute a block in a new context where its values are merged with the
94
96
  # incoming values. Restores the previous context after the block executes.
95
97
 
96
- # @param [String] key The lookup key
97
98
  # @param [Hash] values Will be merged with values of the current context
98
99
  # and returned in a new context
99
- # @param [Callable] Block to execute in a new context
100
100
  # @yield [context, values] Yields the newly created context and values
101
101
  # to the block
102
+ # @yieldparam [Context] context The newly created context
103
+ # @yieldparam [Hash] values The values merged into the new context
102
104
  def with_values(values)
103
105
  ctx = current.set_values(values)
104
106
  token = attach(ctx)
@@ -119,6 +121,9 @@ module OpenTelemetry # rubocop:disable Style/Documentation
119
121
  Fiber.current.opentelemetry_context = []
120
122
  end
121
123
 
124
+ # Returns an empty context.
125
+ #
126
+ # @return [Context]
122
127
  def empty
123
128
  new(EMPTY_ENTRIES)
124
129
  end
@@ -160,7 +165,6 @@ module OpenTelemetry # rubocop:disable Style/Documentation
160
165
  #
161
166
  # @param [Hash] values The values to be merged with the current context's
162
167
  # entries.
163
- # @param [Object] value Object to be stored under key
164
168
  # @return [Context]
165
169
  def set_values(values) # rubocop:disable Naming/AccessorMethodName
166
170
  Context.new(@entries.merge(values))
@@ -13,9 +13,22 @@ module OpenTelemetry
13
13
  # It delegates to a "real" TracerProvider after the global tracer provider is registered.
14
14
  # It returns {ProxyTracer} instances until the delegate is installed.
15
15
  class ProxyTracerProvider < Trace::TracerProvider
16
- Key = Struct.new(:name, :version)
16
+ Key = Struct.new(:name, :version, :attributes)
17
17
  private_constant(:Key)
18
18
 
19
+ # Wraps a legacy TracerProvider whose `#tracer` method does not accept
20
+ # the `attributes:` keyword argument, dropping the argument on delegation.
21
+ class LegacyProviderWrapper
22
+ def initialize(legacy_provider)
23
+ @legacy_provider = legacy_provider
24
+ end
25
+
26
+ def tracer(name = nil, version = nil, attributes: nil)
27
+ @legacy_provider.tracer(name, version)
28
+ end
29
+ end
30
+ private_constant(:LegacyProviderWrapper)
31
+
19
32
  # Returns a new {ProxyTracerProvider} instance.
20
33
  #
21
34
  # @return [ProxyTracerProvider]
@@ -35,25 +48,45 @@ module OpenTelemetry
35
48
  return
36
49
  end
37
50
 
51
+ provider = LegacyProviderWrapper.new(provider) unless supports_attributes?(provider)
52
+
38
53
  @mutex.synchronize do
39
54
  @delegate = provider
40
- @registry.each { |key, tracer| tracer.delegate = provider.tracer(key.name, key.version) }
55
+ @registry.each { |key, tracer| tracer.delegate = @delegate.tracer(key.name, key.version, attributes: key.attributes) }
41
56
  end
42
57
  end
43
58
 
44
59
  # Returns a {Tracer} instance.
45
60
  #
46
- # @param [optional String] name Instrumentation package name
47
- # @param [optional String] version Instrumentation package version
61
+ # Supports both positional arguments (legacy) and keyword arguments:
62
+ # tracer('name', '1.0') # legacy positional
63
+ # tracer(name: 'name', version: '1.0', attributes: {...}) # keyword
64
+ #
65
+ # When both positional and keyword arguments are provided for the same
66
+ # parameter, the keyword argument takes precedence.
67
+ #
68
+ # @param [String] name Instrumentation scope name
69
+ # @param [String] version Instrumentation scope version
70
+ # @param [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] attributes
71
+ # Instrumentation scope attributes
48
72
  #
49
73
  # @return [Tracer]
50
- def tracer(name = nil, version = nil)
74
+ def tracer(deprecated_name = nil, deprecated_version = nil, name: nil, version: nil, attributes: nil)
75
+ name ||= deprecated_name
76
+ version ||= deprecated_version
51
77
  @mutex.synchronize do
52
- return @delegate.tracer(name, version) unless @delegate.nil?
78
+ return @delegate.tracer(name, version, attributes: attributes) unless @delegate.nil?
53
79
 
54
- @registry[Key.new(name, version)] ||= ProxyTracer.new
80
+ @registry[Key.new(name, version, attributes)] ||= ProxyTracer.new
55
81
  end
56
82
  end
83
+
84
+ private
85
+
86
+ def supports_attributes?(provider)
87
+ provider.respond_to?(:tracer) &&
88
+ provider.method(:tracer).parameters.any? { |_, n| n == :attributes }
89
+ end
57
90
  end
58
91
  end
59
92
  end
@@ -11,10 +11,12 @@ module OpenTelemetry
11
11
  # https://www.w3.org/TR/trace-context/
12
12
  # {Trace::SpanContext}
13
13
  class TraceParent
14
+ # rubocop:disable Style/EmptyClassDefinition
14
15
  InvalidFormatError = Class.new(Error)
15
16
  InvalidVersionError = Class.new(Error)
16
17
  InvalidTraceIDError = Class.new(Error)
17
18
  InvalidSpanIDError = Class.new(Error)
19
+ # rubocop:enable Style/EmptyClassDefinition
18
20
 
19
21
  TRACE_PARENT_HEADER = 'traceparent'
20
22
  SUPPORTED_VERSION = 0
@@ -93,7 +93,7 @@ module OpenTelemetry
93
93
  # documents} certain "standard attributes" that have prescribed semantic
94
94
  # meanings.
95
95
  #
96
- # @param [OpenTelemetry::Trace::Link] the link object to add on the {Span}.
96
+ # @param [OpenTelemetry::Trace::Link] link The link object to add on the {Span}.
97
97
  #
98
98
  # @return [self] returns itself
99
99
  def add_link(link)
@@ -40,7 +40,7 @@ module OpenTelemetry
40
40
  #
41
41
  # @return [Boolean]
42
42
  def sampled?
43
- (@flags & 1) != 0
43
+ @flags.anybits?(1)
44
44
  end
45
45
 
46
46
  DEFAULT = from_byte(0)
@@ -34,7 +34,7 @@ module OpenTelemetry
34
34
  def in_span(name, attributes: nil, links: nil, start_timestamp: nil, kind: nil, record_exception: true)
35
35
  span = nil
36
36
  span = start_span(name, attributes: attributes, links: links, start_timestamp: start_timestamp, kind: kind)
37
- Trace.with_span(span) { |s, c| yield s, c }
37
+ Trace.with_span(span) { |s, c| yield s, c } # rubocop:disable Style/ExplicitBlockArgument
38
38
  rescue Exception => e # rubocop:disable Lint/RescueException
39
39
  span&.record_exception(e) if record_exception
40
40
  span&.status = Status.error("Unhandled exception of type: #{e.class}")
@@ -10,11 +10,20 @@ module OpenTelemetry
10
10
  class TracerProvider
11
11
  # Returns a {Tracer} instance.
12
12
  #
13
- # @param [optional String] name Instrumentation package name
14
- # @param [optional String] version Instrumentation package version
13
+ # Supports both positional arguments (legacy) and keyword arguments:
14
+ # tracer('name', '1.0') # legacy positional
15
+ # tracer(name: 'name', version: '1.0', attributes: {...}) # keyword
16
+ #
17
+ # When both positional and keyword arguments are provided for the same
18
+ # parameter, the keyword argument takes precedence.
19
+ #
20
+ # @param [String] name Instrumentation scope name
21
+ # @param [String] version Instrumentation scope version
22
+ # @param [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] attributes
23
+ # Instrumentation scope attributes
15
24
  #
16
25
  # @return [Tracer]
17
- def tracer(name = nil, version = nil)
26
+ def tracer(deprecated_name = nil, deprecated_version = nil, name: nil, version: nil, attributes: nil)
18
27
  @tracer ||= Tracer.new
19
28
  end
20
29
  end
@@ -75,7 +75,7 @@ module OpenTelemetry
75
75
  # @return [Tracestate]
76
76
  def initialize(hash)
77
77
  excess = hash.size - MAX_MEMBER_COUNT
78
- hash = Hash[hash.drop(excess)] if excess.positive?
78
+ hash = hash.drop(excess).to_h if excess.positive?
79
79
  @hash = hash.freeze
80
80
  end
81
81
 
@@ -105,7 +105,7 @@ module OpenTelemetry
105
105
  return self
106
106
  end
107
107
 
108
- h = Hash[@hash]
108
+ h = @hash.to_h.dup
109
109
  h[key] = value
110
110
  self.class.create(h)
111
111
  end
@@ -118,7 +118,7 @@ module OpenTelemetry
118
118
  def delete(key)
119
119
  return self unless @hash.key?(key)
120
120
 
121
- h = Hash[@hash]
121
+ h = @hash.to_h.dup
122
122
  h.delete(key)
123
123
  self.class.create(h)
124
124
  end
@@ -53,8 +53,9 @@ module OpenTelemetry
53
53
  # Returns a context containing the span, derived from the optional parent
54
54
  # context, or the current context if one was not provided.
55
55
  #
56
- # @param [optional Context] context The context to use as the parent for
57
- # the returned context
56
+ # @param [Span] span The span to store in the returned context.
57
+ # @param [Context] parent_context The optional context to use as the parent
58
+ # for the returned context.
58
59
  def context_with_span(span, parent_context: Context.current)
59
60
  parent_context.set_value(CURRENT_SPAN_KEY, span)
60
61
  end
@@ -6,5 +6,5 @@
6
6
 
7
7
  module OpenTelemetry
8
8
  ## Current OpenTelemetry version
9
- VERSION = '1.10.1'
9
+ VERSION = '1.11.1'
10
10
  end
data/lib/opentelemetry.rb CHANGED
@@ -24,13 +24,28 @@ module OpenTelemetry
24
24
  @mutex = Mutex.new
25
25
  @tracer_provider = Internal::ProxyTracerProvider.new
26
26
 
27
- attr_writer :propagation, :logger, :error_handler
27
+ attr_writer :propagation, :logger
28
28
 
29
29
  # @return [Object, Logger] configured Logger or a default STDOUT Logger.
30
30
  def logger
31
31
  @logger ||= Logger.new($stdout, level: ENV['OTEL_LOG_LEVEL'] || Logger::INFO)
32
32
  end
33
33
 
34
+ # Configures error handler used by {handle_error}.
35
+ #
36
+ # Assigned object must respond to +#call+ and accept the keyword arguments
37
+ # +exception:+ and +message:+.
38
+ #
39
+ # @param [#call] error_handler The error handler to use
40
+ #
41
+ # @example Log OpenTelemetry errors with a custom prefix
42
+ # OpenTelemetry.error_handler = lambda do |exception: nil, message: nil|
43
+ # OpenTelemetry.logger.warn("otel: #{[message, exception&.message].compact.join(' - ')}")
44
+ # end
45
+ def error_handler=(error_handler)
46
+ @error_handler = error_handler
47
+ end
48
+
34
49
  # @return [Callable] configured error handler or a default that logs the
35
50
  # exception and message at ERROR level.
36
51
  def error_handler
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.1
4
+ version: 1.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
@@ -88,10 +88,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby
88
88
  licenses:
89
89
  - Apache-2.0
90
90
  metadata:
91
- changelog_uri: https://rubydoc.info/gems/opentelemetry-api/1.10.1/file/CHANGELOG.md
92
- source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/opentelemetry-api/v1.10.1/api
91
+ changelog_uri: https://rubydoc.info/gems/opentelemetry-api/1.11.1/file/CHANGELOG.md
92
+ source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/opentelemetry-api/v1.11.1/api
93
93
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby/issues
94
- documentation_uri: https://rubydoc.info/gems/opentelemetry-api/1.10.1
94
+ documentation_uri: https://rubydoc.info/gems/opentelemetry-api/1.11.1
95
95
  rdoc_options: []
96
96
  require_paths:
97
97
  - lib
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
106
  - !ruby/object:Gem::Version
107
107
  version: '0'
108
108
  requirements: []
109
- rubygems_version: 4.0.10
109
+ rubygems_version: 4.0.16
110
110
  specification_version: 4
111
111
  summary: A stats collection and distributed tracing framework
112
112
  test_files: []