Module: TingYun::Instrumentation::Support::MethodInstrumentation::ClassMethods
- Defined in:
- lib/ting_yun/instrumentation/support/method_instrumentation.rb
Constant Summary collapse
- DEFAULT_SETTINGS =
{:scope => true, :metric => true, :before_code => "", :after_code => "" }.freeze
Instance Method Summary collapse
- #add_method_tracer(method_name, metric_name = nil, opt = {}) ⇒ Object
-
#default_metric_name(method_name) ⇒ Object
Example: Foo.default_metric_name(‘bar’) #=> “tingyun/#Foo.name/bar”.
- #define_method_with_scope(method_name, metric_name, options) ⇒ Object
- #define_method_without_scope(method_name, metric_name, options) ⇒ Object
- #method_exists?(method_name) ⇒ Boolean
- #tingyun_eval(method_name, metric_name, options) ⇒ Object
-
#traced_method_exists?(method_name, metric_name) ⇒ Boolean
Checks to see if we have already traced a method with a given metric by checking to see if the traced method exists.
- #validate_options(method_name, options) ⇒ Object
Instance Method Details
#add_method_tracer(method_name, metric_name = nil, opt = {}) ⇒ Object
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/ting_yun/instrumentation/support/method_instrumentation.rb', line 183 def add_method_tracer(method_name, metric_name = nil, opt={}) return unless method_exists?(method_name) metric_name ||= default_metric_name(method_name) return if traced_method_exists?(method_name, metric_name) traced_method = tingyun_eval(method_name, metric_name,opt) visibility = TingYun::Helper.instance_method_visibility self, method_name class_eval traced_method, __FILE__, __LINE__ alias_method define_untrace_method_name(method_name, metric_name), method_name alias_method method_name, define_trace_method_name(method_name, metric_name) send visibility, method_name send visibility, define_trace_method_name(method_name, metric_name) ::TingYun::Agent.logger.debug("Traced method: class = #{self.name},"+ "method = #{method_name}, "+ "metric = '#{metric_name}'") end |
#default_metric_name(method_name) ⇒ Object
Example:
Foo.default_metric_name('bar') #=> "tingyun/#{Foo.name}/bar"
63 64 65 |
# File 'lib/ting_yun/instrumentation/support/method_instrumentation.rb', line 63 def default_metric_name(method_name) "tingyun/#{self.name}/#{method_name.to_s}" end |
#define_method_with_scope(method_name, metric_name, options) ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/ting_yun/instrumentation/support/method_instrumentation.rb', line 100 def define_method_with_scope(method_name,metric_name,) "def #{define_trace_method_name(method_name,metric_name)}(*args, &block) #{[:before_code]} result = ::TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(\"#{metric_name}\", :metric => #{[:metric]}) do #{define_untrace_method_name(method_name, metric_name)}(*args, &block) end #{[:after_code]} result end" end |
#define_method_without_scope(method_name, metric_name, options) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/ting_yun/instrumentation/support/method_instrumentation.rb', line 113 def define_method_without_scope(method_name,metric_name,) "def #{define_trace_method_name(method_name,metric_name)}(*args, &block) return #{define_untrace_method_name(method_name, metric_name)}(*args, &block) unless TingYun::Agent::TransactionState.tl_get.execution_traced?\n #{[:before_code]} t0 = Time.now begin #{define_untrace_method_name(method_name, metric_name)}(*args, &block)\n ensure duration = (Time.now - t0).to_f ::TingYun::Agent.record_metric(\"#{metric_name}\", duration) #{[:after_code]} end end" end |
#method_exists?(method_name) ⇒ Boolean
55 56 57 58 59 |
# File 'lib/ting_yun/instrumentation/support/method_instrumentation.rb', line 55 def method_exists?(method_name) exists = method_defined?(method_name) || private_method_defined?(method_name) ::TingYun::Agent.logger.error("Did not trace #{self.name}##{method_name} because that method does not exist") unless exists exists end |
#tingyun_eval(method_name, metric_name, options) ⇒ Object
78 79 80 81 82 83 84 85 |
# File 'lib/ting_yun/instrumentation/support/method_instrumentation.rb', line 78 def tingyun_eval(method_name, metric_name, ) = (method_name, ) if [:scope] define_method_with_scope(method_name, metric_name, ) else define_method_without_scope(method_name,metric_name, ) end end |
#traced_method_exists?(method_name, metric_name) ⇒ Boolean
Checks to see if we have already traced a method with a given metric by checking to see if the traced method exists. Warns the user if methods are being double-traced to help with debugging custom instrumentation.
72 73 74 75 76 |
# File 'lib/ting_yun/instrumentation/support/method_instrumentation.rb', line 72 def traced_method_exists?(method_name, metric_name) exists = method_defined?(define_trace_method_name(method_name, metric_name)) ::TingYun::Agent.logger.error("Attempt to trace a method twice with the same metric: Method = #{method_name}, Metric Name = #{metric_name}") if exists exists end |
#validate_options(method_name, options) ⇒ Object
89 90 91 92 93 94 95 96 97 98 |
# File 'lib/ting_yun/instrumentation/support/method_instrumentation.rb', line 89 def (method_name, ) unless .is_a?(Hash) raise TypeError.new("Error adding method tracer to #{method_name}: provided options must be a Hash") end = DEFAULT_SETTINGS.merge() unless [:scope] || [:metric] raise "Can't add a tracer where push_scope is false and metric is false" end end |