diff --git a/instrumentation/aws_sdk/lib/opentelemetry/instrumentation/aws_sdk/instrumentation.rb b/instrumentation/aws_sdk/lib/opentelemetry/instrumentation/aws_sdk/instrumentation.rb index 07b4075f2..6173074b2 100644 --- a/instrumentation/aws_sdk/lib/opentelemetry/instrumentation/aws_sdk/instrumentation.rb +++ b/instrumentation/aws_sdk/lib/opentelemetry/instrumentation/aws_sdk/instrumentation.rb @@ -10,10 +10,11 @@ module AwsSdk # Instrumentation class that detects and installs the AwsSdk instrumentation class Instrumentation < OpenTelemetry::Instrumentation::Base MINIMUM_VERSION = Gem::Version.new('2.0.0') + CURRENT_MAJOR_VERSION = Gem::Version.new('3.0.0') install do |_config| require_dependencies - add_plugin(Seahorse::Client::Base, *loaded_constants) + add_plugins(Seahorse::Client::Base, *loaded_constants) end present do @@ -46,14 +47,42 @@ def require_dependencies require_relative 'messaging_helper' end - def add_plugin(*targets) + def add_plugins(*targets) targets.each { |klass| klass.add_plugin(AwsSdk::Plugin) } end def loaded_constants + if gem_version >= CURRENT_MAJOR_VERSION + load_v3_constants + else + load_legacy_constants + end + end + + def load_v3_constants + ::Aws.constants.each_with_object([]) do |c, constants| + m = ::Aws.const_get(c) + next unless unloaded_service?(c, m) + + begin + constants << m.const_get(:Client) + rescue StandardError => e + OpenTelemetry.logger.warn("Constant could not be loaded: #{e}") + end + end + end + + def unloaded_service?(constant, service_module) + !::Aws.autoload?(constant) && + service_module.is_a?(Module) && + service_module.const_defined?(:Client) && + (service_module.const_get(:Client).superclass == Seahorse::Client::Base) + end + + def load_legacy_constants # Cross-check services against loaded AWS constants # Module#const_get can return a constant from ancestors when there's a miss. - # If this conincidentally matches another constant, it will attempt to patch + # If this coincidentally matches another constant, it will attempt to patch # the wrong constant, resulting in patch failure. available_services = ::Aws.constants & SERVICES.map(&:to_sym) available_services.each_with_object([]) do |service, constants| diff --git a/instrumentation/aws_sdk/opentelemetry-instrumentation-aws_sdk.gemspec b/instrumentation/aws_sdk/opentelemetry-instrumentation-aws_sdk.gemspec index 01415e31c..4fba14c34 100644 --- a/instrumentation/aws_sdk/opentelemetry-instrumentation-aws_sdk.gemspec +++ b/instrumentation/aws_sdk/opentelemetry-instrumentation-aws_sdk.gemspec @@ -20,8 +20,8 @@ Gem::Specification.new do |spec| spec.license = 'Apache-2.0' spec.files = Dir.glob('lib/**/*.rb') + - Dir.glob('*.md') + - ['LICENSE', '.yardopts'] + Dir.glob('*.md') + + ['LICENSE', '.yardopts'] spec.require_paths = ['lib'] spec.required_ruby_version = '>= 3.0' @@ -29,6 +29,10 @@ Gem::Specification.new do |spec| spec.add_dependency 'opentelemetry-instrumentation-base', '~> 0.22.1' spec.add_development_dependency 'appraisal', '~> 2.5' + spec.add_development_dependency 'aws-sdk-dynamodb' + spec.add_development_dependency 'aws-sdk-s3' + spec.add_development_dependency 'aws-sdk-sns' + spec.add_development_dependency 'aws-sdk-sqs' spec.add_development_dependency 'bundler', '~> 2.4' spec.add_development_dependency 'minitest', '~> 5.0' spec.add_development_dependency 'opentelemetry-sdk', '~> 1.1'