Class: OpenTelemetry::Instrumentation::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/opentelemetry/instrumentation/base.rb

Overview

The Base class holds all metadata and configuration for an instrumentation. All instrumentation packages should include a subclass of Instrumentation::Base that will register it with OpenTelemetry.instrumentation_registry and make it available for discovery and installation by an SDK.

A typical subclass of Base will provide an install block, a present block, and possibly a compatible block. Below is an example:

module OpenTelemetry module Instrumentation module Sinatra class Instrumentation < OpenTelemetry::Instrumentation::Base install do |config| # install instrumentation, either by library hook or applying # a monkey patch end

    # determine if the target library is present
    present do
      defined?(::Sinatra)
    end

    # if the target library is present, is it compatible?
    compatible do
      Gem.loaded_specs['sinatra'].version > MIN_VERSION
    end
  end
end

end end

The instrumentation name and version will be inferred from the namespace of the class. In this example, they'd be 'OpenTelemetry::Instrumentation::Sinatra' and OpenTelemetry::Instrumentation::Sinatra::VERSION, but can be explicitly set using the instrumentation_name and instrumetation_version methods if necessary.

All subclasses of OpenTelemetry::Instrumentation::Base are automatically registered with OpenTelemetry.instrumentation_registry which is used by SDKs for instrumentation discovery and installation.

Instrumentation libraries can use the instrumentation subclass to easily gain a reference to its named tracer. For example:

OpenTelemetry::Instrumentation::Sinatra.instance.tracer

The instrumention class establishes a convention for disabling an instrumentation by environment variable and local configuration. An instrumentation disabled by environment variable will take precedence over local config. The convention for environment variable name is the library name, upcased with '::' replaced by underscores, OPENTELEMETRY shortened to OTELLANG, and 'ENABLED' appended. For example: OTEL_RUBY_INSTRUMENTATION_SINATRA_ENABLED = false.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, version, install_blk, present_blk, compatible_blk, options) ⇒ Base

Returns a new instance of Base.



187
188
189
190
191
192
193
194
195
196
197
# File 'lib/opentelemetry/instrumentation/base.rb', line 187

def initialize(name, version, install_blk, present_blk,
               compatible_blk, options)
  @name = name
  @version = version
  @install_blk = install_blk
  @present_blk = present_blk
  @compatible_blk = compatible_blk
  @config = {}
  @installed = false
  @options = options
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



183
184
185
# File 'lib/opentelemetry/instrumentation/base.rb', line 183

def config
  @config
end

#installedObject (readonly) Also known as: installed?

Returns the value of attribute installed.



183
184
185
# File 'lib/opentelemetry/instrumentation/base.rb', line 183

def installed
  @installed
end

#nameObject (readonly)

Returns the value of attribute name.



183
184
185
# File 'lib/opentelemetry/instrumentation/base.rb', line 183

def name
  @name
end

#tracerObject (readonly)

Returns the value of attribute tracer.



183
184
185
# File 'lib/opentelemetry/instrumentation/base.rb', line 183

def tracer
  @tracer
end

#versionObject (readonly)

Returns the value of attribute version.



183
184
185
# File 'lib/opentelemetry/instrumentation/base.rb', line 183

def version
  @version
end

Class Method Details

.compatible(&blk) ⇒ Object

The compatible block for this instrumentation. This check will be run if the target library is present to determine if it's compatible. It's not required, but a common use case will be to check to target library version for compatibility.

Parameters:

  • blk (Callable)

    The compatibility block for this instrumentation



136
137
138
# File 'lib/opentelemetry/instrumentation/base.rb', line 136

def compatible(&blk)
  @compatible_blk = blk
end

.install(&blk) {|config| ... } ⇒ Object

The install block for this instrumentation. This will be where you install instrumentation, either by framework hook or applying a monkey patch.

Parameters:

  • blk (Callable)

    The install block for this instrumentation

Yield Parameters:

  • config (Hash)

    The instrumentation config will be yielded to the install block



116
117
118
# File 'lib/opentelemetry/instrumentation/base.rb', line 116

def install(&blk)
  @install_blk = blk
end

.instanceObject



156
157
158
159
# File 'lib/opentelemetry/instrumentation/base.rb', line 156

def instance
  @instance ||= new(instrumentation_name, instrumentation_version, install_blk,
                    present_blk, compatible_blk, options)
end

.instrumentation_name(instrumentation_name = nil) ⇒ Object

Optionally set the name of this instrumentation. If not explicitly set, the name will default to the namespace of the class, or the class name if it does not have a namespace. If there is not a namespace, or a class name, it will default to 'unknown'.

Parameters:

  • instrumentation_name (String) (defaults to: nil)

    The full name of the instrumentation package



