Module: OneApm::Support::MethodTracer::ClassMethods::AddMethodTracer
- Included in:
- OneApm::Support::MethodTracer::ClassMethods
- Defined in:
- lib/one_apm/support/method_tracer.rb
Overview
contains methods refactored out of the #add_method_tracer method
Constant Summary collapse
- ALLOWED_KEYS =
[:force, :metric, :push_scope, :code_header, :code_footer].freeze
- DEPRECATED_KEYS =
[:force, :scoped_metric_only, :deduct_call_time_from_parent].freeze
- OA_DEFAULT_SETTINGS =
{:push_scope => true, :metric => true, :code_header => "", :code_footer => "" }.freeze
Instance Method Summary collapse
-
#assemble_code_header(method_name, metric_name_code, options) ⇒ Object
Returns a code snippet to be eval’d that skips tracing when the agent is not tracing execution.
-
#check_for_illegal_keys!(method_name, options) ⇒ Object
raises an error when the OneApm::Support::MethodTracer::ClassMethods#add_method_tracer method is called with improper keys.
-
#check_for_push_scope_and_metric(options) ⇒ Object
validity checking - add_method_tracer must receive either push scope or metric, or else it would record no data.
-
#code_to_eval(method_name, metric_name_code, options) ⇒ Object
Decides which code snippet we should be eval’ing in this context, based on the options.
-
#default_metric_name_code(method_name) ⇒ Object
Default to the class where the method is defined.
-
#method_with_push_scope(method_name, metric_name_code, options) ⇒ Object
returns an eval-able string that contains the tracing code for a fully traced metric including scoping.
-
#method_without_push_scope(method_name, metric_name_code, options) ⇒ Object
returns an eval-able string that contains the traced method code used if the agent is not creating a scope for use in scoped metrics.
-
#oneapm_method_exists?(method_name) ⇒ Boolean
Checks to see if the method we are attempting to trace actually exists or not.
-
#traced_method_exists?(method_name, metric_name_code) ⇒ 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
Checks the provided options to make sure that they make sense.
Instance Method Details
#assemble_code_header(method_name, metric_name_code, options) ⇒ Object
Returns a code snippet to be eval’d that skips tracing when the agent is not tracing execution. turns instrumentation into effectively one method call overhead when the agent is disabled
174 175 176 177 178 |
# File 'lib/one_apm/support/method_tracer.rb', line 174 def assemble_code_header(method_name, metric_name_code, ) header = "return #{_untraced_method_name(method_name, metric_name_code)}(*args, &block) unless OneApm::Manager.tl_is_execution_traced?\n" header += [:code_header].to_s header end |
#check_for_illegal_keys!(method_name, options) ⇒ Object
raises an error when the OneApm::Support::MethodTracer::ClassMethods#add_method_tracer method is called with improper keys. This aids in debugging new instrumentation by failing fast
103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/one_apm/support/method_tracer.rb', line 103 def check_for_illegal_keys!(method_name, ) unrecognized_keys = .keys - ALLOWED_KEYS deprecated_keys = .keys & DEPRECATED_KEYS if unrecognized_keys.any? raise "Unrecognized options when adding method tracer to #{method_name}: " + unrecognized_keys.join(', ') end if deprecated_keys.any? OneApm::Manager.logger.warn("Deprecated options when adding method tracer to #{method_name}: "+ deprecated_keys.join(', ')) end end |
#check_for_push_scope_and_metric(options) ⇒ Object
validity checking - add_method_tracer must receive either push scope or metric, or else it would record no data. Raises an error if this is the case
121 122 123 124 125 |
# File 'lib/one_apm/support/method_tracer.rb', line 121 def check_for_push_scope_and_metric() unless [:push_scope] || [:metric] raise "Can't add a tracer where push_scope is false and metric is false" end end |
#code_to_eval(method_name, metric_name_code, options) ⇒ Object
Decides which code snippet we should be eval’ing in this context, based on the options.
213 214 215 216 217 218 219 220 |
# File 'lib/one_apm/support/method_tracer.rb', line 213 def code_to_eval(method_name, metric_name_code, ) = (method_name, ) if [:push_scope] method_with_push_scope(method_name, metric_name_code, ) else method_without_push_scope(method_name, metric_name_code, ) end end |
#default_metric_name_code(method_name) ⇒ Object
Default to the class where the method is defined.
Example:
Foo.default_metric_name_code('bar') #=> "Custom/#{Foo.name}/bar"
147 148 149 |
# File 'lib/one_apm/support/method_tracer.rb', line 147 def default_metric_name_code(method_name) "Custom/#{self.name}/#{method_name.to_s}" end |
#method_with_push_scope(method_name, metric_name_code, options) ⇒ Object
returns an eval-able string that contains the tracing code for a fully traced metric including scoping
199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/one_apm/support/method_tracer.rb', line 199 def method_with_push_scope(method_name, metric_name_code, ) "def #{_traced_method_name(method_name, metric_name_code)}(*args, &block) #{[:code_header]} result = ::OneApm::Support::MethodTracer::Helpers.trace_execution_scoped(\"#{metric_name_code}\", :metric => #{[:metric]}) do #{_untraced_method_name(method_name, metric_name_code)}(*args, &block) end #{[:code_footer]} result end" end |
#method_without_push_scope(method_name, metric_name_code, options) ⇒ Object
returns an eval-able string that contains the traced method code used if the agent is not creating a scope for use in scoped metrics.
183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/one_apm/support/method_tracer.rb', line 183 def method_without_push_scope(method_name, metric_name_code, ) "def #{_traced_method_name(method_name, metric_name_code)}(*args, &block) #{assemble_code_header(method_name, metric_name_code, )} t0 = Time.now begin #{_untraced_method_name(method_name, metric_name_code)}(*args, &block)\n ensure duration = (Time.now - t0).to_f OneApm::Manager.record_metric(\"#{metric_name_code}\", duration) #{[:code_footer]} end end" end |
#oneapm_method_exists?(method_name) ⇒ Boolean
Checks to see if the method we are attempting to trace actually exists or not. #add_method_tracer can’t do anything if the method doesn’t exist.
154 155 156 157 158 |
# File 'lib/one_apm/support/method_tracer.rb', line 154 def oneapm_method_exists?(method_name) exists = method_defined?(method_name) || private_method_defined?(method_name) OneApm::Manager.logger.error("Did not trace #{self.name}##{method_name} because that method does not exist") unless exists exists end |
#traced_method_exists?(method_name, metric_name_code) ⇒ 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.
164 165 166 167 168 |
# File 'lib/one_apm/support/method_tracer.rb', line 164 def traced_method_exists?(method_name, metric_name_code) exists = method_defined?(_traced_method_name(method_name, metric_name_code)) OneApm::Manager.logger.error("Attempt to trace a method twice with the same metric: Method = #{method_name}, Metric Name = #{metric_name_code}") if exists exists end |
#validate_options(method_name, options) ⇒ Object
Checks the provided options to make sure that they make sense. Raises an error if the options are incorrect to assist with debugging, so that errors occur at class construction time rather than instrumentation run time
133 134 135 136 137 138 139 140 141 |
# File 'lib/one_apm/support/method_tracer.rb', line 133 def (method_name, ) unless .is_a?(Hash) raise TypeError.new("Error adding method tracer to #{method_name}: provided options must be a Hash") end check_for_illegal_keys!(method_name, ) = OA_DEFAULT_SETTINGS.merge() check_for_push_scope_and_metric() end |