opentelemetry-api 0.14.0 → 1.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
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