Module: NewRelic::Agent::MethodTracer::TraceExecutionScoped
- Extended by:
- TraceExecutionScoped
- Included in:
- NewRelic::Agent::MethodTracer, TraceExecutionScoped
- 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_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.
- #has_parent? ⇒ Boolean
-
#log_errors(code_area) ⇒ Object
helper for logging errors to the newrelic_agent.log properly.
- #metrics_for_current_transaction(first_name, other_names, options) ⇒ Object
- #metrics_for_parent_transaction(first_name, options) ⇒ Object
-
#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.
- #record_metrics(first_name, other_names, duration, exclusive, options) ⇒ Object
-
#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_names, expected_scope, options, 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(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
99 100 101 |
# File 'lib/new_relic/agent/method_tracer.rb', line 99 def agent_instance NewRelic::Agent.instance end |
#get_stats_scoped(first_name, scoped_metric_only) ⇒ Object
returns a scoped metric stat for the specified name
120 121 122 |
# File 'lib/new_relic/agent/method_tracer.rb', line 120 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
124 125 126 |
# File 'lib/new_relic/agent/method_tracer.rb', line 124 def get_stats_unscoped(name) stat_engine.get_stats_no_scope(name) end |
#has_parent? ⇒ Boolean
199 200 201 |
# File 'lib/new_relic/agent/method_tracer.rb', line 199 def has_parent? !NewRelic::Agent::Transaction.parent.nil? end |
#log_errors(code_area) ⇒ Object
helper for logging errors to the newrelic_agent.log properly. Logs the error at error level
157 158 159 160 161 |
# File 'lib/new_relic/agent/method_tracer.rb', line 157 def log_errors(code_area) yield rescue => e ::NewRelic::Agent.logger.error("Caught exception in #{code_area}.", e) end |
#metrics_for_current_transaction(first_name, other_names, options) ⇒ Object
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/new_relic/agent/method_tracer.rb', line 180 def metrics_for_current_transaction(first_name, other_names, ) metrics = [] if ![:scoped_metric_only] metrics += other_names.map { |n| NewRelic::MetricSpec.new(n) } end if [:metric] if ![:scoped_metric_only] metrics << NewRelic::MetricSpec.new(first_name) end if NewRelic::Agent::Transaction.in_transaction? && ![:transaction] metrics << NewRelic::MetricSpec.new(first_name, StatsEngine::MetricStats::SCOPE_PLACEHOLDER) end end metrics end |
#metrics_for_parent_transaction(first_name, options) ⇒ Object
203 204 205 206 207 208 209 |
# File 'lib/new_relic/agent/method_tracer.rb', line 203 def metrics_for_parent_transaction(first_name, ) if has_parent? && [:metric] && [:transaction] [NewRelic::MetricSpec.new(first_name, StatsEngine::MetricStats::SCOPE_PLACEHOLDER)] else [] end 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
151 152 153 |
# File 'lib/new_relic/agent/method_tracer.rb', line 151 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.
140 141 142 |
# File 'lib/new_relic/agent/method_tracer.rb', line 140 def push_flag!(forced) agent_instance.push_trace_execution_flag(true) if forced end |
#record_metrics(first_name, other_names, duration, exclusive, options) ⇒ Object
211 212 213 214 215 216 217 218 219 220 |
# File 'lib/new_relic/agent/method_tracer.rb', line 211 def record_metrics(first_name, other_names, duration, exclusive, ) metrics = metrics_for_current_transaction(first_name, other_names, ) stat_engine.record_metrics_internal(metrics, duration, exclusive) parent_metrics = metrics_for_parent_transaction(first_name, ) parent_metrics.each do |metric| parent_txn = NewRelic::Agent::Transaction.parent parent_txn.stats_hash.record(metric, duration, exclusive) end 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
131 132 133 |
# File 'lib/new_relic/agent/method_tracer.rb', line 131 def set_if_nil(hash, key) hash[key] = true if hash[key].nil? end |
#stat_engine ⇒ Object
Shorthand to return the current statistics engine
115 116 117 |
# File 'lib/new_relic/agent/method_tracer.rb', line 115 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
110 111 112 |
# File 'lib/new_relic/agent/method_tracer.rb', line 110 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.
251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/new_relic/agent/method_tracer.rb', line 251 def trace_execution_scoped(metric_names, ={}) return yield if trace_disabled?() set_if_nil(, :metric) set_if_nil(, :deduct_call_time_from_parent) metric_names = Array(metric_names) first_name = metric_names.shift start_time, expected_scope = trace_execution_scoped_header() begin yield ensure (start_time, first_name, metric_names, expected_scope, ) end end |
#trace_execution_scoped_footer(t0, first_name, metric_names, expected_scope, options, 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.
230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/new_relic/agent/method_tracer.rb', line 230 def (t0, first_name, metric_names, expected_scope, , t1=Time.now.to_f) log_errors("trace_method_execution footer") do pop_flag!([:force]) if expected_scope scope = stat_engine.pop_scope(expected_scope, first_name, t1) duration = t1 - t0 exclusive = duration - scope.children_time record_metrics(first_name, metric_names, duration, exclusive, ) end end end |
#trace_execution_scoped_header(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.
170 171 172 173 174 175 176 177 178 |
# File 'lib/new_relic/agent/method_tracer.rb', line 170 def trace_execution_scoped_header(, t0=Time.now.to_f) scope = log_errors("trace_execution_scoped header") do push_flag!([:force]) scope = stat_engine.push_scope(:method_tracer, 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
104 105 106 |
# File 'lib/new_relic/agent/method_tracer.rb', line 104 def traced? NewRelic::Agent.is_execution_traced? end |