Module: NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScoped
- Extended by:
- 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
- #in_transaction? ⇒ 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
104 105 106 |
# File 'lib/new_relic/agent/method_tracer.rb', line 104 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
125 126 127 |
# File 'lib/new_relic/agent/method_tracer.rb', line 125 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
129 130 131 |
# File 'lib/new_relic/agent/method_tracer.rb', line 129 def get_stats_unscoped(name) stat_engine.get_stats_no_scope(name) end |
#has_parent? ⇒ Boolean
208 209 210 |
# File 'lib/new_relic/agent/method_tracer.rb', line 208 def has_parent? !NewRelic::Agent::Transaction.parent.nil? end |
#in_transaction? ⇒ Boolean
204 205 206 |
# File 'lib/new_relic/agent/method_tracer.rb', line 204 def in_transaction? NewRelic::Agent::Transaction.in_transaction? end |
#log_errors(code_area) ⇒ Object
helper for logging errors to the newrelic_agent.log properly. Logs the error at error level
162 163 164 165 166 |
# File 'lib/new_relic/agent/method_tracer.rb', line 162 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
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'lib/new_relic/agent/method_tracer.rb', line 185 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 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
212 213 214 215 216 217 218 |
# File 'lib/new_relic/agent/method_tracer.rb', line 212 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
156 157 158 |
# File 'lib/new_relic/agent/method_tracer.rb', line 156 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.
145 146 147 |
# File 'lib/new_relic/agent/method_tracer.rb', line 145 def push_flag!(forced) agent_instance.push_trace_execution_flag(true) if forced end |
#record_metrics(first_name, other_names, duration, exclusive, options) ⇒ Object
220 221 222 223 224 225 226 227 228 229 |
# File 'lib/new_relic/agent/method_tracer.rb', line 220 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
136 137 138 |
# File 'lib/new_relic/agent/method_tracer.rb', line 136 def set_if_nil(hash, key) hash[key] = true if hash[key].nil? end |
#stat_engine ⇒ Object
Shorthand to return the current statistics engine
120 121 122 |
# File 'lib/new_relic/agent/method_tracer.rb', line 120 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
115 116 117 |
# File 'lib/new_relic/agent/method_tracer.rb', line 115 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.
260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/new_relic/agent/method_tracer.rb', line 260 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.
239 240 241 242 243 244 245 246 247 248 249 |
# File 'lib/new_relic/agent/method_tracer.rb', line 239 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.
175 176 177 178 179 180 181 182 183 |
# File 'lib/new_relic/agent/method_tracer.rb', line 175 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
109 110 111 |
# File 'lib/new_relic/agent/method_tracer.rb', line 109 def traced? NewRelic::Agent.is_execution_traced? end |