Class: NewRelic::Agent::Transaction
- Inherits:
-
Object
- Object
- NewRelic::Agent::Transaction
show all
- Includes:
- Pop
- Defined in:
- lib/new_relic/agent/transaction.rb,
lib/new_relic/agent/transaction/pop.rb,
lib/new_relic/agent/transaction/xray_sample_buffer.rb,
lib/new_relic/agent/transaction/slowest_sample_buffer.rb,
lib/new_relic/agent/transaction/transaction_sample_buffer.rb,
lib/new_relic/agent/transaction/force_persist_sample_buffer.rb,
lib/new_relic/agent/transaction/developer_mode_sample_buffer.rb
Defined Under Namespace
Modules: Pop
Classes: DeveloperModeSampleBuffer, ForcePersistSampleBuffer, SlowestSampleBuffer, TransactionSampleBuffer, XraySampleBuffer
Constant Summary
collapse
- OVERVIEW_SPECS =
[
[:webDuration, MetricSpec.new('HttpDispatcher')],
[:queueDuration, MetricSpec.new('WebFrontend/QueueTime')],
[:externalDuration, MetricSpec.new('External/allWeb')],
[:databaseDuration, MetricSpec.new('ActiveRecord/all')],
[:gcCumulative, MetricSpec.new("GC/cumulative")],
[:memcacheDuration, MetricSpec.new('Memcache/allWeb')]
]
- APDEX_METRIC_SPEC =
NewRelic::MetricSpec.new('Apdex').freeze
- @@java_classes_loaded =
false
Instance Attribute Summary collapse
-
#apdex_start ⇒ Object
A Time instance used for calculating the apdex score, which.
-
#database_metric_name ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time.
-
#depth ⇒ Object
readonly
Returns the value of attribute depth.
-
#exceptions ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time.
-
#filtered_params ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time.
-
#force_flag ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time.
-
#jruby_cpu_start ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time.
-
#name ⇒ Object
Returns the value of attribute name.
-
#process_cpu_start ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time.
-
#request ⇒ Object
Give the current transaction a request context.
-
#start_time ⇒ Object
A Time instance for the start time, never nil.
-
#stats_hash ⇒ Object
readonly
Returns the value of attribute stats_hash.
-
#type ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time.
Class Method Summary
collapse
-
.abort_transaction! ⇒ Object
Indicate that you don’t want to keep the currently saved transaction information.
-
.add_custom_parameters(p) ⇒ Object
Add context parameters to the transaction.
-
.agent ⇒ Object
-
.apdex_bucket(duration, failed, apdex_t) ⇒ Object
-
.current ⇒ Object
Return the currently active transaction, or nil.
-
.custom_parameters ⇒ Object
-
.database_metric_name ⇒ Object
This is the name of the model currently assigned to database measurements, overriding the default.
-
.freeze_name ⇒ Object
-
.in_transaction? ⇒ Boolean
-
.notice_error(e, options = {}) ⇒ Object
If we have an active transaction, notice the error and increment the error metric.
-
.parent ⇒ Object
-
.record_apdex(end_time, is_error) ⇒ Object
-
.recording_web_transaction? ⇒ Boolean
Returns truthy if the current in-progress transaction is considered a a web transaction (as opposed to, e.g., a background transaction).
-
.referer ⇒ Object
-
.referer_from_request(request) ⇒ Object
Make a safe attempt to get the referer from a request object, generally successful when it’s a Rack request.
-
.set_user_attributes(attributes) ⇒ Object
-
.stack ⇒ Object
-
.start(transaction_type, options = {}) ⇒ Object
-
.stop(metric_name = nil, end_time = Time.now) ⇒ Object
-
.transaction_type_is_web?(type) ⇒ Boolean
-
.uri_from_request(request) ⇒ Object
Make a safe attempt to get the URI, without the host and query string.
-
.user_attributes ⇒ Object
Instance Method Summary
collapse
-
#abort_transaction! ⇒ Object
Call this to ensure that the current transaction is not saved.
-
#add_custom_parameters(p) ⇒ Object
-
#apdex_t ⇒ Object
-
#custom_parameters ⇒ Object
-
#freeze_name ⇒ Object
-
#has_parent? ⇒ Boolean
-
#initialize(type = :controller, options = {}) ⇒ Transaction
constructor
A new instance of Transaction.
-
#merge_stats_hash ⇒ Object
-
#name_frozen? ⇒ Boolean
-
#name_set? ⇒ Boolean
-
#notice_error(e, options = {}) ⇒ Object
-
#noticed_error_ids ⇒ Object
-
#parent ⇒ Object
-
#queue_time ⇒ Object
-
#record_apdex(end_time = Time.now, is_error = nil) ⇒ Object
-
#record_exceptions ⇒ Object
-
#recording_web_transaction? ⇒ Boolean
-
#referer ⇒ Object
For the current web transaction, return the full referer, minus the host string, or nil.
-
#root? ⇒ Boolean
-
#send_transaction_finished_event(start_time, end_time, overview_metrics) ⇒ Object
-
#set_user_attributes(attributes) ⇒ Object
-
#start(transaction_type) ⇒ Object
Indicate that we are entering a measured controller action or task.
-
#stop(fallback_name = ::NewRelic::Agent::UNKNOWN_METRIC, end_time = Time.now) ⇒ Object
-
#transaction_overview_metrics ⇒ Object
-
#transaction_specific_apdex_t ⇒ Object
-
#uri ⇒ Object
For the current web transaction, return the path of the URI minus the host part and query string, or nil.
-
#user_attributes ⇒ Object
-
#with_database_metric_name(model, method) ⇒ Object
Yield to a block that is run with a database metric name context.
Methods included from Pop
#cpu_burn, #current_stack_metric, #jruby_cpu_burn, #log_underflow, #normal_cpu_burn, #record_jruby_cpu_burn, #record_transaction_cpu, #traced?
Constructor Details
#initialize(type = :controller, options = {}) ⇒ Transaction
Returns a new instance of Transaction.
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/new_relic/agent/transaction.rb', line 96
def initialize(type=:controller, options={})
@type = type
@start_time = Time.now
@apdex_start = @start_time
@jruby_cpu_start = jruby_cpu_time
@process_cpu_start = process_cpu
@filtered_params = options[:filtered_params] || {}
@force_flag = options[:force]
@request = options[:request]
@exceptions = {}
@stats_hash = StatsHash.new
TransactionState.get.transaction = self
end
|
Instance Attribute Details
#apdex_start ⇒ Object
A Time instance used for calculating the apdex score, which
21
22
23
|
# File 'lib/new_relic/agent/transaction.rb', line 21
def apdex_start
@apdex_start
end
|
#database_metric_name ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time
24
25
26
|
# File 'lib/new_relic/agent/transaction.rb', line 24
def database_metric_name
@database_metric_name
end
|
#depth ⇒ Object
Returns the value of attribute depth.
94
95
96
|
# File 'lib/new_relic/agent/transaction.rb', line 94
def depth
@depth
end
|
#exceptions ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time
24
25
26
|
# File 'lib/new_relic/agent/transaction.rb', line 24
def exceptions
@exceptions
end
|
#filtered_params ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time
24
25
26
|
# File 'lib/new_relic/agent/transaction.rb', line 24
def filtered_params
@filtered_params
end
|
#force_flag ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time
24
25
26
|
# File 'lib/new_relic/agent/transaction.rb', line 24
def force_flag
@force_flag
end
|
#jruby_cpu_start ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time
24
25
26
|
# File 'lib/new_relic/agent/transaction.rb', line 24
def jruby_cpu_start
@jruby_cpu_start
end
|
#name ⇒ Object
Returns the value of attribute name.
26
27
28
|
# File 'lib/new_relic/agent/transaction.rb', line 26
def name
@name
end
|
#process_cpu_start ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time
24
25
26
|
# File 'lib/new_relic/agent/transaction.rb', line 24
def process_cpu_start
@process_cpu_start
end
|
#request ⇒ Object
Give the current transaction a request context. Use this to get the URI and referer. The request is interpreted loosely as a Rack::Request or an ActionController::AbstractRequest.
32
33
34
|
# File 'lib/new_relic/agent/transaction.rb', line 32
def request
@request
end
|
#start_time ⇒ Object
A Time instance for the start time, never nil
20
21
22
|
# File 'lib/new_relic/agent/transaction.rb', line 20
def start_time
@start_time
end
|
#stats_hash ⇒ Object
Returns the value of attribute stats_hash.
27
28
29
|
# File 'lib/new_relic/agent/transaction.rb', line 27
def stats_hash
@stats_hash
end
|
#type ⇒ Object
might end up being @start, or it might be further upstream if we can find a request header for the queue entry time
24
25
26
|
# File 'lib/new_relic/agent/transaction.rb', line 24
def type
@type
end
|
Class Method Details
.abort_transaction! ⇒ Object
Indicate that you don’t want to keep the currently saved transaction information
164
165
166
|
# File 'lib/new_relic/agent/transaction.rb', line 164
def self.abort_transaction!
current.abort_transaction! if current
end
|
.add_custom_parameters(p) ⇒ Object
Add context parameters to the transaction. This information will be passed in to errors and transaction traces. Keys and Values should be strings, numbers or date/times.
292
293
294
|
# File 'lib/new_relic/agent/transaction.rb', line 292
def self.add_custom_parameters(p)
current.add_custom_parameters(p) if current
end
|
.agent ⇒ Object
74
75
76
|
# File 'lib/new_relic/agent/transaction.rb', line 74
def self.agent
NewRelic::Agent.instance
end
|
.apdex_bucket(duration, failed, apdex_t) ⇒ Object
418
419
420
421
422
423
424
425
426
427
428
429
|
# File 'lib/new_relic/agent/transaction.rb', line 418
def self.apdex_bucket(duration, failed, apdex_t)
case
when failed
:apdex_f
when duration <= apdex_t
:apdex_s
when duration <= 4 * apdex_t
:apdex_t
else
:apdex_f
end
end
|
.current ⇒ Object
Return the currently active transaction, or nil.
35
36
37
|
# File 'lib/new_relic/agent/transaction.rb', line 35
def self.current
self.stack.last
end
|
.custom_parameters ⇒ Object
296
297
298
|
# File 'lib/new_relic/agent/transaction.rb', line 296
def self.custom_parameters
(current && current.custom_parameters) ? current.custom_parameters : {}
end
|
.database_metric_name ⇒ Object
This is the name of the model currently assigned to database measurements, overriding the default.
66
67
68
|
# File 'lib/new_relic/agent/transaction.rb', line 66
def self.database_metric_name
current && current.database_metric_name
end
|
.freeze_name ⇒ Object
78
79
80
|
# File 'lib/new_relic/agent/transaction.rb', line 78
def self.freeze_name
self.current && self.current.freeze_name
end
|
.in_transaction? ⇒ Boolean
60
61
62
|
# File 'lib/new_relic/agent/transaction.rb', line 60
def self.in_transaction?
!self.stack.empty?
end
|
.notice_error(e, options = {}) ⇒ Object
If we have an active transaction, notice the error and increment the error metric. Options:
-
:request
=> Request object to get the uri and referer
-
:uri
=> The request path, minus any request params or query string.
-
:referer
=> The URI of the referer
-
:metric
=> The metric name associated with the transaction
-
:request_params
=> Request parameters, already filtered if necessary
-
:custom_params
=> Custom parameters
Anything left over is treated as custom params
265
266
267
268
269
270
271
272
273
274
275
276
|
# File 'lib/new_relic/agent/transaction.rb', line 265
def self.notice_error(e, options={})
request = options.delete(:request)
if request
options[:referer] = referer_from_request(request)
options[:uri] = uri_from_request(request)
end
if current
current.notice_error(e, options)
else
agent.error_collector.notice_error(e, options)
end
end
|
.parent ⇒ Object
39
40
41
|
# File 'lib/new_relic/agent/transaction.rb', line 39
def self.parent
self.stack[-2]
end
|
.record_apdex(end_time, is_error) ⇒ Object
414
415
416
|
# File 'lib/new_relic/agent/transaction.rb', line 414
def self.record_apdex(end_time, is_error)
current && current.record_apdex(end_time, is_error)
end
|
.recording_web_transaction? ⇒ Boolean
Returns truthy if the current in-progress transaction is considered a a web transaction (as opposed to, e.g., a background transaction).
380
381
382
|
# File 'lib/new_relic/agent/transaction.rb', line 380
def self.recording_web_transaction?
self.current && self.current.recording_web_transaction?
end
|
.referer ⇒ Object
70
71
72
|
# File 'lib/new_relic/agent/transaction.rb', line 70
def self.referer
current && current.referer
end
|
.referer_from_request(request) ⇒ Object
Make a safe attempt to get the referer from a request object, generally successful when it’s a Rack request.
394
395
396
397
398
|
# File 'lib/new_relic/agent/transaction.rb', line 394
def self.referer_from_request(request)
if request && request.respond_to?(:referer)
request.referer.to_s.split('?').first
end
end
|
.set_user_attributes(attributes) ⇒ Object
300
301
302
|
# File 'lib/new_relic/agent/transaction.rb', line 300
def self.set_user_attributes(attributes)
current.set_user_attributes(attributes) if current
end
|
.stack ⇒ Object
56
57
58
|
# File 'lib/new_relic/agent/transaction.rb', line 56
def self.stack
TransactionState.get.current_transaction_stack
end
|
.start(transaction_type, options = {}) ⇒ Object
43
44
45
46
47
48
|
# File 'lib/new_relic/agent/transaction.rb', line 43
def self.start(transaction_type, options={})
txn = Transaction.new(transaction_type, options)
txn.start(transaction_type)
self.stack.push(txn)
return txn
end
|
.stop(metric_name = nil, end_time = Time.now) ⇒ Object
50
51
52
53
54
|
# File 'lib/new_relic/agent/transaction.rb', line 50
def self.stop(metric_name=nil, end_time=Time.now)
txn = self.stack.last
txn.stop(metric_name, end_time) if txn
return self.stack.pop
end
|
.transaction_type_is_web?(type) ⇒ Boolean
384
385
386
|
# File 'lib/new_relic/agent/transaction.rb', line 384
def self.transaction_type_is_web?(type)
[:controller, :uri, :rack, :sinatra].include?(type)
end
|
.uri_from_request(request) ⇒ Object
Make a safe attempt to get the URI, without the host and query string.
401
402
403
404
405
406
407
408
409
410
|
# File 'lib/new_relic/agent/transaction.rb', line 401
def self.uri_from_request(request)
approximate_uri = case
when request.respond_to?(:fullpath) then request.fullpath
when request.respond_to?(:path) then request.path
when request.respond_to?(:request_uri) then request.request_uri
when request.respond_to?(:uri) then request.uri
when request.respond_to?(:url) then request.url
end
return approximate_uri[%r{^(https?://.*?)?(/[^?]*)}, 2] || '/' if approximate_uri end
|
.user_attributes ⇒ Object
304
305
306
|
# File 'lib/new_relic/agent/transaction.rb', line 304
def self.user_attributes
(current) ? current.user_attributes : {}
end
|
Instance Method Details
#abort_transaction! ⇒ Object
Call this to ensure that the current transaction is not saved
179
180
181
|
# File 'lib/new_relic/agent/transaction.rb', line 179
def abort_transaction!
transaction_sampler.ignore_transaction
end
|
#add_custom_parameters(p) ⇒ Object
370
371
372
|
# File 'lib/new_relic/agent/transaction.rb', line 370
def add_custom_parameters(p)
custom_parameters.merge!(p)
end
|
#apdex_t ⇒ Object
326
327
328
|
# File 'lib/new_relic/agent/transaction.rb', line 326
def apdex_t
transaction_specific_apdex_t || Agent.config[:apdex_t]
end
|
#custom_parameters ⇒ Object
358
359
360
|
# File 'lib/new_relic/agent/transaction.rb', line 358
def custom_parameters
@custom_parameters ||= {}
end
|
#freeze_name ⇒ Object
126
127
128
129
130
|
# File 'lib/new_relic/agent/transaction.rb', line 126
def freeze_name
return if name_frozen?
@name = NewRelic::Agent.instance.transaction_rules.rename(@name)
@name_frozen = true
end
|
#has_parent? ⇒ Boolean
144
145
146
|
# File 'lib/new_relic/agent/transaction.rb', line 144
def has_parent?
self.class.stack.size > 1
end
|
#merge_stats_hash ⇒ Object
225
226
227
228
|
# File 'lib/new_relic/agent/transaction.rb', line 225
def merge_stats_hash
stats_hash.resolve_scopes!(@name)
NewRelic::Agent.instance.stats_engine.merge!(stats_hash)
end
|
#name_frozen? ⇒ Boolean
132
133
134
|
# File 'lib/new_relic/agent/transaction.rb', line 132
def name_frozen?
@name_frozen
end
|
#notice_error(e, options = {}) ⇒ Object
Do not call this. Invoke the class method instead.
279
280
281
282
283
284
285
286
287
288
|
# File 'lib/new_relic/agent/transaction.rb', line 279
def notice_error(e, options={}) params = custom_parameters
options[:referer] = referer if referer
options[:request_params] = filtered_params if filtered_params
options[:uri] = uri if uri
options.merge!(custom_parameters)
if !@exceptions.keys.include?(e)
@exceptions[e] = options
end
end
|
#noticed_error_ids ⇒ Object
110
111
112
|
# File 'lib/new_relic/agent/transaction.rb', line 110
def noticed_error_ids
@noticed_error_ids ||= []
end
|
#parent ⇒ Object
136
137
138
|
# File 'lib/new_relic/agent/transaction.rb', line 136
def parent
has_parent? && self.class.stack[-2]
end
|
#queue_time ⇒ Object
366
367
368
|
# File 'lib/new_relic/agent/transaction.rb', line 366
def queue_time
@apdex_start ? @start_time - @apdex_start : 0
end
|
#record_apdex(end_time = Time.now, is_error = nil) ⇒ Object
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
|
# File 'lib/new_relic/agent/transaction.rb', line 310
def record_apdex(end_time=Time.now, is_error=nil)
return unless recording_web_transaction? && NewRelic::Agent.is_execution_traced?
freeze_name
action_duration = end_time - start_time
total_duration = end_time - apdex_start
is_error = is_error.nil? ? !exceptions.empty? : is_error
apdex_bucket_global = self.class.apdex_bucket(total_duration, is_error, apdex_t)
apdex_bucket_txn = self.class.apdex_bucket(action_duration, is_error, apdex_t)
@stats_hash.record(APDEX_METRIC_SPEC, apdex_bucket_global, apdex_t)
txn_apdex_metric = NewRelic::MetricSpec.new(@name.gsub(/^[^\/]+\//, 'Apdex/'))
@stats_hash.record(txn_apdex_metric, apdex_bucket_txn, apdex_t)
end
|
#record_exceptions ⇒ Object
230
231
232
233
234
235
|
# File 'lib/new_relic/agent/transaction.rb', line 230
def record_exceptions
@exceptions.each do |exception, options|
options[:metric] = @name
agent.error_collector.notice_error(exception, options)
end
end
|
#recording_web_transaction? ⇒ Boolean
388
389
390
|
# File 'lib/new_relic/agent/transaction.rb', line 388
def recording_web_transaction?
self.class.transaction_type_is_web?(@type)
end
|
#referer ⇒ Object
For the current web transaction, return the full referer, minus the host string, or nil.
174
175
176
|
# File 'lib/new_relic/agent/transaction.rb', line 174
def referer
@referer ||= self.class.referer_from_request(@request)
end
|
#root? ⇒ Boolean
140
141
142
|
# File 'lib/new_relic/agent/transaction.rb', line 140
def root?
self.class.stack.size == 1
end
|
#send_transaction_finished_event(start_time, end_time, overview_metrics) ⇒ Object
214
215
216
217
218
219
220
221
222
223
|
# File 'lib/new_relic/agent/transaction.rb', line 214
def send_transaction_finished_event(start_time, end_time, overview_metrics)
payload = {
:name => @name,
:type => @type,
:start_timestamp => start_time.to_f,
:duration => end_time.to_f - start_time.to_f,
:overview_metrics => overview_metrics
}
agent.events.notify(:transaction_finished, payload)
end
|
#set_user_attributes(attributes) ⇒ Object
374
375
376
|
# File 'lib/new_relic/agent/transaction.rb', line 374
def set_user_attributes(attributes)
user_attributes.merge!(attributes)
end
|
#start(transaction_type) ⇒ Object
Indicate that we are entering a measured controller action or task. Make sure you unwind every push with a pop call.
150
151
152
153
154
155
156
157
158
159
160
|
# File 'lib/new_relic/agent/transaction.rb', line 150
def start(transaction_type)
@name = NewRelic::Agent::UNKNOWN_METRIC
transaction_sampler.notice_first_scope_push(start_time)
sql_sampler.notice_first_scope_push(start_time)
NewRelic::Agent::StatsEngine::GCProfiler.init
agent.stats_engine.start_transaction
transaction_sampler.notice_transaction(uri, filtered_params)
sql_sampler.notice_transaction(uri, filtered_params)
end
|
#stop(fallback_name = ::NewRelic::Agent::UNKNOWN_METRIC, end_time = Time.now) ⇒ Object
Unwind one stack level. It knows if it’s back at the outermost caller and does the appropriate wrapup of the context.
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
# File 'lib/new_relic/agent/transaction.rb', line 186
def stop(fallback_name=::NewRelic::Agent::UNKNOWN_METRIC, end_time=Time.now)
@name = fallback_name unless name_set? || name_frozen?
freeze_name
log_underflow if @type.nil?
if self.root?
if traced?
record_transaction_cpu
gc_time = NewRelic::Agent::StatsEngine::GCProfiler.capture
end
@transaction_trace = transaction_sampler.notice_scope_empty(self, Time.now, gc_time)
sql_sampler.notice_scope_empty(@name)
overview_metrics = transaction_overview_metrics
end
record_exceptions
merge_stats_hash
if self.root?
send_transaction_finished_event(start_time, end_time, overview_metrics)
agent.stats_engine.end_transaction
end
end
|
#transaction_overview_metrics ⇒ Object
246
247
248
249
250
251
252
253
|
# File 'lib/new_relic/agent/transaction.rb', line 246
def transaction_overview_metrics
metrics = {}
stats = @stats_hash
OVERVIEW_SPECS.each do |(dest_key, spec)|
metrics[dest_key] = stats[spec].total_call_time if stats.key?(spec)
end
metrics
end
|
#transaction_specific_apdex_t ⇒ Object
330
331
332
333
|
# File 'lib/new_relic/agent/transaction.rb', line 330
def transaction_specific_apdex_t
key = :web_transactions_apdex
Agent.config[key] && Agent.config[key][self.name]
end
|
#uri ⇒ Object
For the current web transaction, return the path of the URI minus the host part and query string, or nil.
169
170
171
|
# File 'lib/new_relic/agent/transaction.rb', line 169
def uri
@uri ||= self.class.uri_from_request(@request) unless @request.nil?
end
|
#user_attributes ⇒ Object
362
363
364
|
# File 'lib/new_relic/agent/transaction.rb', line 362
def user_attributes
@user_atrributes ||= {}
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.
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
|
# File 'lib/new_relic/agent/transaction.rb', line 342
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
|