module StackifyRubyAPM::Spies
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
@api private
Public Class Methods
class_exists?(class_name)
click to toggle source
# File lib/stackify_apm/spies.rb, line 87 def self.class_exists?(class_name) if class_name klass = Module.const_get(class_name) return klass.is_a?(Class) end rescue NameError return false end
hook_into(name)
click to toggle source
# File lib/stackify_apm/spies.rb, line 58 def self.hook_into(name) return unless (registration = require_hooks[name]) return unless safe_defined?(registration.const_name) installed[registration.const_name] = registration registration.install registration.require_paths.each do |path| require_hooks.delete path end end
installed()
click to toggle source
# File lib/stackify_apm/spies.rb, line 37 def self.installed @installed ||= {} end
ismethod_exists(class_name, current_method)
click to toggle source
rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/PerceivedComplexity
# File lib/stackify_apm/spies.rb, line 98 def self.ismethod_exists(class_name, current_method) module_consget = Module.const_get(class_name) current_method_without_apm = "_without_apm_#{current_method}" self_current_method_without_apm = "_self_without_apm_#{current_method}" with_flag = module_consget.instance_methods(false).include?(:"#{current_method_without_apm}") self_with_flag = module_consget.instance_methods(false).include?(:"#{self_current_method_without_apm}") current_method_exists = module_consget.instance_methods(false).include?(:"#{current_method}") self_current_method_exists = module_consget.instance_methods(false).include?(:"self.#{current_method}") exists = false if (self_with_flag == false && with_flag == false) && (current_method_exists == true || self_current_method_exists == true) exists = true end if (module_consget.methods.include?(:"#{current_method_without_apm}") == false && module_consget.methods.include?(:"#{self_current_method_without_apm}") == false) && (module_consget.methods.include?(:"#{current_method}") || module_consget.methods.include?(:"self.#{current_method}")) exists = true end exists end
parse_json_config(file)
click to toggle source
# File lib/stackify_apm/spies.rb, line 74 def self.parse_json_config(file) jsondata = {} if ENV['STACKIFY_RUBY_ENV'] == 'rspec' file = 'spec/integration/stackify_spec.json' end return unless File.exist?(file) File.open(file) do |f| jsondata = JSON.parse(f.read) end jsondata end
register(*args)
click to toggle source
# File lib/stackify_apm/spies.rb, line 41 def self.register(*args) registration = Registration.new(*args) if safe_defined?(registration.const_name) registration.install installed[registration.const_name] = registration else register_require_hook registration end end
register_require_hook(registration)
click to toggle source
# File lib/stackify_apm/spies.rb, line 52 def self.register_require_hook(registration) registration.require_paths.each do |path| require_hooks[path] = registration end end
require_hooks()
click to toggle source
# File lib/stackify_apm/spies.rb, line 33 def self.require_hooks @require_hooks ||= {} end
run_custom_instrumentation()
click to toggle source
# File lib/stackify_apm/spies/custom_instrumenter.rb, line 16 def self.run_custom_instrumentation config = Config.new to_instrument = parse_json_config(config.json_config_file) if config.logger.nil? config.debug_logger config.logger.send(:info, '[StackifyRubyAPM] Error: config/stackify.json does not exist which is required for custom instrumentation!') if to_instrument.nil? end return unless !to_instrument.nil? && !to_instrument.empty? && defined?(to_instrument['instrumentation']) && (to_instrument['instrumentation'].count > 0) to_instrument['instrumentation'].each do |custom_spy| current_class = defined?(custom_spy['class']) ? custom_spy['class'] : nil current_module = defined?(custom_spy['module']) ? custom_spy['module'] : nil current_method = custom_spy['method'] tracked_func = custom_spy['trackedFunction'] tracked_func_name = defined?(custom_spy['trackedFunctionName']) ? custom_spy['trackedFunctionName'] : '' transaction = defined?(custom_spy['transaction']) ? custom_spy['transaction'] : nil file_path = defined?(custom_spy['file_path']) ? custom_spy['file_path'] : nil if current_class tracked_function_tpl = tracked_func_name.nil? ? '{{ClassName}}.{{MethodName}}' : tracked_func_name tracked_function_name = tracked_function_tpl.to_s.sub '{{ClassName}}', current_class tracked_function_name = tracked_function_name.to_s.sub '{{MethodName}}', current_method elsif current_module tracked_function_tpl = tracked_func_name.nil? ? '{{ModuleName}}.{{MethodName}}' : tracked_func_name tracked_function_name = tracked_function_tpl.to_s.sub '{{ModuleName}}', current_module tracked_function_name = tracked_function_name.to_s.sub '{{MethodName}}', current_method end begin if current_module if file_path.nil? config.logger.send(:info, "[StackifyRubyAPM] Error: Missing file_path in module which is required in custom instrumentation.") else require file_path StackifyRubyAPM::InstrumenterHelper.patched_module(tracked_func, current_module, file_path, current_method: current_method, tracked_function_name: tracked_function_name, is_transaction: transaction) end end rescue => e throw e end if !class_exists?(current_class) && !file_path.nil? begin require file_path rescue LoadError => e debug "[StackifyRubyAPM] File path doesn't exist." debug e.inspect end end # rubocop:disable Style/Next if class_exists?(current_class) mod_constant = Module.const_get(current_class.to_s) klass_method_flag = mod_constant.method_defined?(current_method.to_s) singleton_method_flag = mod_constant.respond_to?(current_method.to_s) klass_private_method_flag = mod_constant.private_method_defined?(current_method.to_s) klass_protected_method_flag = mod_constant.protected_method_defined?(current_method.to_s) class_location = mod_constant.instance_methods(false).map do |m| mod_constant.instance_method(m).source_location.first end.uniq class_path = class_location.last if klass_method_flag || klass_private_method_flag StackifyRubyAPM::InstrumenterHelper.m_class( tracked_func, current_class, class_path, current_method: current_method, tracked_function_name: tracked_function_name, is_transaction: transaction, is_private_method: klass_private_method_flag, is_protected_method: klass_protected_method_flag ) elsif singleton_method_flag StackifyRubyAPM::InstrumenterHelper.m_singleton(tracked_func, current_class, class_path, current_method: current_method, tracked_function_name: tracked_function_name, is_transaction: transaction) end end # rubocop:enable Style/Next end end
safe_defined?(const_name)
click to toggle source
# File lib/stackify_apm/spies.rb, line 70 def self.safe_defined?(const_name) Util::Inflector.safe_constantize(const_name) end