87
88
89
90
91
92
93
# File 'lib/opentelemetry/instrumentation/base.rb', line 87

def instrumentation_name(instrumentation_name = nil)
  if instrumentation_name
    @instrumentation_name = instrumentation_name
  else
    @instrumentation_name ||= infer_name || 'unknown'
  end
end

.instrumentation_version(instrumentation_version = nil) ⇒ Object

Optionally set the version of this instrumentation. If not explicitly set, the version will default to the VERSION constant under namespace of the class, or the VERSION constant under the class name if it does not have a namespace. If a VERSION constant cannot be found, it defaults to '0.0.0'.

Parameters:

  • instrumentation_version (String) (defaults to: nil)

    The version of the instrumentation package



102
103
104
105
106
107
108
# File 'lib/opentelemetry/instrumentation/base.rb', line 102

def instrumentation_version(instrumentation_version = nil)
  if instrumentation_version
    @instrumentation_version = instrumentation_version
  else
    @instrumentation_version ||= infer_version || '0.0.0'
  end
end

.option(name, default:, validate:) ⇒ Object

The option method is used to define default configuration options for the instrumentation library. It requires a name, default value, and a validation callable to be provided. a key in the VALIDATORS hash. The supported keys are, :array, :boolean, :callable, :integer, :string.

Parameters:

  • name (String)

    The name of the configuration option

  • default

    The default value to be used, or to used if validation fails

  • validate (Callable, Symbol)

    Accepts a callable or a symbol that matches

Raises:

  • (ArgumentError)


148
149
150
151
152
153
154
# File 'lib/opentelemetry/instrumentation/base.rb', line 148

def option(name, default:, validate:)
  validate = VALIDATORS[validate] || validate
  raise ArgumentError, "validate must be #{VALIDATORS.keys.join(', ')}, or a callable" unless validate.respond_to?(:call)

  @options ||= []
  @options << { name: name, default: default, validate: validate }
end

.present(&blk) ⇒ Object

The present block for this instrumentation. This block is used to detect if target library is present on the system. Typically this will involve checking to see if the target gem spec was loaded or if expected constants from the target library are present.

Parameters:

  • blk (Callable)

    The present block for this instrumentation



126
127
128
# File 'lib/opentelemetry/instrumentation/base.rb', line 126

def present(&blk)
  @present_blk = blk
end

Instance Method Details

#compatible?Boolean

Calls the compatible block of the Instrumentation subclasses, if no block is provided it's assumed to be compatible

Returns:

  • (Boolean)


233
234
235
236
237
# File 'lib/opentelemetry/instrumentation/base.rb', line 233

def compatible?
  return true unless @compatible_blk

  instance_exec(&@compatible_blk)
end

#enabled?(config = nil) ⇒ Boolean

Whether this instrumentation is enabled. It first checks to see if it's enabled by an environment variable and will proceed to check if it's enabled by local config, if given.

Parameters:

  • config (optional Hash) (defaults to: nil)

    The local config

Returns:

  • (Boolean)


244
245
246
247
248
249
# File 'lib/opentelemetry/instrumentation/base.rb', line 244

def enabled?(config = nil)
  return false unless enabled_by_env_var?
  return config[:enabled] if config&.key?(:enabled)

  true
end

#install(config = {}) ⇒ Object

Install instrumentation with the given config. The present? and compatible? will be run first, and install will return false if either fail. Will return true if install was completed successfully.

Parameters:

  • config (Hash) (defaults to: {})

    The config for this instrumentation



204
205
206
207
208
209
210
211
212
# File 'lib/opentelemetry/instrumentation/base.rb', line 204

def install(config = {})
  return true if installed?
  return false unless installable?(config)

  @config = config_options(config)
  instance_exec(@config, &@install_blk)
  @tracer ||= OpenTelemetry.tracer_provider.tracer(name, version)
  @installed = true
end

#installable?(config = {}) ⇒ Boolean

Whether or not this instrumentation is installable in the current process. Will be true when the instrumentation defines an install block, is not disabled by environment or config, and the target library present and compatible.

Parameters:

  • config (Hash) (defaults to: {})

    The config for this instrumentation

Returns:

  • (Boolean)


219
220
221
# File 'lib/opentelemetry/instrumentation/base.rb', line 219

def installable?(config = {})
  @install_blk && enabled?(config) && present? && compatible?
end

#present?Boolean

Calls the present block of the Instrumentation subclasses, if no block is provided it's assumed the instrumentation is not present

Returns:

  • (Boolean)


225
226
227
228
229
# File 'lib/opentelemetry/instrumentation/base.rb', line 225

def present?
  return false unless @present_blk

  instance_exec(&@present_blk)
end