opentelemetry-api 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +9 -0
- data/CHANGELOG.md +1 -0
- data/LICENSE +201 -0
- data/OVERVIEW.md +66 -0
- data/lib/opentelemetry-api.rb +7 -0
- data/lib/opentelemetry.rb +61 -0
- data/lib/opentelemetry/context.rb +154 -0
- data/lib/opentelemetry/context/key.rb +29 -0
- data/lib/opentelemetry/context/propagation.rb +22 -0
- data/lib/opentelemetry/context/propagation/composite_propagator.rb +73 -0
- data/lib/opentelemetry/context/propagation/default_getter.rb +26 -0
- data/lib/opentelemetry/context/propagation/default_setter.rb +26 -0
- data/lib/opentelemetry/context/propagation/noop_extractor.rb +26 -0
- data/lib/opentelemetry/context/propagation/noop_injector.rb +26 -0
- data/lib/opentelemetry/context/propagation/propagation.rb +27 -0
- data/lib/opentelemetry/context/propagation/propagator.rb +64 -0
- data/lib/opentelemetry/correlation_context.rb +16 -0
- data/lib/opentelemetry/correlation_context/builder.rb +18 -0
- data/lib/opentelemetry/correlation_context/manager.rb +36 -0
- data/lib/opentelemetry/correlation_context/propagation.rb +57 -0
- data/lib/opentelemetry/correlation_context/propagation/context_keys.rb +27 -0
- data/lib/opentelemetry/correlation_context/propagation/text_extractor.rb +60 -0
- data/lib/opentelemetry/correlation_context/propagation/text_injector.rb +55 -0
- data/lib/opentelemetry/error.rb +9 -0
- data/lib/opentelemetry/instrumentation.rb +15 -0
- data/lib/opentelemetry/instrumentation/base.rb +245 -0
- data/lib/opentelemetry/instrumentation/registry.rb +87 -0
- data/lib/opentelemetry/internal.rb +22 -0
- data/lib/opentelemetry/metrics.rb +16 -0
- data/lib/opentelemetry/metrics/handles.rb +44 -0
- data/lib/opentelemetry/metrics/instruments.rb +105 -0
- data/lib/opentelemetry/metrics/meter.rb +72 -0
- data/lib/opentelemetry/metrics/meter_provider.rb +22 -0
- data/lib/opentelemetry/trace.rb +51 -0
- data/lib/opentelemetry/trace/event.rb +46 -0
- data/lib/opentelemetry/trace/link.rb +46 -0
- data/lib/opentelemetry/trace/propagation.rb +17 -0
- data/lib/opentelemetry/trace/propagation/context_keys.rb +35 -0
- data/lib/opentelemetry/trace/propagation/trace_context.rb +59 -0
- data/lib/opentelemetry/trace/propagation/trace_context/text_extractor.rb +58 -0
- data/lib/opentelemetry/trace/propagation/trace_context/text_injector.rb +55 -0
- data/lib/opentelemetry/trace/propagation/trace_context/trace_parent.rb +130 -0
- data/lib/opentelemetry/trace/span.rb +145 -0
- data/lib/opentelemetry/trace/span_context.rb +56 -0
- data/lib/opentelemetry/trace/span_kind.rb +35 -0
- data/lib/opentelemetry/trace/status.rb +114 -0
- data/lib/opentelemetry/trace/trace_flags.rb +50 -0
- data/lib/opentelemetry/trace/tracer.rb +103 -0
- data/lib/opentelemetry/trace/tracer_provider.rb +22 -0
- data/lib/opentelemetry/trace/util/http_to_status.rb +47 -0
- data/lib/opentelemetry/version.rb +10 -0
- metadata +220 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
module OpenTelemetry
|
8
|
+
module CorrelationContext
|
9
|
+
module Propagation
|
10
|
+
# The ContextKeys module contains the keys used to index correlations
|
11
|
+
# in a {Context} instance
|
12
|
+
module ContextKeys
|
13
|
+
extend self
|
14
|
+
|
15
|
+
CORRELATION_CONTEXT_KEY = Context.create_key('correlation-context')
|
16
|
+
private_constant :CORRELATION_CONTEXT_KEY
|
17
|
+
|
18
|
+
# Returns the context key that correlations are indexed by
|
19
|
+
#
|
20
|
+
# @return [Context::Key]
|
21
|
+
def correlation_context_key
|
22
|
+
CORRELATION_CONTEXT_KEY
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
require 'cgi'
|
8
|
+
|
9
|
+
module OpenTelemetry
|
10
|
+
module CorrelationContext
|
11
|
+
module Propagation
|
12
|
+
# Extracts correlations from carriers in the W3C Correlation Context format
|
13
|
+
class TextExtractor
|
14
|
+
include Context::Propagation::DefaultGetter
|
15
|
+
|
16
|
+
# Returns a new TextExtractor that extracts context using the specified
|
17
|
+
# header key
|
18
|
+
#
|
19
|
+
# @param [String] correlation_context_key The correlation context header
|
20
|
+
# key used in the carrier
|
21
|
+
# @return [TextExtractor]
|
22
|
+
def initialize(correlation_context_key: 'otcorrelations')
|
23
|
+
@correlation_context_key = correlation_context_key
|
24
|
+
end
|
25
|
+
|
26
|
+
# Extract remote correlations from the supplied carrier.
|
27
|
+
# If extraction fails, the original context will be returned
|
28
|
+
#
|
29
|
+
# @param [Carrier] carrier The carrier to get the header from
|
30
|
+
# @param [Context] context The context to be updated with extracted correlations
|
31
|
+
# @param [optional Callable] getter An optional callable that takes a carrier and a key and
|
32
|
+
# returns the value associated with the key. If omitted the default getter will be used
|
33
|
+
# which expects the carrier to respond to [] and []=.
|
34
|
+
# @yield [Carrier, String] if an optional getter is provided, extract will yield the carrier
|
35
|
+
# and the header key to the getter.
|
36
|
+
# @return [Context] context updated with extracted correlations, or the original context
|
37
|
+
# if extraction fails
|
38
|
+
def extract(carrier, context, &getter)
|
39
|
+
getter ||= default_getter
|
40
|
+
header = getter.call(carrier, @correlation_context_key)
|
41
|
+
|
42
|
+
entries = header.gsub(/\s/, '').split(',')
|
43
|
+
|
44
|
+
correlations = entries.each_with_object({}) do |entry, memo|
|
45
|
+
# The ignored variable below holds properties as per the W3C spec.
|
46
|
+
# OTel is not using them currently, but they might be used for
|
47
|
+
# metadata in the future
|
48
|
+
kv, = entry.split(';', 2)
|
49
|
+
k, v = kv.split('=').map!(&CGI.method(:unescape))
|
50
|
+
memo[k] = v
|
51
|
+
end
|
52
|
+
|
53
|
+
context.set_value(ContextKeys.correlation_context_key, correlations)
|
54
|
+
rescue StandardError
|
55
|
+
context
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2019 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
require 'cgi'
|
8
|
+
|
9
|
+
module OpenTelemetry
|
10
|
+
module CorrelationContext
|
11
|
+
module Propagation
|
12
|
+
# Injects correlation context using the W3C Correlation Context format
|
13
|
+
class TextInjector
|
14
|
+
include Context::Propagation::DefaultSetter
|
15
|
+
|
16
|
+
# Returns a new TextInjector that injects context using the specified
|
17
|
+
# header key
|
18
|
+
#
|
19
|
+
# @param [String] correlation_context_header_key The correlation context header
|
20
|
+
# key used in the carrier
|
21
|
+
# @return [TextInjector]
|
22
|
+
def initialize(correlation_context_key: 'otcorrelations')
|
23
|
+
@correlation_context_key = correlation_context_key
|
24
|
+
end
|
25
|
+
|
26
|
+
# Inject in-process correlations into the supplied carrier.
|
27
|
+
#
|
28
|
+
# @param [Carrier] carrier The carrier to inject correlations into
|
29
|
+
# @param [Context] context The context to read correlations 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 correlations
|
36
|
+
def inject(carrier, context, &setter)
|
37
|
+
return carrier unless (correlations = context[ContextKeys.correlation_context_key]) && !correlations.empty?
|
38
|
+
|
39
|
+
setter ||= default_setter
|
40
|
+
setter.call(carrier, @correlation_context_key, encode(correlations))
|
41
|
+
|
42
|
+
carrier
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def encode(correlations)
|
48
|
+
correlations.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
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2020 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
|
@@ -0,0 +1,245 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2020 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
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2020 OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
module OpenTelemetry
|
8
|
+
module Instrumentation
|
9
|
+
# The instrumentation Registry contains information about instrumentation
|
10
|
+
# available and facilitates discovery, installation and
|
11
|
+
# configuration. This functionality is primarily useful for SDK
|
12
|
+
# implementors.
|
13
|
+
class Registry
|
14
|
+
def initialize
|
15
|
+
@lock = Mutex.new
|
16
|
+
@instrumentation = []
|
17
|
+
end
|
18
|
+
|
19
|
+
# @api private
|
20
|
+
def register(instrumentation)
|
21
|
+
@lock.synchronize do
|
22
|
+
@instrumentation << instrumentation
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Lookup an instrumentation definition by name. Returns nil if +instrumentation_name+
|
27
|
+
# is not found.
|
28
|
+
#
|
29
|
+
# @param [String] instrumentation_name A stringified class name for an instrumentation
|
30
|
+
# @return [Instrumentation]
|
31
|
+
def lookup(instrumentation_name)
|
32
|
+
@lock.synchronize do
|
33
|
+
find_instrumentation(instrumentation_name)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Install the specified instrumentation with optionally specified configuration.
|
38
|
+
#
|
39
|
+
# @param [Array<String>] instrumentation_names An array of instrumentation names to
|
40
|
+
# install
|
41
|
+
# @param [optional Hash<String, Hash>] instrumentation_config_map A map of
|
42
|
+
# instrumentation_name to config. This argument is optional and config can be
|
43
|
+
# passed for as many or as few instrumentations as desired.
|
44
|
+
def install(instrumentation_names, instrumentation_config_map = {})
|
45
|
+
@lock.synchronize do
|
46
|
+
instrumentation_names.each do |instrumentation_name|
|
47
|
+
instrumentation = find_instrumentation(instrumentation_name)
|
48
|
+
OpenTelemetry.logger.warn "Could not install #{instrumentation_name} because it was not found" unless instrumentation
|
49
|
+
|
50
|
+
install_instrumentation(instrumentation, instrumentation_config_map[instrumentation.name])
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Install all instrumentation available and installable in this process.
|
56
|
+
#
|
57
|
+
# @param [optional Hash<String, Hash>] instrumentation_config_map A map of
|
58
|
+
# instrumentation_name to config. This argument is optional and config can be
|
59
|
+
# passed for as many or as few instrumentations as desired.
|
60
|
+
def install_all(instrumentation_config_map = {})
|
61
|
+
@lock.synchronize do
|
62
|
+
@instrumentation.map(&:instance).each do |instrumentation|
|
63
|
+
install_instrumentation(instrumentation, instrumentation_config_map[instrumentation.name])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def find_instrumentation(instrumentation_name)
|
71
|
+
@instrumentation.detect { |a| a.instance.name == instrumentation_name }
|
72
|
+
&.instance
|
73
|
+
end
|
74
|
+
|
75
|
+
def install_instrumentation(instrumentation, config)
|
76
|
+
if instrumentation.install(config)
|
77
|
+
OpenTelemetry.logger.info "Instrumentation: #{instrumentation.name} was successfully installed"
|
78
|
+
else
|
79
|
+
OpenTelemetry.logger.warn "Instrumentation: #{instrumentation.name} failed to install"
|
80
|
+
end
|
81
|
+
rescue => e # rubocop:disable Style/RescueStandardError
|
82
|
+
OpenTelemetry.logger.warn "Instrumentation: #{instrumentation.name} unhandled exception" \
|
83
|
+
"during install #{e}: #{e.backtrace}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|