Module: NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScoped
- Included in:
- NewRelic::Agent::MethodTracer::InstanceMethods
- Defined in:
- lib/new_relic/agent/method_tracer.rb
Overview
Refactored out of the previous trace_execution_scoped method, most methods in this module relate to code used in the #trace_execution_scoped method in this module
Instance Method Summary collapse
-
#agent_instance ⇒ Object
Shorthand to return the NewRelic::Agent.instance.
-
#get_metric_stats(metrics, options) ⇒ Object
returns an array containing the first metric, and an array of other unscoped statistics we should also record along side it.
-
#get_stats_scoped(first_name, scoped_metric_only) ⇒ Object
returns a scoped metric stat for the specified name.
-
#get_stats_unscoped(name) ⇒ Object
Shorthand method to get stats from the stat engine.
-
#log_errors(code_area, metric) ⇒ Object
helper for logging errors to the newrelic_agent.log properly.
-
#main_stat(metric, options) ⇒ Object
the main statistic we should record in #trace_execution_scoped - a scoped metric provided by the first item in the metric array.
-
#pop_flag!(forced) ⇒ Object
delegates to #agent_instance to pop the trace execution flag, only if execution of this metric is forced.
-
#push_flag!(forced) ⇒ Object
delegates to #agent_instance to push a trace execution flag, only if execution of this metric is forced.
-
#set_if_nil(hash, key) ⇒ Object
Helper for setting a hash key if the hash key is nil, instead of the default ||= behavior which sets if it is false as well.
-
#stat_engine ⇒ Object
Shorthand to return the current statistics engine.
-
#trace_disabled?(options) ⇒ Boolean
Tracing is disabled if we are not in a traced context and no force option is supplied.
-
#trace_execution_scoped(metric_names, options = {}) ⇒ Object
Trace a given block with stats and keep track of the caller.
-
#trace_execution_scoped_footer(t0, first_name, metric_stats, expected_scope, forced, t1 = Time.now.to_f) ⇒ Object
Handles the end of the #trace_execution_scoped method - calculating the time taken, popping the tracing flag if needed, deducting time taken by children, and tracing the subsidiary unscoped metrics if any.
-
#trace_execution_scoped_header(metric, options, t0 = Time.now.to_f) ⇒ Object
provides the header for our traced execution scoped method - gets the initial time, sets the tracing flag if needed, and pushes the scope onto the metric stack logs any errors that occur and returns the start time and the scope so that we can check for it later, to maintain sanity.
-
#traced? ⇒ Boolean
Shorthand to return the status of tracing.
Instance Method Details
#agent_instance ⇒ Object
Shorthand to return the NewRelic::Agent.instance
101 102 103 |
# File 'lib/new_relic/agent/method_tracer.rb', line 101 def agent_instance NewRelic::Agent.instance end |
#get_metric_stats(metrics, options) ⇒ Object
returns an array containing the first metric, and an array of other unscoped statistics we should also record along side it
140 141 142 143 144 145 146 147 148 |
# File 'lib/new_relic/agent/method_tracer.rb', line 140 def get_metric_stats(metrics, ) metrics = Array(metrics) first_name = metrics.shift stats = metrics.map do | name | get_stats_unscoped(name) end stats.unshift(main_stat(first_name, )) if [:metric] [first_name, stats] end |
#get_stats_scoped(first_name, scoped_metric_only) ⇒ Object
returns a scoped metric stat for the specified name
122 123 124 |
# File 'lib/new_relic/agent/method_tracer.rb', line 122 def get_stats_scoped(first_name, scoped_metric_only) stat_engine.get_stats(first_name, true, scoped_metric_only) end |
#get_stats_unscoped(name) ⇒ Object
Shorthand method to get stats from the stat engine
126 127 128 |
# File 'lib/new_relic/agent/method_tracer.rb', line 126 def get_stats_unscoped(name) stat_engine.get_stats_no_scope(name) end |
#log_errors(code_area, metric) ⇒ Object
helper for logging errors to the newrelic_agent.log properly. Logs the error at error level, and includes a backtrace if we’re running at debug level
180 181 182 183 184 185 |
# File 'lib/new_relic/agent/method_tracer.rb', line 180 def log_errors(code_area, metric) yield rescue => e NewRelic::Control.instance.log.error("Caught exception in #{code_area}. Metric name = #{metric}, exception = #{e}") NewRelic::Control.instance.log.error(e.backtrace.join("\n")) end |
#main_stat(metric, options) ⇒ Object
the main statistic we should record in #trace_execution_scoped - a scoped metric provided by the first item in the metric array
133 134 135 |
# File 'lib/new_relic/agent/method_tracer.rb', line 133 def main_stat(metric, ) get_stats_scoped(metric, [:scoped_metric_only]) end |
#pop_flag!(forced) ⇒ Object
delegates to #agent_instance to pop the trace execution flag, only if execution of this metric is forced. otherwise this is taken care of for us automatically.
This ends the forced recording of metrics within the #trace_execution_scoped block
173 174 175 |
# File 'lib/new_relic/agent/method_tracer.rb', line 173 def pop_flag!(forced) agent_instance.pop_trace_execution_flag if forced end |
#push_flag!(forced) ⇒ Object
delegates to #agent_instance to push a trace execution flag, only if execution of this metric is forced.
This causes everything scoped inside this metric to be recorded, even if the parent transaction is generally not.
162 163 164 |
# File 'lib/new_relic/agent/method_tracer.rb', line 162 def push_flag!(forced) agent_instance.push_trace_execution_flag(true) if forced end |
#set_if_nil(hash, key) ⇒ Object
Helper for setting a hash key if the hash key is nil, instead of the default ||= behavior which sets if it is false as well
153 154 155 |
# File 'lib/new_relic/agent/method_tracer.rb', line 153 def set_if_nil(hash, key) hash[key] = true if hash[key].nil? end |
#stat_engine ⇒ Object
Shorthand to return the current statistics engine
117 118 119 |
# File 'lib/new_relic/agent/method_tracer.rb', line 117 def stat_engine agent_instance.stats_engine end |
#trace_disabled?(options) ⇒ Boolean
Tracing is disabled if we are not in a traced context and no force option is supplied
112 113 114 |
# File 'lib/new_relic/agent/method_tracer.rb', line 112 def trace_disabled?() !(traced? || [:force]) end |
#trace_execution_scoped(metric_names, options = {}) ⇒ Object
Trace a given block with stats and keep track of the caller. See NewRelic::Agent::MethodTracer::ClassMethods#add_method_tracer for a description of the arguments. metric_names
is either a single name or an array of metric names. If more than one metric is passed, the produce_metric
option only applies to the first. The others are always recorded. Only the first metric is pushed onto the scope stack.
Generally you pass an array of metric names if you want to record the metric under additional categories, but generally this *should never ever be done*. Most of the time you can aggregate on the server.
235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/new_relic/agent/method_tracer.rb', line 235 def trace_execution_scoped(metric_names, ={}) return yield if trace_disabled?() set_if_nil(, :metric) set_if_nil(, :deduct_call_time_from_parent) first_name, metric_stats = get_metric_stats(metric_names, ) start_time, expected_scope = trace_execution_scoped_header(first_name, ) begin yield ensure (start_time, first_name, metric_stats, expected_scope, [:force]) end end |
#trace_execution_scoped_footer(t0, first_name, metric_stats, expected_scope, forced, t1 = Time.now.to_f) ⇒ Object
Handles the end of the #trace_execution_scoped method - calculating the time taken, popping the tracing flag if needed, deducting time taken by children, and tracing the subsidiary unscoped metrics if any
this method fails safely if the header does not manage to push the scope onto the stack - it simply does not trace any metrics.
212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/new_relic/agent/method_tracer.rb', line 212 def (t0, first_name, metric_stats, expected_scope, forced, t1=Time.now.to_f) log_errors("trace_method_execution footer", first_name) do duration = t1 - t0 pop_flag!(forced) if expected_scope scope = stat_engine.pop_scope(expected_scope, duration, t1) exclusive = duration - scope.children_time metric_stats.each { |stats| stats.trace_call(duration, exclusive) } end end end |
#trace_execution_scoped_header(metric, options, t0 = Time.now.to_f) ⇒ Object
provides the header for our traced execution scoped method - gets the initial time, sets the tracing flag if needed, and pushes the scope onto the metric stack logs any errors that occur and returns the start time and the scope so that we can check for it later, to maintain sanity. If the scope stack becomes unbalanced, this transaction loses meaning.
194 195 196 197 198 199 200 201 202 |
# File 'lib/new_relic/agent/method_tracer.rb', line 194 def trace_execution_scoped_header(metric, , t0=Time.now.to_f) scope = log_errors("trace_execution_scoped header", metric) do push_flag!([:force]) scope = stat_engine.push_scope(metric, t0, [:deduct_call_time_from_parent]) end # needed in case we have an error, above, to always return # the start time. [t0, scope] end |
#traced? ⇒ Boolean
Shorthand to return the status of tracing
106 107 108 |
# File 'lib/new_relic/agent/method_tracer.rb', line 106 def traced? NewRelic::Agent.is_execution_traced? end |