opentelemetry-api 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/lib/opentelemetry.rb +23 -23
  4. data/lib/opentelemetry/baggage.rb +4 -1
  5. data/lib/opentelemetry/baggage/builder.rb +30 -4
  6. data/lib/opentelemetry/baggage/entry.rb +20 -0
  7. data/lib/opentelemetry/baggage/manager.rb +76 -13
  8. data/lib/opentelemetry/baggage/noop_builder.rb +18 -0
  9. data/lib/opentelemetry/baggage/noop_manager.rb +45 -0
  10. data/lib/opentelemetry/baggage/propagation.rb +9 -18
  11. data/lib/opentelemetry/baggage/propagation/text_map_propagator.rb +109 -0
  12. data/lib/opentelemetry/context/propagation.rb +35 -5
  13. data/lib/opentelemetry/context/propagation/composite_text_map_propagator.rb +105 -0
  14. data/lib/opentelemetry/context/propagation/noop_text_map_propagator.rb +51 -0
  15. data/lib/opentelemetry/context/propagation/{propagator.rb → text_map_propagator.rb} +23 -16
  16. data/lib/opentelemetry/internal.rb +17 -0
  17. data/lib/opentelemetry/internal/proxy_tracer.rb +38 -0
  18. data/lib/opentelemetry/internal/proxy_tracer_provider.rb +59 -0
  19. data/lib/opentelemetry/trace/propagation/trace_context.rb +7 -18
  20. data/lib/opentelemetry/trace/propagation/trace_context/text_map_propagator.rb +73 -0
  21. data/lib/opentelemetry/version.rb +1 -1
  22. metadata +16 -21
  23. data/lib/opentelemetry/baggage/propagation/text_map_extractor.rb +0 -57
  24. data/lib/opentelemetry/baggage/propagation/text_map_injector.rb +0 -52
  25. data/lib/opentelemetry/context/propagation/composite_propagator.rb +0 -72
  26. data/lib/opentelemetry/context/propagation/noop_extractor.rb +0 -26
  27. data/lib/opentelemetry/context/propagation/noop_injector.rb +0 -26
  28. data/lib/opentelemetry/instrumentation.rb +0 -15
  29. data/lib/opentelemetry/instrumentation/base.rb +0 -307
  30. data/lib/opentelemetry/instrumentation/registry.rb +0 -86
  31. data/lib/opentelemetry/metrics.rb +0 -16
  32. data/lib/opentelemetry/metrics/handles.rb +0 -44
  33. data/lib/opentelemetry/metrics/instruments.rb +0 -105
  34. data/lib/opentelemetry/metrics/meter.rb +0 -72
  35. data/lib/opentelemetry/metrics/meter_provider.rb +0 -22
  36. data/lib/opentelemetry/trace/propagation/trace_context/text_map_extractor.rb +0 -52
  37. data/lib/opentelemetry/trace/propagation/trace_context/text_map_injector.rb +0 -49
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2044ecfc3776d70aa668bcbd537f9df904f3a48a19b3b1daa67d0632686b3358
4
- data.tar.gz: 996749298853bb15d62cadff700e06a1f3bcb505f5b49786b713c1daa1796165
3
+ metadata.gz: 9d983ae124f8d6da3e8fa92560912718bdbbc9a3ea89f2012cb2d51e6d80873d
4
+ data.tar.gz: 75bc11d4296b0a21a136b3ada57d6a5cf59c736d61d6d113ab4bbd6195dacb8c
5
5
  SHA512:
6
- metadata.gz: 12c9863e4b90e34f5b4d6e2e3e5b97244d609e5381d554b39d461e77cfff5e7f8130b1389c68743d6fb7ea3080321aa4b12dc56e3ca78cac20fda1cc0100e7b7
7
- data.tar.gz: 990f49fa7ef5e2990283cf4b42af9a6ecaa4989078a7b084568806675a9a2d3ae635bb830bccc9626b51869e3f0bfc9df5406f2cdbfda6c33576e4fd92c26716
6
+ metadata.gz: 2c051831f433ca25fbbdf4662d7ac8e156804bdb98e6dd5d2476597baac55561edc46d32bb3a02d23f7a316e20aee88b6ea5dfae608813933d8d08d5fdbb7afb
7
+ data.tar.gz: 9bd812321d5d84960a4e866a50b1a6b483a6742a4a909118792a72859e7123df0f945fea4476eeb9e5eca6e2b120cfd09eee55475a7ef36f11bafb4e124f1258
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Release History: opentelemetry-api
2
2
 
3
+ ### v0.17.0 / 2021-04-22
4
+
5
+ * BREAKING CHANGE: Replace TextMapInjector/TextMapExtractor pairs with a TextMapPropagator.
6
+
7
+ [Check the propagator documentation](https://open-telemetry.github.io/opentelemetry-ruby/) for the new usage.
8
+ * BREAKING CHANGE: Remove metrics API.
9
+
10
+ `OpenTelemetry::Metrics` and all of its behavior removed until spec stabilizes.
11
+ * BREAKING CHANGE: Extract instrumentation base from api (#698).
12
+
13
+ To take advantage of a base instrumentation class to create your own auto-instrumentation, require and use the `opentelemetry-instrumentation-base` gem.
14
+
15
+ * ADDED: Default noop tracer for instrumentation
16
+ * FIXED: Refactor propagators to add #fields
17
+ * FIXED: Remove metrics API
18
+ * FIXED: Dynamically upgrade global tracer provider
19
+
3
20
  ### v0.16.0 / 2021-03-17
4
21
 
5
22
  * ADDED: Span#add_attributes
data/lib/opentelemetry.rb CHANGED
@@ -9,9 +9,8 @@ require 'logger'
9
9
  require 'opentelemetry/error'
10
10
  require 'opentelemetry/context'
11
11
  require 'opentelemetry/baggage'
12
- require_relative './opentelemetry/instrumentation'
13
- require 'opentelemetry/metrics'
14
12
  require 'opentelemetry/trace'
13
+ require 'opentelemetry/internal'
15
14
  require 'opentelemetry/version'
16
15
 
17
16
  # OpenTelemetry is an open source observability framework, providing a
@@ -22,8 +21,10 @@ require 'opentelemetry/version'
22
21
  module OpenTelemetry
23
22
  extend self
24
23
 
25
- attr_writer :tracer_provider, :meter_provider, :propagation, :baggage,
26
- :logger, :error_handler
24
+ @mutex = Mutex.new
25
+ @tracer_provider = Internal::ProxyTracerProvider.new
26
+
27
+ attr_writer :propagation, :baggage, :logger, :error_handler
27
28
 
28
29
  # @return [Object, Logger] configured Logger or a default STDOUT Logger.
29
30
  def logger
@@ -44,36 +45,35 @@ module OpenTelemetry
44
45
  error_handler.call(exception: exception, message: message)
45
46
  end
46
47
 
48
+ # Register the global tracer provider.
49
+ #
50
+ # @param [TracerProvider] provider A tracer provider to register as the
51
+ # global instance.
52
+ def tracer_provider=(provider)
53
+ @mutex.synchronize do
54
+ if @tracer_provider.instance_of? Internal::ProxyTracerProvider
55
+ logger.debug("Upgrading default proxy tracer provider to #{provider.class}")
56
+ @tracer_provider.delegate = provider
57
+ end
58
+ @tracer_provider = provider
59
+ end
60
+ end
61
+
47
62
  # @return [Object, Trace::TracerProvider] registered tracer provider or a
48
63
  # default no-op implementation of the tracer provider.
49
64
  def tracer_provider
50
- @tracer_provider ||= Trace::TracerProvider.new
51
- end
52
-
53
- # @return [Object, Metrics::MeterProvider] registered meter provider or a
54
- # default no-op implementation of the meter provider.
55
- def meter_provider
56
- @meter_provider ||= Metrics::MeterProvider.new
57
- end
58
-
59
- # @return [Instrumentation::Registry] registry containing all known
60
- # instrumentation
61
- def instrumentation_registry
62
- @instrumentation_registry ||= Instrumentation::Registry.new
65
+ @mutex.synchronize { @tracer_provider }
63
66
  end
64
67
 
65
- # @return [Object, Baggage::Manager] registered
68
+ # @return [Object, Baggage::NoopManager] registered
66
69
  # baggage manager or a default no-op implementation of the
67
70
  # manager.
68
71
  def baggage
69
- @baggage ||= Baggage::Manager.new
72
+ @baggage ||= Baggage::NoopManager.new
70
73
  end
71
74
 
72
75
  # @return [Context::Propagation::Propagator] a propagator instance
73
76
  def propagation
74
- @propagation ||= Context::Propagation::Propagator.new(
75
- Context::Propagation::NoopInjector.new,
76
- Context::Propagation::NoopExtractor.new
77
- )
77
+ @propagation ||= Context::Propagation::NoopTextMapPropagator.new
78
78
  end
79
79
  end
@@ -4,9 +4,12 @@
4
4
  #
5
5
  # SPDX-License-Identifier: Apache-2.0
6
6
 
7
+ require 'opentelemetry/baggage/propagation'
7
8
  require 'opentelemetry/baggage/builder'
9
+ require 'opentelemetry/baggage/entry'
8
10
  require 'opentelemetry/baggage/manager'
9
- require 'opentelemetry/baggage/propagation'
11
+ require 'opentelemetry/baggage/noop_builder'
12
+ require 'opentelemetry/baggage/noop_manager'
10
13
 
11
14
  module OpenTelemetry
12
15
  # The Baggage module provides functionality to record and propagate
@@ -6,13 +6,39 @@
6
6
 
7
7
  module OpenTelemetry
8
8
  module Baggage
9
- # No op implementation of Baggage::Builder
9
+ # Operational implementation of Baggage::Builder
10
10
  class Builder
11
- def set_value(key, value); end
11
+ # @api private
12
+ attr_reader :entries
12
13
 
13
- def remove_value(key); end
14
+ # @api private
15
+ def initialize(entries)
16
+ @entries = entries
17
+ end
14
18
 
15
- def clear; end
19
+ # Set key-value in the to-be-created baggage
20
+ #
21
+ # @param [String] key The key to store this value under
22
+ # @param [String] value String value to be stored under key
23
+ # @param [optional String] metadata This is here to store properties
24
+ # received from other W3C Baggage impelmentations but is not exposed in
25
+ # OpenTelemetry. This is condsidered private API and not for use by
26
+ # end-users.
27
+ def set_value(key, value, metadata: nil)
28
+ @entries[key] = OpenTelemetry::Baggage::Entry.new(value, metadata)
29
+ end
30
+
31
+ # Removes key from the to-be-created baggage
32
+ #
33
+ # @param [String] key The key to remove
34
+ def remove_value(key)
35
+ @entries.delete(key)
36
+ end
37
+
38
+ # Clears all baggage from the to-be-created baggage
39
+ def clear
40
+ @entries.clear
41
+ end
16
42
  end
17
43
  end
18
44
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright The OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
7
+ module OpenTelemetry
8
+ # OpenTelemetry Baggage Implementation
9
+ module Baggage
10
+ # Read-only representation of a baggage entry
11
+ class Entry
12
+ attr_reader :value, :metadata
13
+
14
+ def initialize(value, metadata = nil)
15
+ @value = value
16
+ @metadata = metadata
17
+ end
18
+ end
19
+ end
20
+ end
@@ -6,35 +6,98 @@
6
6
 
7
7
  module OpenTelemetry
8
8
  module Baggage
9
- # No op implementation of Baggage::Manager
9
+ # Operational Baggage Manager implementation
10
10
  class Manager
11
- NOOP_BUILDER = Builder.new
12
- EMPTY_VALUES = {}.freeze
13
- private_constant(:NOOP_BUILDER, :EMPTY_VALUES)
11
+ BAGGAGE_KEY = OpenTelemetry::Baggage::Propagation::ContextKeys.baggage_key
12
+ EMPTY_BAGGAGE = {}.freeze
13
+ private_constant(:BAGGAGE_KEY, :EMPTY_BAGGAGE)
14
14
 
15
+ # Used to chain modifications to baggage. The result is a
16
+ # context with an updated baggage. If only a single
17
+ # modification is being made to baggage, use the other
18
+ # methods on +Manager+, if multiple modifications are being made, use
19
+ # this one.
20
+ #
21
+ # @param [optional Context] context The context to update with with new
22
+ # modified baggage. Defaults to +Context.current+
23
+ # @return [Context]
15
24
  def build(context: Context.current)
16
- yield NOOP_BUILDER
17
- context
25
+ builder = Builder.new(baggage_for(context).dup)
26
+ yield builder
27
+ context.set_value(BAGGAGE_KEY, builder.entries)
18
28
  end
19
29
 
20
- def set_value(key, value, context: Context.current)
21
- context
30
+ # Returns a new context with empty baggage
31
+ #
32
+ # @param [optional Context] context Context to clear baggage from. Defaults
33
+ # to +Context.current+
34
+ # @return [Context]
35
+ def clear(context: Context.current)
36
+ context.set_value(BAGGAGE_KEY, EMPTY_BAGGAGE)
22
37
  end
23
38
 
39
+ # Returns the corresponding baggage.entry (or nil) for key
40
+ #
41
+ # @param [String] key The lookup key
42
+ # @param [optional Context] context The context from which to retrieve
43
+ # the key.
44
+ # Defaults to +Context.current+
45
+ # @return [String]
24
46
  def value(key, context: Context.current)
25
- nil
47
+ baggage_for(context)[key]&.value
26
48
  end
27
49
 
50
+ # Returns the baggage
51
+ #
52
+ # @param [optional Context] context The context from which to retrieve
53
+ # the baggage.
54
+ # Defaults to +Context.current+
55
+ # @return [Hash]
28
56
  def values(context: Context.current)
29
- EMPTY_VALUES
57
+ baggage_for(context).transform_values(&:value)
58
+ end
59
+
60
+ # @api private
61
+ def raw_entries(context: Context.current)
62
+ baggage_for(context).dup.freeze
63
+ end
64
+
65
+ # Returns a new context with new key-value pair
66
+ #
67
+ # @param [String] key The key to store this value under
68
+ # @param [String] value String value to be stored under key
69
+ # @param [optional String] metadata This is here to store properties
70
+ # received from other W3C Baggage impelmentations but is not exposed in
71
+ # OpenTelemetry. This is condsidered private API and not for use by
72
+ # end-users.
73
+ # @param [optional Context] context The context to update with new
74
+ # value. Defaults to +Context.current+
75
+ # @return [Context]
76
+ def set_value(key, value, metadata: nil, context: Context.current)
77
+ new_baggage = baggage_for(context).dup
78
+ new_baggage[key] = Entry.new(value, metadata)
79
+ context.set_value(BAGGAGE_KEY, new_baggage)
30
80
  end
31
81
 
82
+ # Returns a new context with value at key removed
83
+ #
84
+ # @param [String] key The key to remove
85
+ # @param [optional Context] context The context to remove baggage
86
+ # from. Defaults to +Context.current+
87
+ # @return [Context]
32
88
  def remove_value(key, context: Context.current)
33
- context
89
+ baggage = baggage_for(context)
90
+ return context unless baggage.key?(key)
91
+
92
+ new_baggage = baggage.dup
93
+ new_baggage.delete(key)
94
+ context.set_value(BAGGAGE_KEY, new_baggage)
34
95
  end
35
96
 
36
- def clear(context: Context.current)
37
- context
97
+ private
98
+
99
+ def baggage_for(context)
100
+ context.value(BAGGAGE_KEY) || EMPTY_BAGGAGE
38
101
  end
39
102
  end
40
103
  end
@@ -0,0 +1,18 @@
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 Baggage
9
+ # No op implementation of Baggage::Builder
10
+ class NoopBuilder
11
+ def set_value(key, value, metadata: nil); end
12
+
13
+ def remove_value(key); end
14
+
15
+ def clear; end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,45 @@
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 Baggage
9
+ # No op implementation of Baggage::Manager
10
+ class NoopManager
11
+ NOOP_BUILDER = NoopBuilder.new
12
+ EMPTY_HASH = {}.freeze
13
+ private_constant(:NOOP_BUILDER, :EMPTY_HASH)
14
+
15
+ def build(context: Context.current)
16
+ yield NOOP_BUILDER
17
+ context
18
+ end
19
+
20
+ def set_value(key, value, metadata: nil, context: Context.current)
21
+ context
22
+ end
23
+
24
+ def value(key, context: Context.current)
25
+ nil
26
+ end
27
+
28
+ def values(context: Context.current)
29
+ EMPTY_HASH
30
+ end
31
+
32
+ def raw_entries(context: Context.current)
33
+ EMPTY_HASH
34
+ end
35
+
36
+ def remove_value(key, context: Context.current)
37
+ context
38
+ end
39
+
40
+ def clear(context: Context.current)
41
+ context
42
+ end
43
+ end
44
+ end
45
+ end
@@ -5,32 +5,23 @@
5
5
  # SPDX-License-Identifier: Apache-2.0
6
6
 
7
7
  require 'opentelemetry/baggage/propagation/context_keys'
8
- require 'opentelemetry/baggage/propagation/text_map_injector'
9
- require 'opentelemetry/baggage/propagation/text_map_extractor'
8
+ require 'opentelemetry/baggage/propagation/text_map_propagator'
10
9
 
11
10
  module OpenTelemetry
12
11
  module Baggage
13
- # The Baggage::Propagation module contains injectors and
14
- # extractors for sending and receiving baggage over the wire
12
+ # The Baggage::Propagation module contains a text map propagator for
13
+ # sending and receiving baggage over the wire.
15
14
  module Propagation
16
15
  extend self
17
16
 
18
- BAGGAGE_KEY = 'baggage'
19
- TEXT_MAP_EXTRACTOR = TextMapExtractor.new
20
- TEXT_MAP_INJECTOR = TextMapInjector.new
17
+ TEXT_MAP_PROPAGATOR = TextMapPropagator.new
21
18
 
22
- private_constant :BAGGAGE_KEY, :TEXT_MAP_INJECTOR, :TEXT_MAP_EXTRACTOR
19
+ private_constant :TEXT_MAP_PROPAGATOR
23
20
 
24
- # Returns an extractor that extracts context using the W3C Baggage
25
- # format
26
- def text_map_injector
27
- TEXT_MAP_INJECTOR
28
- end
29
-
30
- # Returns an injector that injects context using the W3C Baggage
31
- # format
32
- def text_map_extractor
33
- TEXT_MAP_EXTRACTOR
21
+ # Returns a text map propagator that propagates context using the
22
+ # W3C Baggage format.
23
+ def text_map_propagator
24
+ TEXT_MAP_PROPAGATOR
34
25
  end
35
26
  end
36
27
  end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright The OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
7
+ require 'cgi'
8
+
9
+ module OpenTelemetry
10
+ module Baggage
11
+ module Propagation
12
+ # Propagates baggage using the W3C Baggage format
13
+ class TextMapPropagator
14
+ # Maximums according to W3C Baggage spec
15
+ MAX_ENTRIES = 180
16
+ MAX_ENTRY_LENGTH = 4096
17
+ MAX_TOTAL_LENGTH = 8192
18
+
19
+ BAGGAGE_KEY = 'baggage'
20
+ FIELDS = [BAGGAGE_KEY].freeze
21
+
22
+ private_constant :BAGGAGE_KEY, :FIELDS, :MAX_ENTRIES, :MAX_ENTRY_LENGTH, :MAX_TOTAL_LENGTH
23
+
24
+ # Inject in-process baggage into the supplied carrier.
25
+ #
26
+ # @param [Carrier] carrier The mutable carrier to inject baggage into
27
+ # @param [Context] context The context to read baggage from
28
+ # @param [optional Setter] setter If the optional setter is provided, it
29
+ # will be used to write context into the carrier, otherwise the default
30
+ # text map setter will be used.
31
+ def inject(carrier, context: Context.current, setter: Context::Propagation.text_map_setter)
32
+ baggage = OpenTelemetry.baggage.raw_entries(context: context)
33
+
34
+ return if baggage.nil? || baggage.empty?
35
+
36
+ encoded_baggage = encode(baggage)
37
+ setter.set(carrier, BAGGAGE_KEY, encoded_baggage) unless encoded_baggage&.empty?
38
+ nil
39
+ end
40
+
41
+ # Extract remote baggage from the supplied carrier.
42
+ # If extraction fails, the original context will be returned
43
+ #
44
+ # @param [Carrier] carrier The carrier to get the header from
45
+ # @param [optional Context] context Context to be updated with the baggage
46
+ # extracted from the carrier. Defaults to +Context.current+.
47
+ # @param [optional Getter] getter If the optional getter is provided, it
48
+ # will be used to read the header from the carrier, otherwise the default
49
+ # text map getter will be used.
50
+ #
51
+ # @return [Context] context updated with extracted baggage, or the original context
52
+ # if extraction fails
53
+ def extract(carrier, context: Context.current, getter: Context::Propagation.text_map_getter)
54
+ header = getter.get(carrier, BAGGAGE_KEY)
55
+
56
+ entries = header.gsub(/\s/, '').split(',')
57
+
58
+ OpenTelemetry.baggage.build(context: context) do |builder|
59
+ entries.each do |entry|
60
+ # Note metadata is currently unused in OpenTelemetry, but is part
61
+ # the W3C spec where it's referred to as properties. We preserve
62
+ # the properties (as-is) so that they can be propagated elsewhere.
63
+ kv, meta = entry.split(';', 2)
64
+ k, v = kv.split('=').map!(&CGI.method(:unescape))
65
+ builder.set_value(k, v, metadata: meta)
66
+ end
67
+ end
68
+ rescue StandardError => e
69
+ OpenTelemetry.logger.debug "Error extracting W3C baggage: #{e.message}"
70
+ context
71
+ end
72
+
73
+ # Returns the predefined propagation fields. If your carrier is reused, you
74
+ # should delete the fields returned by this method before calling +inject+.
75
+ #
76
+ # @return [Array<String>] a list of fields that will be used by this propagator.
77
+ def fields
78
+ FIELDS
79
+ end
80
+
81
+ private
82
+
83
+ def encode(baggage)
84
+ result = +''
85
+ encoded_count = 0
86
+ baggage.each_pair do |key, entry|
87
+ break unless encoded_count < MAX_ENTRIES
88
+
89
+ encoded_entry = encode_value(key, entry)
90
+ next unless encoded_entry.size <= MAX_ENTRY_LENGTH &&
91
+ encoded_entry.size + result.size <= MAX_TOTAL_LENGTH
92
+
93
+ result << encoded_entry << ','
94
+ encoded_count += 1
95
+ end
96
+ result.chop!
97
+ end
98
+
99
+ def encode_value(key, entry)
100
+ result = +"#{CGI.escape(key.to_s)}=#{CGI.escape(entry.value.to_s)}"
101
+ # We preserve metadata recieved on extract and assume it's already formatted
102
+ # for transport. It's sent as-is without further processing.
103
+ result << ";#{entry.metadata}" if entry.metadata
104
+ result
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end