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) ⇒ Base

Returns a new instance of Base.



163
164
165
166
167
168
169
170
171
172
# File 'lib/opentelemetry/instrumentation/base.rb', line 163

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

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



159
160
161
# File 'lib/opentelemetry/instrumentation/base.rb', line 159

def config
  @config
end

#installedObject (readonly) Also known as: installed?

Returns the value of attribute installed.



159
160
161
# File 'lib/opentelemetry/instrumentation/base.rb', line 159

def installed
  @installed
end

#nameObject (readonly)

Returns the value of attribute name.



159
160
161
# File 'lib/opentelemetry/instrumentation/base.rb', line 159

def name
  @name
end

#tracerObject (readonly)

Returns the value of attribute tracer.



159
160
161
# File 'lib/opentelemetry/instrumentation/base.rb', line 159

def tracer
  @tracer
end

#versionObject (readonly)

Returns the value of attribute version.



159
160
161
# File 'lib/opentelemetry/instrumentation/base.rb', line 159

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



128
129
130
# File 'lib/opentelemetry/instrumentation/base.rb', line 128

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



108
109
110
# File 'lib/opentelemetry/instrumentation/base.rb', line 108

def install(&blk)
  @install_blk = blk
end

.instanceObject



132
133
134
135
# File 'lib/opentelemetry/instrumentation/base.rb', line 132

def instance
  @instance ||= new(instrumentation_name, instrumentation_version, install_blk,
                    present_blk, compatible_blk)
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



79
80
81
82
83
84
85
# File 'lib/opentelemetry/instrumentation/base.rb', line 79

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



94
95
96
97
98
99
100
# File 'lib/opentelemetry/instrumentation/base.rb', line 94

def instrumentation_version(instrumentation_version = nil)
  if instrumentation_version
    @instrumentation_version = instrumentation_version
  else
    @instrumentation_version ||= infer_version || '0.0.0'
  end
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



118
119
120
# File 'lib/opentelemetry/instrumentation/base.rb', line 118

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)


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

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)


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

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



179
180
181
182
183
184
185
186
187
# File 'lib/opentelemetry/instrumentation/base.rb', line 179

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

  @config = config unless config.nil?
  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)


194
195
196
# File 'lib/opentelemetry/instrumentation/base.rb', line 194

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)


200
201
202
203
204
# File 'lib/opentelemetry/instrumentation/base.rb', line 200

def present?
  return false unless @present_blk

  instance_exec(&@present_blk)
end