Class: NewRelic::Agent::Instrumentation::MetricFrame
- Defined in:
- lib/new_relic/agent/instrumentation/metric_frame.rb
Overview
A struct holding the information required to measure a controller action. This is put on the thread local. Handles the issue of re-entrancy, or nested action calls.
This class is not part of the public API. Avoid making calls on it directly.
Constant Summary collapse
- @@java_classes_loaded =
false
Instance Attribute Summary collapse
-
#apdex_start ⇒ Object
Returns the value of attribute apdex_start.
-
#available_request ⇒ Object
Returns the value of attribute available_request.
-
#database_metric_name ⇒ Object
Returns the value of attribute database_metric_name.
-
#depth ⇒ Object
readonly
Returns the value of attribute depth.
-
#exception ⇒ Object
Returns the value of attribute exception.
-
#filtered_params ⇒ Object
Returns the value of attribute filtered_params.
-
#force_flag ⇒ Object
Returns the value of attribute force_flag.
-
#jruby_cpu_start ⇒ Object
Returns the value of attribute jruby_cpu_start.
-
#process_cpu_start ⇒ Object
Returns the value of attribute process_cpu_start.
-
#start ⇒ Object
Returns the value of attribute start.
Class Method Summary collapse
-
.abort_transaction! ⇒ Object
Indicate that you don’t want to keep the currently saved transaction information.
-
.current(create_if_empty = nil) ⇒ Object
Return the currently active metric frame, or nil.
-
.database_metric_name ⇒ Object
This is the name of the model currently assigned to database measurements, overriding the default.
-
.notice_error(e, custom_params = {}) ⇒ Object
If we have an active metric frame, notice the error and increment the error metric.
Instance Method Summary collapse
-
#abort_transaction! ⇒ Object
Call this to ensure that the current transaction is not saved.
- #category ⇒ Object
-
#initialize ⇒ MetricFrame
constructor
A new instance of MetricFrame.
- #metric_name ⇒ Object
- #notice_error(e, custom_params = {}) ⇒ Object
- #path ⇒ Object
- #pop ⇒ Object
-
#push(category, path) ⇒ Object
Indicate that we are entering a measured controller action or task.
- #record_apdex ⇒ Object
-
#recorded_metrics ⇒ Object
Return the array of metrics to record for the current metric frame.
-
#start_transaction ⇒ Object
This needs to be called after entering the call to trace the controller action, otherwise the controller action blames itself.
-
#with_database_metric_name(model, method) ⇒ Object
Yield to a block that is run with a database metric name context.
Constructor Details
#initialize ⇒ MetricFrame
Returns a new instance of MetricFrame.
38 39 40 41 42 43 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 38 def initialize @start = Time.now.to_f @path_stack = [] # stack of [controller, path] elements @jruby_cpu_start = jruby_cpu_time @process_cpu_start = process_cpu end |
Instance Attribute Details
#apdex_start ⇒ Object
Returns the value of attribute apdex_start.
8 9 10 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 8 def apdex_start @apdex_start end |
#available_request ⇒ Object
Returns the value of attribute available_request.
8 9 10 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 8 def available_request @available_request end |
#database_metric_name ⇒ Object
Returns the value of attribute database_metric_name.
8 9 10 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 8 def database_metric_name @database_metric_name end |
#depth ⇒ Object (readonly)
Returns the value of attribute depth.
36 37 38 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 36 def depth @depth end |
#exception ⇒ Object
Returns the value of attribute exception.
8 9 10 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 8 def exception @exception end |
#filtered_params ⇒ Object
Returns the value of attribute filtered_params.
8 9 10 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 8 def filtered_params @filtered_params end |
#force_flag ⇒ Object
Returns the value of attribute force_flag.
8 9 10 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 8 def force_flag @force_flag end |
#jruby_cpu_start ⇒ Object
Returns the value of attribute jruby_cpu_start.
8 9 10 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 8 def jruby_cpu_start @jruby_cpu_start end |
#process_cpu_start ⇒ Object
Returns the value of attribute process_cpu_start.
8 9 10 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 8 def process_cpu_start @process_cpu_start end |
#start ⇒ Object
Returns the value of attribute start.
8 9 10 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 8 def start @start end |
Class Method Details
.abort_transaction! ⇒ Object
Indicate that you don’t want to keep the currently saved transaction information
53 54 55 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 53 def self.abort_transaction! current.abort_transaction! if current end |
.current(create_if_empty = nil) ⇒ Object
Return the currently active metric frame, or nil. Call with true
to create a new metric frame if one is not already on the thread.
14 15 16 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 14 def self.current(create_if_empty=nil) Thread.current[:newrelic_metric_frame] ||= create_if_empty && new end |
.database_metric_name ⇒ Object
This is the name of the model currently assigned to database measurements, overriding the default.
20 21 22 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 20 def self.database_metric_name current && current.database_metric_name end |
.notice_error(e, custom_params = {}) ⇒ Object
If we have an active metric frame, notice the error and increment the error metric.
102 103 104 105 106 107 108 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 102 def self.notice_error(e, custom_params={}) if current current.notice_error(e, custom_params) else NewRelic::Agent.instance.error_collector.notice_error(e, nil, nil, custom_params) end end |
Instance Method Details
#abort_transaction! ⇒ Object
Call this to ensure that the current transaction is not saved
58 59 60 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 58 def abort_transaction! NewRelic::Agent.instance.transaction_sampler.ignore_transaction end |
#category ⇒ Object
71 72 73 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 71 def category @path_stack.last.first end |
#metric_name ⇒ Object
125 126 127 128 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 125 def metric_name return nil if @path_stack.empty? category + '/' + path end |
#notice_error(e, custom_params = {}) ⇒ Object
110 111 112 113 114 115 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 110 def notice_error(e, custom_params={}) if exception != e NewRelic::Agent.instance.error_collector.notice_error(e, nil, metric_name, filtered_params.merge(custom_params)) self.exception = e end end |
#path ⇒ Object
74 75 76 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 74 def path @path_stack.last.last end |
#pop ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 78 def pop category, path = @path_stack.pop if category.nil? NewRelic::Control.instance.log.error "Underflow in metric frames: #{caller.join("\n ")}" end # change the transaction name back to whatever was on the stack. if @path_stack.empty? Thread.current[:newrelic_metric_frame] = nil if NewRelic::Agent.is_execution_traced? cpu_burn = nil if @process_cpu_start cpu_burn = process_cpu - @process_cpu_start elsif @jruby_cpu_start cpu_burn = jruby_cpu_time - @jruby_cpu_start NewRelic::Agent.get_stats_no_scope(NewRelic::Metrics::USER_TIME).record_data_point(cpu_burn) end NewRelic::Agent.instance.transaction_sampler.notice_transaction_cpu_time(cpu_burn) if cpu_burn NewRelic::Agent.instance.histogram.process(Time.now.to_f - start) if recording_web_transaction?(category) end end NewRelic::Agent.instance.stats_engine.scope_name = metric_name end |
#push(category, path) ⇒ Object
Indicate that we are entering a measured controller action or task. Make sure you unwind every push with a pop call.
47 48 49 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 47 def push(category, path) @path_stack.push [category, path] end |
#record_apdex ⇒ Object
116 117 118 119 120 121 122 123 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 116 def record_apdex return unless recording_web_transaction? ending = Time.now.to_f summary_stat = NewRelic::Agent.instance.stats_engine.get_custom_stats("Apdex", NewRelic::ApdexStats) controller_stat = NewRelic::Agent.instance.stats_engine.get_custom_stats("Apdex/#{path}", NewRelic::ApdexStats) update_apdex(summary_stat, ending - apdex_start, exception) update_apdex(controller_stat, ending - start, exception) end |
#recorded_metrics ⇒ Object
Return the array of metrics to record for the current metric frame.
131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 131 def recorded_metrics metrics = [ metric_name ] if @path_stack.size == 1 if recording_web_transaction? metrics += ["Controller", "HttpDispatcher"] else metrics += ["#{category}/all", "OtherTransaction/all"] end end metrics end |
#start_transaction ⇒ Object
This needs to be called after entering the call to trace the controller action, otherwise the controller action blames itself. It gets reset in the normal #pop call.
63 64 65 66 67 68 69 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 63 def start_transaction NewRelic::Agent.instance.stats_engine.start_transaction metric_name # Only push the transaction context info once, on entry: if @path_stack.size == 1 NewRelic::Agent.instance.transaction_sampler.notice_transaction(metric_name, available_request, filtered_params) end end |
#with_database_metric_name(model, method) ⇒ Object
Yield to a block that is run with a database metric name context. This means the Database instrumentation will use this for the metric name if it does not otherwise know about a model. This is re-entrant.
-
model
is the DB model class -
method
is the name of the finder method or other method to identify the operation with.
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/new_relic/agent/instrumentation/metric_frame.rb', line 150 def with_database_metric_name(model, method) previous = @database_metric_name model_name = case model when Class model.name when String model else model.to_s end @database_metric_name = "ActiveRecord/#{model_name}/#{method}" yield ensure @database_metric_name=previous end |