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