opentelemetry-api 0.12.1 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +39 -0
  3. data/README.md +4 -4
  4. data/lib/opentelemetry.rb +24 -20
  5. data/lib/opentelemetry/baggage.rb +4 -1
  6. data/lib/opentelemetry/baggage/builder.rb +30 -4
  7. data/lib/opentelemetry/baggage/entry.rb +20 -0
  8. data/lib/opentelemetry/baggage/manager.rb +76 -13
  9. data/lib/opentelemetry/baggage/noop_builder.rb +18 -0
  10. data/lib/opentelemetry/baggage/noop_manager.rb +45 -0
  11. data/lib/opentelemetry/baggage/propagation.rb +9 -38
  12. data/lib/opentelemetry/baggage/propagation/text_map_propagator.rb +109 -0
  13. data/lib/opentelemetry/context/propagation.rb +62 -7
  14. data/lib/opentelemetry/context/propagation/composite_text_map_propagator.rb +105 -0
  15. data/lib/opentelemetry/context/propagation/noop_text_map_propagator.rb +51 -0
  16. data/lib/opentelemetry/context/propagation/rack_env_getter.rb +48 -0
  17. data/lib/opentelemetry/context/propagation/text_map_getter.rb +27 -0
  18. data/lib/opentelemetry/context/propagation/text_map_propagator.rb +71 -0
  19. data/lib/opentelemetry/context/propagation/text_map_setter.rb +21 -0
  20. data/lib/opentelemetry/internal.rb +17 -0
  21. data/lib/opentelemetry/internal/proxy_tracer.rb +38 -0
  22. data/lib/opentelemetry/internal/proxy_tracer_provider.rb +59 -0
  23. data/lib/opentelemetry/trace/propagation/trace_context.rb +7 -37
  24. data/lib/opentelemetry/trace/propagation/trace_context/text_map_propagator.rb +73 -0
  25. data/lib/opentelemetry/trace/span.rb +25 -1
  26. data/lib/opentelemetry/version.rb +1 -1
  27. metadata +20 -25
  28. data/lib/opentelemetry/baggage/propagation/text_map_extractor.rb +0 -60
  29. data/lib/opentelemetry/baggage/propagation/text_map_injector.rb +0 -55
  30. data/lib/opentelemetry/context/propagation/composite_propagator.rb +0 -73
  31. data/lib/opentelemetry/context/propagation/default_getter.rb +0 -26
  32. data/lib/opentelemetry/context/propagation/default_setter.rb +0 -26
  33. data/lib/opentelemetry/context/propagation/noop_extractor.rb +0 -26
  34. data/lib/opentelemetry/context/propagation/noop_injector.rb +0 -26
  35. data/lib/opentelemetry/context/propagation/propagation.rb +0 -27
  36. data/lib/opentelemetry/context/propagation/propagator.rb +0 -64
  37. data/lib/opentelemetry/instrumentation.rb +0 -15
  38. data/lib/opentelemetry/instrumentation/base.rb +0 -245
  39. data/lib/opentelemetry/instrumentation/registry.rb +0 -86
  40. data/lib/opentelemetry/metrics.rb +0 -16
  41. data/lib/opentelemetry/metrics/handles.rb +0 -44
  42. data/lib/opentelemetry/metrics/instruments.rb +0 -105
  43. data/lib/opentelemetry/metrics/meter.rb +0 -72
  44. data/lib/opentelemetry/metrics/meter_provider.rb +0 -22
  45. data/lib/opentelemetry/trace/propagation/trace_context/text_map_extractor.rb +0 -57
  46. data/lib/opentelemetry/trace/propagation/trace_context/text_map_injector.rb +0 -54
