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.
-
modelis the DB model class -
methodis 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 |