opentelemetry-api 0.14.0 → 1.0.0.rc2

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +51 -0
  3. data/README.md +2 -2
  4. data/lib/opentelemetry.rb +21 -28
  5. data/lib/opentelemetry/baggage.rb +95 -2
  6. data/lib/opentelemetry/baggage/builder.rb +30 -4
  7. data/lib/opentelemetry/baggage/entry.rb +20 -0
  8. data/lib/opentelemetry/baggage/propagation.rb +9 -18
  9. data/lib/opentelemetry/baggage/propagation/text_map_propagator.rb +110 -0
  10. data/lib/opentelemetry/context.rb +48 -33
  11. data/lib/opentelemetry/context/propagation.rb +35 -5
  12. data/lib/opentelemetry/context/propagation/composite_text_map_propagator.rb +105 -0
  13. data/lib/opentelemetry/context/propagation/noop_text_map_propagator.rb +51 -0
  14. data/lib/opentelemetry/context/propagation/rack_env_getter.rb +3 -1
  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.rb +10 -0
  20. data/lib/opentelemetry/trace/propagation/trace_context.rb +7 -18
  21. data/lib/opentelemetry/trace/propagation/trace_context/text_map_propagator.rb +73 -0
  22. data/lib/opentelemetry/trace/span.rb +20 -0
  23. data/lib/opentelemetry/trace/status.rb +34 -5
  24. data/lib/opentelemetry/trace/tracer.rb +8 -9
  25. data/lib/opentelemetry/version.rb +1 -1
  26. metadata +16 -25
  27. data/lib/opentelemetry/baggage/manager.rb +0 -41
  28. data/lib/opentelemetry/baggage/propagation/text_map_extractor.rb +0 -57
  29. data/lib/opentelemetry/baggage/propagation/text_map_injector.rb +0 -52
  30. data/lib/opentelemetry/context/propagation/composite_propagator.rb +0 -72
  31. data/lib/opentelemetry/context/propagation/noop_extractor.rb +0 -26
  32. data/lib/opentelemetry/context/propagation/noop_injector.rb +0 -26
  33. data/lib/opentelemetry/instrumentation.rb +0 -15
  34. data/lib/opentelemetry/instrumentation/base.rb +0 -245
  35. data/lib/opentelemetry/instrumentation/registry.rb +0 -86
  36. data/lib/opentelemetry/metrics.rb +0 -16
  37. data/lib/opentelemetry/metrics/handles.rb +0 -44
  38. data/lib/opentelemetry/metrics/instruments.rb +0 -105
  39. data/lib/opentelemetry/metrics/meter.rb +0 -72
  40. data/lib/opentelemetry/metrics/meter_provider.rb +0 -22
  41. data/lib/opentelemetry/trace/propagation/trace_context/text_map_extractor.rb +0 -52
  42. data/lib/opentelemetry/trace/propagation/trace_context/text_map_injector.rb +0 -49
  43. data/lib/opentelemetry/trace/util/http_to_status.rb +0 -28