@@ -1,55 +0,0 @@
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
- # Injects baggage using the W3C Baggage format
13
- class TextMapInjector
14
- include Context::Propagation::DefaultSetter
15
-
16
- # Returns a new TextMapInjector that injects context using the specified
17
- # header key
18
- #
19
- # @param [String] baggage_key The baggage header
20
- # key used in the carrier
21
- # @return [TextMapInjector]
22
- def initialize(baggage_key: 'baggage')
23
- @baggage_key = baggage_key
24
- end
25
-
26
- # Inject in-process baggage into the supplied carrier.
27
- #
28
- # @param [Carrier] carrier The carrier to inject baggage into
29
- # @param [Context] context The context to read baggage from
30
- # @param [optional Callable] getter An optional callable that takes a carrier and a key and
31
- # returns the value associated with the key. If omitted the default getter will be used
32
- # which expects the carrier to respond to [] and []=.
33
- # @yield [Carrier, String] if an optional getter is provided, inject will yield the carrier
34
- # and the header key to the getter.
35
- # @return [Object] carrier with injected baggage
36
- def inject(carrier, context, &setter)
37
- return carrier unless (baggage = context[ContextKeys.baggage_key]) && !baggage.empty?
38
-
39
- setter ||= default_setter
40
- setter.call(carrier, @baggage_key, encode(baggage))
41
-
42
- carrier
43
- end
44
-
45
- private
46
-
47
- def encode(baggage)
48
- baggage.inject(+'') do |memo, (k, v)|
49
- memo << CGI.escape(k.to_s) << '=' << CGI.escape(v.to_s) << ','
50
- end.chop!
51
- end
52
- end
53
- end
54
- end
55
- end
@@ -1,73 +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
- class Context
9
- module Propagation
10
- # A composite propagator composes a list of injectors and extractors into
11
- # single interface exposing inject and extract methods. Injection and
12
- # extraction will preserve the order of the injectors and extractors
13
- # passed in during initialization.
14
- class CompositePropagator
15
- # Returns a Propagator that extracts using the provided extractors
16
- # and injectors.
17
- #
18
- # @param [Array<#inject>] injectors
19
- # @param [Array<#extract>] extractors
20
- def initialize(injectors, extractors)
21
- @injectors = injectors
22
- @extractors = extractors
23
- end
24
-
25
- # Runs injectors in order and returns a carrier. If an injection fails
26
- # a warning will be logged and remaining injectors will be executed.
27
- # Always returns a valid carrier.
28
- #
29
- # @param [Object] carrier A carrier to inject context into
30
- # context into
31
- # @param [optional Context] context Context to be injected into carrier.
32
- # Defaults to +Context.current+
33
- # @param [optional Callable] setter An optional callable that takes a
34
- # carrier, a key and a value and assigns the key-value pair in the
35
- # carrier. If omitted the default setter will be used which expects
36
- # the carrier to respond to [] and []=.
37
- #
38
- # @return [Object] carrier
39
- def inject(carrier, context = Context.current, &setter)
40
- @injectors.inject(carrier) do |memo, injector|
41
- injector.inject(memo, context, &setter)
42
- rescue => e # rubocop:disable Style/RescueStandardError
43
- OpenTelemetry.logger.warn "Error in CompositePropagator#inject #{e.message}"
44
- carrier
45
- end
46
- end
47
-
48
- # Runs extractors in order and returns a Context updated with the
49
- # results of each extraction. If an extraction fails, a warning will be
50
- # logged and remaining extractors will continue to be executed. Always
51
- # returns a valid context.
52
- #
53
- # @param [Object] carrier The carrier to extract context from
54
- # @param [optional Context] context Context to be updated with the state
55
- # extracted from the carrier. Defaults to +Context.current+
56
- # @param [optional Callable] getter An optional callable that takes a carrier and a key and
57
- # returns the value associated with the key. If omitted the default getter will be used
58
- # which expects the carrier to respond to [] and []=.
59
- #
60
- # @return [Context] a new context updated with state extracted from the
61
- # carrier
62
- def extract(carrier, context = Context.current, &getter)
63
- @extractors.inject(context) do |ctx, extractor|
64
- extractor.extract(carrier, ctx, &getter)
65
- rescue => e # rubocop:disable Style/RescueStandardError
66
- OpenTelemetry.logger.warn "Error in CompositePropagator#extract #{e.message}"
67
- ctx
68
- end
69
- end
70
- end
71
- end
72
- end
73
- end
@@ -1,26 +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
- class Context
9
- module Propagation
10
- # The default getter module provides a common method for reading
11
- # a key from a carrier that implements +[]+
12
- module DefaultGetter
13
- DEFAULT_GETTER = ->(carrier, key) { carrier[key] }
14
- private_constant :DEFAULT_GETTER
15
-
16
- # Returns a callable that can read a key from a carrier that implements
17
- # +[]+. Useful for extract operations.
18
- #
19
- # @return [Callable]
20
- def default_getter
21
- DEFAULT_GETTER
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,26 +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
- class Context
9
- module Propagation
10
- # The default setter module provides a common method for writing
11
- # a key into a carrier that implements +[]=+
12
- module DefaultSetter
13
- DEFAULT_SETTER = ->(carrier, key, value) { carrier[key] = value }
14
- private_constant :DEFAULT_SETTER
15
-
16
- # Returns a callable that can write a key into a carrier that implements
17
- # +[]=+. Useful for inject operations.
18
- #
19
- # @return [Callable]
20
- def default_setter
21
- DEFAULT_SETTER
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,26 +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
- class Context
9
- module Propagation
10
- # A no-op extractor implementation
11
- class NoopExtractor
12
- # Extract a context from the given carrier
13
- #
14
- # @param [Object] carrier The carrier to extract the context from
15
- # @param [Context] context The context to be upated with the extracted
16
- # context
17
- # @param [optional Callable] getter An optional callable that takes a carrier and a key and
18
- # and returns the value associated with the key
19
- # @return [Context]
20
- def extract(carrier, context, &getter)
21
- context
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,26 +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
- class Context
9
- module Propagation
10
- # A no-op injector implementation
11
- class NoopInjector
12
- # Inject the given context into the specified carrier
13
- #
14
- # @param [Object] carrier The carrier to inject the provided context
15
- # into
16
- # @param [Context] context The context to be injected
17
- # @param [optional Callable] setter An optional callable that takes a carrier and a key and
18
- # a value and assigns the key-value pair in the carrier
19
- # @return [Object] carrier
20
- def inject(carrier, context, &setter)
21
- carrier
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,27 +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
- class Context
9
- module Propagation
10
- # The Propagation class provides methods to inject and extract context
11
- # to pass across process boundaries
12
- class Propagation
13
- # Get or set the global http propagator. Use a CompositePropagator
14
- # to propagate multiple formats.
15
- attr_accessor :http
16
-
17
- # Get or set the global text propagator. Use a CompositePropagator
18
- # to propagate multiple formats.
19
- attr_accessor :text
20
-
21
- def initialize
22
- @http = @text = Propagator.new(NoopInjector.new, NoopExtractor.new)
23
- end
24
- end
25
- end
26
- end
27
- end
@@ -1,64 +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
- class Context
9
- module Propagation
10
- # A propagator composes an extractor and injector into a single interface
11
- # exposing inject and extract methods
12
- class Propagator
13
- # Returns a Propagator that delegates inject and extract to the provided
14
- # injector and extractor
15
- #
16
- # @param [#inject] injector
17
- # @param [#extract] extractor
18
- def initialize(injector, extractor)
19
- @injector = injector
20
- @extractor = extractor
21
- end
22
-
23
- # Returns a carrier with the provided context injected according the
24
- # underlying injector. Returns the carrier and logs a warning if
25
- # injection fails.
26
- #
27
- # @param [Object] carrier A carrier to inject context into
28
- # context into
29
- # @param [optional Context] context Context to be injected into carrier. Defaults
30
- # to +Context.current+
31
- # @param [optional Callable] setter An optional callable that takes a carrier, a key and
32
- # a value and assigns the key-value pair in the carrier. If omitted the default setter
33
- # will be used which expects the carrier to respond to [] and []=.
34
- #
35
- # @return [Object] carrier
36
- def inject(carrier, context = Context.current, &setter)
37
- @injector.inject(carrier, context, &setter)
38
- rescue => e # rubocop:disable Style/RescueStandardError
39
- OpenTelemetry.logger.warn "Error in Propagator#inject #{e.message}"
40
- carrier
41
- end
42
-
43
- # Extracts and returns context from a carrier. Returns the provided
44
- # context and logs a warning if an error if extraction fails.
45
- #
46
- # @param [Object] carrier The carrier to extract context from
47
- # @param [optional Context] context Context to be updated with the state
48
- # extracted from the carrier. Defaults to +Context.current+
49
- # @param [optional Callable] getter An optional callable that takes a carrier and a key and
50
- # returns the value associated with the key. If omitted the default getter will be used
51
- # which expects the carrier to respond to [] and []=.
52
- #
53
- # @return [Context] a new context updated with state extracted from the
54
- # carrier
55
- def extract(carrier, context = Context.current, &getter)
56
- @extractor.extract(carrier, context, &getter)
57
- rescue => e # rubocop:disable Style/RescueStandardError
58
- OpenTelemetry.logger.warn "Error in Propagator#extract #{e.message}"
59
- context
60
- end
61
- end
62
- end
63
- end
64
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Copyright The OpenTelemetry Authors
4
- #
5
- # SPDX-License-Identifier: Apache-2.0
6
-
7
- require 'opentelemetry/instrumentation/registry'
8
- require 'opentelemetry/instrumentation/base'
9
-
10
- module OpenTelemetry
11
- # The instrumentation module contains functionality to register and install
12
- # instrumentation
13
- module Instrumentation
14
- end
15
- end
@@ -1,245 +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 Instrumentation
9
- # The Base class holds all metadata and configuration for an
10
- # instrumentation. All instrumentation packages should
11
- # include a subclass of +Instrumentation::Base+ that will register
12
- # it with +OpenTelemetry.instrumentation_registry+ and make it available for
13
- # discovery and installation by an SDK.
14
- #
15
- # A typical subclass of Base will provide an install block, a present
16
- # block, and possibly a compatible block. Below is an
17
- # example:
18
- #
19
- # module OpenTelemetry
20
- # module Instrumentation
21
- # module Sinatra
22
- # class Instrumentation < OpenTelemetry::Instrumentation::Base
23
- # install do |config|
24
- # # install instrumentation, either by library hook or applying
25
- # # a monkey patch
26
- # end
27
- #
28
- # # determine if the target library is present
29
- # present do
30
- # defined?(::Sinatra)
31
- # end
32
- #
33
- # # if the target library is present, is it compatible?
34
- # compatible do
35
- # Gem.loaded_specs['sinatra'].version > MIN_VERSION
36
- # end
37
- # end
38
- # end
39
- # end
40
- # end
41
- #
42
- # The instrumentation name and version will be inferred from the namespace of the
43
- # class. In this example, they'd be 'OpenTelemetry::Instrumentation::Sinatra' and
44
- # OpenTelemetry::Instrumentation::Sinatra::VERSION, but can be explicitly set using
45
- # the +instrumentation_name+ and +instrumetation_version+ methods if necessary.
46
- #
47
- # All subclasses of OpenTelemetry::Instrumentation::Base are automatically
48
- # registered with OpenTelemetry.instrumentation_registry which is used by
49
- # SDKs for instrumentation discovery and installation.
50
- #
51
- # Instrumentation libraries can use the instrumentation subclass to easily gain
52
- # a reference to its named tracer. For example:
53
- #
54
- # OpenTelemetry::Instrumentation::Sinatra.instance.tracer
55
- #
56
- # The instrumention class establishes a convention for disabling an instrumentation
57
- # by environment variable and local configuration. An instrumentation disabled
58
- # by environment variable will take precedence over local config. The
59
- # convention for environment variable name is the library name, upcased with
60
- # '::' replaced by underscores, OPENTELEMETRY shortened to OTEL_{LANG}, and '_ENABLED' appended.
61
- # For example: OTEL_RUBY_INSTRUMENTATION_SINATRA_ENABLED = false.
62
- class Base
63
- class << self
64
- NAME_REGEX = /^(?:(?<namespace>[a-zA-Z0-9_:]+):{2})?(?<classname>[a-zA-Z0-9_]+)$/.freeze
65
- private_constant :NAME_REGEX
66
-
67
- private :new # rubocop:disable Style/AccessModifierDeclarations
68
-
69
- def inherited(subclass)
70
- OpenTelemetry.instrumentation_registry.register(subclass)
71
- end
72
-
73
- # Optionally set the name of this instrumentation. If not
74
- # explicitly set, the name will default to the namespace of the class,
75
- # or the class name if it does not have a namespace. If there is not
76
- # a namespace, or a class name, it will default to 'unknown'.
77
- #
78
- # @param [String] instrumentation_name The full name of the instrumentation package
79
- def instrumentation_name(instrumentation_name = nil)
80
- if instrumentation_name
81
- @instrumentation_name = instrumentation_name
82
- else
83
- @instrumentation_name ||= infer_name || 'unknown'
84
- end
85
- end
86
-
87
- # Optionally set the version of this instrumentation. If not explicitly set,
88
- # the version will default to the VERSION constant under namespace of
89
- # the class, or the VERSION constant under the class name if it does not
90
- # have a namespace. If a VERSION constant cannot be found, it defaults
91
- # to '0.0.0'.
92
- #
93
- # @param [String] instrumentation_version The version of the instrumentation package
94
- def instrumentation_version(instrumentation_version = nil)
95
- if instrumentation_version
96
- @instrumentation_version = instrumentation_version
97
- else
98
- @instrumentation_version ||= infer_version || '0.0.0'
99
- end
100
- end
101
-
102
- # The install block for this instrumentation. This will be where you install
103
- # instrumentation, either by framework hook or applying a monkey patch.
104
- #
105
- # @param [Callable] blk The install block for this instrumentation
106
- # @yieldparam [Hash] config The instrumentation config will be yielded to the
107
- # install block
108
- def install(&blk)
109
- @install_blk = blk
110
- end
111
-
112
- # The present block for this instrumentation. This block is used to detect if
113
- # target library is present on the system. Typically this will involve
114
- # checking to see if the target gem spec was loaded or if expected
115
- # constants from the target library are present.
116
- #
117
- # @param [Callable] blk The present block for this instrumentation
118
- def present(&blk)
119
- @present_blk = blk
120
- end
121
-
122
- # The compatible block for this instrumentation. This check will be run if the
123
- # target library is present to determine if it's compatible. It's not
124
- # required, but a common use case will be to check to target library
125
- # version for compatibility.
126
- #
127
- # @param [Callable] blk The compatibility block for this instrumentation
128
- def compatible(&blk)
129
- @compatible_blk = blk
130
- end
131
-
132
- def instance
133
- @instance ||= new(instrumentation_name, instrumentation_version, install_blk,
134
- present_blk, compatible_blk)
135
- end
136
-
137
- private
138
-
139
- attr_reader :install_blk, :present_blk, :compatible_blk
140
-
141
- def infer_name
142
- @inferred_name ||= if (md = name.match(NAME_REGEX)) # rubocop:disable Naming/MemoizedInstanceVariableName
143
- md['namespace'] || md['classname']
144
- end
145
- end
146
-
147
- def infer_version
148
- return unless (inferred_name = infer_name)
149
-
150
- mod = inferred_name.split('::').map(&:to_sym).inject(Object) do |object, const|
151
- object.const_get(const)
152
- end
153
- mod.const_get(:VERSION)
154
- rescue NameError
155
- nil
156
- end
157
- end
158
-
159
- attr_reader :name, :version, :config, :installed, :tracer
160
-
161
- alias installed? installed
162
-
163
- def initialize(name, version, install_blk, present_blk,
164
- compatible_blk)
165
- @name = name
166
- @version = version
167
- @install_blk = install_blk
168
- @present_blk = present_blk
169
- @compatible_blk = compatible_blk
170
- @config = {}
171
- @installed = false
172
- end
173
-
174
- # Install instrumentation with the given config. The present? and compatible?
175
- # will be run first, and install will return false if either fail. Will
176
- # return true if install was completed successfully.
177
- #
178
- # @param [Hash] config The config for this instrumentation
179
- def install(config = {})
180
- return true if installed?
181
- return false unless installable?(config)
182
-
183
- @config = config unless config.nil?
184
- instance_exec(@config, &@install_blk)
185
- @tracer ||= OpenTelemetry.tracer_provider.tracer(name, version)
186
- @installed = true
187
- end
188
-
189
- # Whether or not this instrumentation is installable in the current process. Will
190
- # be true when the instrumentation defines an install block, is not disabled
191
- # by environment or config, and the target library present and compatible.
192
- #
193
- # @param [Hash] config The config for this instrumentation
194
- def installable?(config = {})
195
- @install_blk && enabled?(config) && present? && compatible?
196
- end
197
-
198
- # Calls the present block of the Instrumentation subclasses, if no block is provided
199
- # it's assumed the instrumentation is not present
200
- def present?
201
- return false unless @present_blk
202
-
203
- instance_exec(&@present_blk)
204
- end
205
-
206
- # Calls the compatible block of the Instrumentation subclasses, if no block is provided
207
- # it's assumed to be compatible
208
- def compatible?
209
- return true unless @compatible_blk
210
-
211
- instance_exec(&@compatible_blk)
212
- end
213
-
214
- # Whether this instrumentation is enabled. It first checks to see if it's enabled
215
- # by an environment variable and will proceed to check if it's enabled
216
- # by local config, if given.
217
- #
218
- # @param [optional Hash] config The local config
219
- def enabled?(config = nil)
220
- return false unless enabled_by_env_var?
221
- return config[:enabled] if config&.key?(:enabled)
222
-
223
- true
224
- end
225
-
226
- private
227
-
228
- # Checks to see if this instrumentation is enabled by env var. By convention, the
229
- # environment variable will be the instrumentation name upper cased, with '::'
230
- # replaced by underscores, OPENTELEMETRY shortened to OTEL_{LANG} and _ENABLED appended.
231
- # For example, the, environment variable name for OpenTelemetry::Instrumentation::Sinatra
232
- # will be OTEL_RUBY_INSTRUMENTATION_SINATRA_ENABLED. A value of 'false' will disable
233
- # the instrumentation, all other values will enable it.
234
- def enabled_by_env_var?
235
- var_name = name.dup.tap do |n|
236
- n.upcase!
237
- n.gsub!('::', '_')
238
- n.gsub!('OPENTELEMETRY_', 'OTEL_RUBY_')
239
- n << '_ENABLED'
240
- end
241
- ENV[var_name] != 'false'
242
- end
243
- end
244
- end
245
- end