lib/ddtrace/contrib/patcher.rb in ddtrace-0.29.1 vs lib/ddtrace/contrib/patcher.rb in ddtrace-0.30.0

- old
+ new

@@ -4,24 +4,52 @@ module Contrib # Common behavior for patcher modules module Patcher def self.included(base) base.send(:include, Datadog::Patcher) - base.send(:extend, InstanceMethods) - base.send(:include, InstanceMethods) + + base.singleton_class.send(:prepend, CommonMethods) + base.send(:prepend, CommonMethods) if base.class == Class end - # Class methods for patchers - module ClassMethods - def patch - raise NotImplementedError, '#patch not implemented for Patcher!' + # Prepended instance methods for all patchers + module CommonMethods + def patch_name + self.class != Class && self.class != Module ? self.class.name : name end - end - # Instance methods for patchers - module InstanceMethods + def patched? + done?(:patch) + end + def patch - raise NotImplementedError, '#patch not implemented for Patcher!' + return unless defined?(super) + + do_once(:patch) do + begin + super.tap do + # Emit a metric + Diagnostics::Health.metrics.instrumentation_patched(1, tags: default_tags) + end + rescue StandardError => e + # Log the error + Datadog::Tracer.log.error("Failed to apply #{patch_name} patch. Cause: #{e} Location: #{e.backtrace.first}") + + # Emit a metric + tags = default_tags + tags << "error:#{e.class.name}" + + Diagnostics::Health.metrics.error_instrumentation_patch(1, tags: tags) + end + end + end + + private + + def default_tags + ["patcher:#{patch_name}"].tap do |tags| + tags << "target_version:#{target_version}" if respond_to?(:target_version) && !target_version.nil? + end end end end end end