@@ -1,41 +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 Baggage
9
- # No op implementation of Baggage::Manager
10
- class Manager
11
- NOOP_BUILDER = Builder.new
12
- EMPTY_VALUES = {}.freeze
13
- private_constant(:NOOP_BUILDER, :EMPTY_VALUES)
14
-
15
- def build(context: Context.current)
16
- yield NOOP_BUILDER
17
- context
18
- end
19
-
20
- def set_value(key, value, 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_VALUES
30
- end
31
-
32
- def remove_value(key, context: Context.current)
33
- context
34
- end
35
-
36
- def clear(context: Context.current)
37
- context
38
- end
39
- end
40
- end
41
- end
@@ -1,57 +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
- # Extracts baggage from carriers in the W3C Baggage format
13
- class TextMapExtractor
14
- # Returns a new TextMapExtractor that extracts context using the specified
15
- # getter
16
- #
17
- # @param [optional Getter] default_getter The default getter used to read
18
- # headers from a carrier during extract. Defaults to a
19
- # {OpenTelemetry::Context::Propagation::TextMapGetter} instance.
20
- # @return [TextMapExtractor]
21
- def initialize(default_getter = Context::Propagation.text_map_getter)
22
- @default_getter = default_getter
23
- end
24
-
25
- # Extract remote baggage from the supplied carrier.
26
- # If extraction fails, the original context will be returned
27
- #
28
- # @param [Carrier] carrier The carrier to get the header from
29
- # @param [Context] context The context to be updated with extracted baggage
30
- # @param [optional Getter] getter If the optional getter is provided, it
31
- # will be used to read the header from the carrier, otherwise the default
32
- # getter will be used.
33
- # @return [Context] context updated with extracted baggage, or the original context
34
- # if extraction fails
35
- def extract(carrier, context, getter = nil)
36
- getter ||= @default_getter
37
- header = getter.get(carrier, BAGGAGE_KEY)
38
-
39
- entries = header.gsub(/\s/, '').split(',')
40
-
41
- baggage = entries.each_with_object({}) do |entry, memo|
42
- # The ignored variable below holds properties as per the W3C spec.
43
- # OTel is not using them currently, but they might be used for
44
- # metadata in the future
45
- kv, = entry.split(';', 2)
46
- k, v = kv.split('=').map!(&CGI.method(:unescape))
47
- memo[k] = v
48
- end
49
-
50
- context.set_value(ContextKeys.baggage_key, baggage)
51
- rescue StandardError
52
- context
53
- end
54
- end
55
- end
56
- end
57
- end
@@ -1,52 +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
- # Returns a new TextMapInjector that injects context using the specified
15
- # setter
16
- #
17
- # @param [optional Setter] default_setter The default setter used to
18
- # write context into a carrier during inject. Defaults to a
19
- # {OpenTelemetry::Context::Propagation::TextMapSetter} instance.
20
- # @return [TextMapInjector]
21
- def initialize(default_setter = Context::Propagation.text_map_setter)
22
- @default_setter = default_setter
23
- end
24
-
25
- # Inject in-process baggage into the supplied carrier.
26
- #
27
- # @param [Carrier] carrier The carrier to inject baggage into
28
- # @param [Context] context The context to read baggage from
29
- # @param [optional Setter] setter If the optional setter is provided, it
30
- # will be used to write context into the carrier, otherwise the default
31
- # setter will be used.
32
- # @return [Object] carrier with injected baggage
33
- def inject(carrier, context, setter = nil)
34
- return carrier unless (baggage = context[ContextKeys.baggage_key]) && !baggage.empty?
35
-
36
- setter ||= @default_setter
37
- setter.set(carrier, BAGGAGE_KEY, encode(baggage))
38
-
39
- carrier
40
- end
41
-
42
- private
43
-
44
- def encode(baggage)
45
- baggage.inject(+'') do |memo, (k, v)|
46
- memo << CGI.escape(k.to_s) << '=' << CGI.escape(v.to_s) << ','
47
- end.chop!
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,72 +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 Setter] setter If the optional setter is provided, it
34
- # will be used to write context into the carrier, otherwise the default
35
- # setter will be used.
36
- #
37
- # @return [Object] carrier
38
- def inject(carrier, context: Context.current, setter: Context::Propagation.text_map_setter)
39
- @injectors.inject(carrier) do |memo, injector|
40
- injector.inject(memo, context, setter)
41
- rescue => e # rubocop:disable Style/RescueStandardError
42
- OpenTelemetry.logger.warn "Error in CompositePropagator#inject #{e.message}"
43
- carrier
44
- end
45
- end
46
-
47
- # Runs extractors in order and returns a Context updated with the
48
- # results of each extraction. If an extraction fails, a warning will be
49
- # logged and remaining extractors will continue to be executed. Always
50
- # returns a valid context.
51
- #
52
- # @param [Object] carrier The carrier to extract context from
53
- # @param [optional Context] context Context to be updated with the state
54
- # extracted from the carrier. Defaults to +Context.current+
55
- # @param [optional Getter] getter If the optional getter is provided, it
56
- # will be used to read the header from the carrier, otherwise the default
57
- # getter will be used.
58
- #
59
- # @return [Context] a new context updated with state extracted from the
60
- # carrier
61
- def extract(carrier, context: Context.current, getter: Context::Propagation.text_map_getter)
62
- @extractors.inject(context) do |ctx, extractor|
63
- extractor.extract(carrier, ctx, getter)
64
- rescue => e # rubocop:disable Style/RescueStandardError
65
- OpenTelemetry.logger.warn "Error in CompositePropagator#extract #{e.message}"
66
- ctx
67
- end
68
- end
69
- end
70
- end
71
- end
72
- 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 = nil)
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,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