# encoding: utf-8 require 'ting_yun/agent' require 'ting_yun/instrumentation/support/metric_translator' module TingYun module Instrumentation module Mongo extend self def install_mongo_instrumentation hook_instrument_methods instrument end def hook_instrument_methods hook_instrument_method(::Mongo::Collection) hook_instrument_method(::Mongo::Connection) hook_instrument_method(::Mongo::Cursor) hook_instrument_method(::Mongo::CollectionWriter) if defined?(::Mongo::CollectionWriter) end def hook_instrument_method(target_class) target_class.class_eval do require 'ting_yun/agent/method_tracer_helpers' def record_mongo_duration(duration) state = TingYun::Agent::TransactionState.tl_get if state state.timings.mon_duration = state.timings.mon_duration + duration * 1000 end end def tingyun_host_port return @db.connection.host_port if self.instance_variable_defined? :@db return @host_to_try if self.instance_variable_defined? :@host_to_try return ['Unknown', 'Unknown'] end def tingyun_generate_metrics(operation, payload = nil) payload ||= { :collection => self.name, :database => self.db.name } TingYun::Instrumentation::Support::MetricTranslator.metrics_for(operation, payload, tingyun_host_port) end def instrument_with_tingyun(name, payload = {}, &block) klass_name, *metrics = tingyun_generate_metrics(name, payload) TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(metrics, payload, method(:record_mongo_duration), klass_name) do instrument_without_tingyun(name, payload, &block) end end alias_method :instrument_without_tingyun, :instrument alias_method :instrument, :instrument_with_tingyun end end def instrument ::Mongo::Collection.class_eval do def save_with_tingyun(doc, opts = {}, &block) y klass_name, *metrics = tingyun_generate_metrics(:save) TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(metrics, opts, method(:record_mongo_duration), klass_name) do save_without_tingyun(doc, opts, &block) end end alias_method :save_without_tingyun, :save alias_method :save, :save_with_tingyun def ensure_index_with_tingyun(spec, opts = {}, &block) klass_name, *metrics = tingyun_generate_metrics(:ensureIndex) TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(metrics, opts, method(:record_mongo_duration), klass_name) do ensure_index_without_tingyun(spec, opts, &block) end end alias_method :ensure_index_without_tingyun, :ensure_index alias_method :ensure_index, :ensure_index_with_tingyun end end end end end TingYun::Support::LibraryDetection.defer do named :mongo depends_on do !::TingYun::Agent.config[:disable_mongo] end depends_on do defined?(::Mongo) && false end depends_on do TingYun::Agent::Datastore::Mongo.supported_version? && !TingYun::Agent::Datastore::Mongo.unsupported_2x? end executes do TingYun::Agent.logger.info 'Installing Mongo instrumentation' end executes do TingYun::Instrumentation::Mongo.install_mongo_instrumentation end end