newrelic_rpm 3.6.2.96 → 3.6.3.103.beta
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/CHANGELOG +33 -1
- data/README.md +7 -7
- data/lib/new_relic/agent/agent.rb +51 -22
- data/lib/new_relic/agent/agent_logger.rb +22 -11
- data/lib/new_relic/agent/configuration/defaults.rb +6 -1
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +1 -6
- data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record.rb +8 -48
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +9 -1
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +4 -3
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +4 -4
- data/lib/new_relic/agent/instrumentation/metric_frame.rb +10 -8
- data/lib/new_relic/agent/instrumentation/padrino.rb +32 -0
- data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +52 -0
- data/lib/new_relic/agent/instrumentation/sinatra/transaction_namer.rb +56 -0
- data/lib/new_relic/agent/instrumentation/sinatra.rb +113 -48
- data/lib/new_relic/agent/new_relic_service.rb +6 -0
- data/lib/new_relic/agent/pipe_channel_manager.rb +13 -8
- data/lib/new_relic/agent/request_sampler.rb +205 -0
- data/lib/new_relic/agent/sampler.rb +0 -1
- data/lib/new_relic/agent/stats_engine/samplers.rb +0 -1
- data/lib/new_relic/agent/stats_engine/transactions.rb +12 -16
- data/lib/new_relic/agent/transaction.rb +27 -4
- data/lib/new_relic/agent/transaction_sample_builder.rb +47 -6
- data/lib/new_relic/agent/transaction_sampler.rb +0 -5
- data/lib/new_relic/agent.rb +17 -0
- data/lib/new_relic/build.rb +2 -2
- data/lib/new_relic/coerce.rb +3 -1
- data/lib/new_relic/rack/agent_hooks.rb +17 -3
- data/lib/new_relic/rack/browser_monitoring.rb +8 -3
- data/lib/new_relic/rack/error_collector.rb +2 -0
- data/lib/new_relic/transaction_sample/segment.rb +0 -23
- data/lib/new_relic/transaction_sample.rb +0 -9
- data/lib/new_relic/version.rb +1 -1
- data/test/agent_helper.rb +204 -0
- data/test/config/newrelic.yml +0 -1
- data/test/config/test_control.rb +3 -1
- data/test/multiverse/suites/agent_only/key_transactions_test.rb +8 -5
- data/test/multiverse/suites/agent_only/logging_test.rb +1 -1
- data/test/multiverse/suites/agent_only/thread_profiling_test.rb +7 -8
- data/test/multiverse/suites/datamapper/Envfile +7 -0
- data/test/multiverse/suites/datamapper/datamapper_test.rb +105 -0
- data/test/multiverse/suites/padrino/Envfile +16 -0
- data/test/multiverse/suites/padrino/config/newrelic.yml +24 -0
- data/test/multiverse/suites/padrino/padrino_test.rb +54 -0
- data/test/multiverse/suites/rails/Envfile +5 -5
- data/test/multiverse/suites/rails/app.rb +1 -0
- data/test/multiverse/suites/rails/request_statistics_test.rb +118 -0
- data/test/multiverse/suites/sinatra/Envfile +8 -2
- data/test/multiverse/suites/sinatra/ignoring_test.rb +185 -0
- data/test/multiverse/suites/sinatra/sinatra_classic_test.rb +92 -0
- data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +0 -3
- data/test/multiverse/suites/sinatra/sinatra_modular_test.rb +89 -0
- data/test/multiverse/suites/sinatra/sinatra_test_cases.rb +120 -0
- data/test/new_relic/agent/agent_logger_test.rb +149 -56
- data/test/new_relic/agent/agent_test.rb +23 -0
- data/test/new_relic/agent/agent_test_controller_test.rb +8 -1
- data/test/new_relic/agent/autostart_test.rb +10 -6
- data/test/new_relic/agent/instrumentation/action_controller_subscriber_test.rb +36 -31
- data/test/new_relic/agent/instrumentation/action_view_subscriber_test.rb +7 -0
- data/test/new_relic/agent/instrumentation/active_record_helper_test.rb +20 -4
- data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +20 -9
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +23 -19
- data/test/new_relic/agent/instrumentation/sequel_test.rb +118 -79
- data/test/new_relic/agent/instrumentation/sinatra/transaction_namer_test.rb +55 -0
- data/test/new_relic/agent/instrumentation/sinatra_test.rb +60 -11
- data/test/new_relic/agent/method_tracer_test.rb +7 -4
- data/test/new_relic/agent/new_relic_service_test.rb +6 -0
- data/test/new_relic/agent/pipe_channel_manager_test.rb +6 -2
- data/test/new_relic/agent/request_sampler_test.rb +159 -0
- data/test/new_relic/agent/stats_engine/samplers_test.rb +1 -5
- data/test/new_relic/agent/stats_engine_test.rb +14 -0
- data/test/new_relic/agent/transaction_sample_builder_test.rb +43 -6
- data/test/new_relic/agent/transaction_sampler_test.rb +31 -1
- data/test/new_relic/agent/transaction_test.rb +29 -0
- data/test/new_relic/agent_test.rb +7 -0
- data/test/new_relic/coerce_test.rb +13 -0
- data/test/new_relic/fake_collector.rb +31 -1
- data/test/new_relic/metric_spec_test.rb +14 -10
- data/test/new_relic/rack/agent_hooks_test.rb +9 -2
- data/test/new_relic/rack/browser_monitoring_test.rb +16 -7
- data/test/new_relic/rack/developer_mode_test.rb +7 -0
- data/test/new_relic/rack/error_collector_test.rb +10 -6
- data/test/new_relic/transaction_sample/segment_test.rb +0 -61
- data/test/new_relic/transaction_sample_subtest_test.rb +0 -19
- data/test/script/ci.sh +14 -0
- data/test/test_helper.rb +79 -203
- data.tar.gz.sig +0 -0
- metadata +50 -18
- metadata.gz.sig +0 -0
- data/test/multiverse/suites/datamapper/encoding_test.rb +0 -40
- data/test/multiverse/suites/sinatra/sinatra_test.rb +0 -143
data/.gitignore
CHANGED
data/CHANGELOG
CHANGED
@@ -1,6 +1,38 @@
|
|
1
|
-
|
2
1
|
# New Relic Ruby Agent Release Notes #
|
3
2
|
|
3
|
+
## 3.6.3 ##
|
4
|
+
|
5
|
+
* Better Sinatra Support
|
6
|
+
|
7
|
+
A number of improvements have been made to our Sinatra instrumentation.
|
8
|
+
More details: https://newrelic.com/docs/ruby/sinatra-support-in-the-ruby-agent
|
9
|
+
|
10
|
+
Sinatra instrumentation has been updated to more accurately reflect the final
|
11
|
+
route that was actually executed, taking pass and conditions into account.
|
12
|
+
|
13
|
+
New Relic middlewares for error collection, real user monitoring, and cross
|
14
|
+
application tracing are automatically inserted into the middleware stack.
|
15
|
+
|
16
|
+
Ignoring routes, similar to functionality available to Rails controllers, is
|
17
|
+
now available in Sinatra as well.
|
18
|
+
|
19
|
+
Routes in 1.4 are properly formatting in transaction names. Thanks Zachary
|
20
|
+
Anker for the contribution!
|
21
|
+
|
22
|
+
* Padrino Support
|
23
|
+
|
24
|
+
Along with improving our support of Sinatra, we've also extended that to
|
25
|
+
supporting Padrino, a framework that builds on Sinatra. Web transactions
|
26
|
+
should show up in New Relic now for Padrino apps automatically. The agent has
|
27
|
+
been tested against the latest Padrino in versions 0.11.x and 0.10.x.
|
28
|
+
|
29
|
+
* Main overview graph only shows web transactions
|
30
|
+
|
31
|
+
In the past database times from background jobs mixed with other web transaction
|
32
|
+
metrics in the main overview graph. This often skewed graphs. A common workaround
|
33
|
+
was to send background jobs to a separate application, but that should no longer
|
34
|
+
be necessary as the overview graphs now only represent web transactions.
|
35
|
+
|
4
36
|
## v3.6.2 ##
|
5
37
|
|
6
38
|
* Sequel support
|
data/README.md
CHANGED
@@ -176,17 +176,17 @@ online. Refer to instructions in *Getting Started*.
|
|
176
176
|
|
177
177
|
## Support
|
178
178
|
|
179
|
-
|
180
|
-
[
|
181
|
-
|
182
|
-
|
179
|
+
You can find more detailed documentation [on our website](http://newrelic.com/docs),
|
180
|
+
and specifically in the [Ruby category](http://newrelic.com/docs/ruby).
|
181
|
+
|
182
|
+
If you can't find what you're looking for there, reach out to us on our [support
|
183
|
+
site](http://support.newrelic.com/) and we'll be happy to help you.
|
183
184
|
|
184
185
|
Also available is community support on IRC: we generally use #newrelic
|
185
186
|
on irc.freenode.net
|
186
187
|
|
187
|
-
Find a bug?
|
188
|
-
|
189
|
-
[support.newrelic.com](http://support.newrelic.com/).
|
188
|
+
Find a bug? Contact us via [support.newrelic.com](http://support.newrelic.com/),
|
189
|
+
or e-mail support @ newrelic.com.
|
190
190
|
|
191
191
|
Thank you, and may your application scale to infinity plus one.
|
192
192
|
|
@@ -16,6 +16,7 @@ require 'new_relic/agent/database'
|
|
16
16
|
require 'new_relic/agent/thread_profiler'
|
17
17
|
require 'new_relic/agent/event_listener'
|
18
18
|
require 'new_relic/agent/cross_app_monitor'
|
19
|
+
require 'new_relic/agent/request_sampler'
|
19
20
|
require 'new_relic/environment_report'
|
20
21
|
|
21
22
|
module NewRelic
|
@@ -40,6 +41,7 @@ module NewRelic
|
|
40
41
|
@error_collector = NewRelic::Agent::ErrorCollector.new
|
41
42
|
@transaction_rules = NewRelic::Agent::RulesEngine.new
|
42
43
|
@metric_rules = NewRelic::Agent::RulesEngine.new
|
44
|
+
@request_sampler = NewRelic::Agent::RequestSampler.new(@events)
|
43
45
|
|
44
46
|
@connect_state = :pending
|
45
47
|
@connect_attempts = 0
|
@@ -51,17 +53,6 @@ module NewRelic
|
|
51
53
|
if Agent.config[:monitor_mode]
|
52
54
|
@service = NewRelic::Agent::NewRelicService.new
|
53
55
|
end
|
54
|
-
|
55
|
-
txn_tracer_enabler = Proc.new do
|
56
|
-
if NewRelic::Agent.config[:'transaction_tracer.enabled'] ||
|
57
|
-
NewRelic::Agent.config[:developer_mode]
|
58
|
-
@stats_engine.transaction_sampler = @transaction_sampler
|
59
|
-
else
|
60
|
-
@stats_engine.transaction_sampler = nil
|
61
|
-
end
|
62
|
-
end
|
63
|
-
Agent.config.register_callback(:'transaction_tracer.enabled', &txn_tracer_enabler)
|
64
|
-
Agent.config.register_callback(:developer_mode, &txn_tracer_enabler)
|
65
56
|
end
|
66
57
|
|
67
58
|
# contains all the class-level methods for NewRelic::Agent::Agent
|
@@ -204,6 +195,8 @@ module NewRelic
|
|
204
195
|
|
205
196
|
::NewRelic::Agent.logger.debug "Starting the worker thread in #{$$} after forking."
|
206
197
|
|
198
|
+
reset_objects_with_locks
|
199
|
+
|
207
200
|
# Clear out stats that are left over from parent process
|
208
201
|
reset_stats
|
209
202
|
|
@@ -324,7 +317,7 @@ module NewRelic
|
|
324
317
|
def log_startup
|
325
318
|
log_environment
|
326
319
|
log_dispatcher
|
327
|
-
|
320
|
+
log_app_name
|
328
321
|
end
|
329
322
|
|
330
323
|
# Log the environment the app thinks it's running in.
|
@@ -342,14 +335,14 @@ module NewRelic
|
|
342
335
|
::NewRelic::Agent.logger.info "Dispatcher: #{dispatcher_name}"
|
343
336
|
end
|
344
337
|
|
338
|
+
def log_app_name
|
339
|
+
::NewRelic::Agent.logger.info "Application: #{Agent.config.app_names.join(", ")}"
|
340
|
+
end
|
341
|
+
|
345
342
|
# Logs the configured application names
|
346
|
-
def
|
343
|
+
def app_name_configured?
|
347
344
|
names = Agent.config.app_names
|
348
|
-
|
349
|
-
::NewRelic::Agent.logger.info "Application: #{names.join(", ")}"
|
350
|
-
else
|
351
|
-
::NewRelic::Agent.logger.error 'Unable to determine application name. Please set the application name in your newrelic.yml or in a NEW_RELIC_APP_NAME environment variable.'
|
352
|
-
end
|
345
|
+
return names.respond_to?(:any?) && names.any?
|
353
346
|
end
|
354
347
|
|
355
348
|
# Connecting in the foreground blocks further startup of the
|
@@ -476,15 +469,32 @@ module NewRelic
|
|
476
469
|
|
477
470
|
include Start
|
478
471
|
|
479
|
-
|
480
|
-
|
481
|
-
|
472
|
+
|
473
|
+
# Check to see if the agent should start, returning +true+ if it should.
|
474
|
+
def agent_should_start?
|
475
|
+
return false if already_started? || disabled?
|
482
476
|
|
483
477
|
if defer_for_resque?
|
484
478
|
::NewRelic::Agent.logger.debug "Deferring startup for Resque in case it daemonizes"
|
485
|
-
return
|
479
|
+
return false
|
486
480
|
end
|
487
481
|
|
482
|
+
unless app_name_configured?
|
483
|
+
NewRelic::Agent.logger.error "No application name configured.",
|
484
|
+
"The Agent cannot start without at least one. Please check your ",
|
485
|
+
"newrelic.yml and ensure that it is valid and has at least one ",
|
486
|
+
"value set for app_name in the #{NewRelic::Control.instance.env} ",
|
487
|
+
"environment."
|
488
|
+
return false
|
489
|
+
end
|
490
|
+
|
491
|
+
return true
|
492
|
+
end
|
493
|
+
|
494
|
+
# Logs a bunch of data and starts the agent, if needed
|
495
|
+
def start
|
496
|
+
return unless agent_should_start?
|
497
|
+
|
488
498
|
@started = true
|
489
499
|
@local_host = determine_host
|
490
500
|
log_startup
|
@@ -503,6 +513,13 @@ module NewRelic
|
|
503
513
|
@launch_time = Time.now
|
504
514
|
end
|
505
515
|
|
516
|
+
# Clear out state for any objects that we know lock from our parents
|
517
|
+
# This is necessary for cases where we're in a forked child and Ruby
|
518
|
+
# might be holding locks for background thread that aren't there anymore.
|
519
|
+
def reset_objects_with_locks
|
520
|
+
@stats_engine = NewRelic::Agent::StatsEngine.new
|
521
|
+
end
|
522
|
+
|
506
523
|
def add_harvest_sampler(subclass)
|
507
524
|
begin
|
508
525
|
::NewRelic::Agent.logger.debug "#{subclass.name} not supported on this platform." and return unless subclass.supported_on_this_platform?
|
@@ -1013,6 +1030,17 @@ module NewRelic
|
|
1013
1030
|
end
|
1014
1031
|
end
|
1015
1032
|
|
1033
|
+
# Fetch samples from the RequestSampler and send them.
|
1034
|
+
def harvest_and_send_analytic_event_data
|
1035
|
+
samples = @request_sampler.samples
|
1036
|
+
@service.analytic_event_data(samples) unless samples.empty?
|
1037
|
+
@request_sampler.reset
|
1038
|
+
rescue => e
|
1039
|
+
NewRelic::Agent.logger.debug "Failed to sent analytics; throttling to conserve memory"
|
1040
|
+
@request_sampler.throttle
|
1041
|
+
raise
|
1042
|
+
end
|
1043
|
+
|
1016
1044
|
def check_for_agent_commands
|
1017
1045
|
commands = @service.get_agent_commands
|
1018
1046
|
::NewRelic::Agent.logger.debug "Received get_agent_commands = #{commands.inspect}"
|
@@ -1031,6 +1059,7 @@ module NewRelic
|
|
1031
1059
|
harvest_and_send_slowest_sample
|
1032
1060
|
harvest_and_send_slowest_sql
|
1033
1061
|
harvest_and_send_timeslice_data
|
1062
|
+
harvest_and_send_analytic_event_data
|
1034
1063
|
harvest_and_send_thread_profile(disconnecting)
|
1035
1064
|
|
1036
1065
|
check_for_agent_commands
|
@@ -16,24 +16,25 @@ module NewRelic
|
|
16
16
|
gather_startup_logs
|
17
17
|
end
|
18
18
|
|
19
|
+
|
19
20
|
def fatal(*msgs)
|
20
|
-
|
21
|
+
format_and_send(:fatal, msgs)
|
21
22
|
end
|
22
23
|
|
23
24
|
def error(*msgs)
|
24
|
-
|
25
|
+
format_and_send(:error, msgs)
|
25
26
|
end
|
26
27
|
|
27
28
|
def warn(*msgs)
|
28
|
-
|
29
|
+
format_and_send(:warn, msgs)
|
29
30
|
end
|
30
31
|
|
31
32
|
def info(*msgs)
|
32
|
-
|
33
|
+
format_and_send(:info, msgs)
|
33
34
|
end
|
34
35
|
|
35
36
|
def debug(*msgs)
|
36
|
-
|
37
|
+
format_and_send(:debug, msgs)
|
37
38
|
end
|
38
39
|
|
39
40
|
def is_startup_logger?
|
@@ -41,14 +42,24 @@ module NewRelic
|
|
41
42
|
end
|
42
43
|
|
43
44
|
# Allows for passing exceptions in explicitly, which format with backtrace
|
44
|
-
def
|
45
|
-
msgs.
|
46
|
-
|
47
|
-
|
45
|
+
def format_and_send(level, *msgs)
|
46
|
+
msgs.flatten!
|
47
|
+
exceptions = msgs.find_all {|m| m.is_a?(Exception) }
|
48
|
+
msgs.collect! do |msg|
|
49
|
+
if msg.respond_to?(:message)
|
50
|
+
"%p: %s" % [ msg.class, msg.message ]
|
48
51
|
else
|
49
|
-
msg
|
52
|
+
msg.to_s
|
50
53
|
end
|
51
|
-
end
|
54
|
+
end
|
55
|
+
|
56
|
+
msgs.each do |msg|
|
57
|
+
@log.send level, msg
|
58
|
+
end
|
59
|
+
|
60
|
+
exceptions.each do |ex|
|
61
|
+
@log.debug { "Debugging backtrace:\n " + ex.backtrace.join("\n ") }
|
62
|
+
end
|
52
63
|
end
|
53
64
|
|
54
65
|
def create_log(config, root, override_logger)
|
@@ -99,6 +99,8 @@ module NewRelic
|
|
99
99
|
:disable_samplers => false,
|
100
100
|
:disable_resque => false,
|
101
101
|
:disable_dj => false,
|
102
|
+
:disable_sinatra => false,
|
103
|
+
:disable_sinatra_auto_middleware => false,
|
102
104
|
:disable_view_instrumentation => false,
|
103
105
|
:disable_backtrace_cleanup => false,
|
104
106
|
:skip_ar_instrumentation => false,
|
@@ -139,7 +141,10 @@ module NewRelic
|
|
139
141
|
|
140
142
|
:'thread_profiler.enabled' => Proc.new { NewRelic::Agent::ThreadProfiler.is_supported? },
|
141
143
|
|
142
|
-
:marshaller => Proc.new { NewRelic::Agent::NewRelicService::JsonMarshaller.is_supported? ? 'json' : 'pruby' }
|
144
|
+
:marshaller => Proc.new { NewRelic::Agent::NewRelicService::JsonMarshaller.is_supported? ? 'json' : 'pruby' },
|
145
|
+
|
146
|
+
:'request_sampler.enabled' => false,
|
147
|
+
:'request_sampler.sample_rate_ms' => 50
|
143
148
|
].freeze
|
144
149
|
end
|
145
150
|
end
|
@@ -2,11 +2,6 @@
|
|
2
2
|
# This file is distributed under New Relic's license terms.
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
require 'new_relic/agent/instrumentation/evented_subscriber'
|
5
|
-
begin
|
6
|
-
require 'rack'
|
7
|
-
rescue LoadError => e
|
8
|
-
Agent.logger.debug(e)
|
9
|
-
end
|
10
5
|
|
11
6
|
module NewRelic
|
12
7
|
module Agent
|
@@ -17,6 +12,7 @@ module NewRelic
|
|
17
12
|
NewRelic::Agent.instance.events.subscribe(:before_call) do |env|
|
18
13
|
|
19
14
|
request = begin
|
15
|
+
require 'rack'
|
20
16
|
::Rack::Request.new(env)
|
21
17
|
rescue => e
|
22
18
|
Agent.logger.debug("Error creating Rack::Request object: #{e}")
|
@@ -111,7 +107,6 @@ module NewRelic
|
|
111
107
|
end
|
112
108
|
|
113
109
|
def stop_transaction(event)
|
114
|
-
TransactionInfo.get.transaction.name = event.metric_name
|
115
110
|
Agent.instance.stats_engine \
|
116
111
|
.pop_scope(event.scope, event.metric_name, event.end)
|
117
112
|
Transaction.stop
|
@@ -51,7 +51,7 @@ module NewRelic
|
|
51
51
|
if parent && (payload[:virtual_path] ||
|
52
52
|
(parent.payload[:identifier] =~ /template$/))
|
53
53
|
return parent.metric_name
|
54
|
-
elsif payload
|
54
|
+
elsif payload.key?(:virtual_path)
|
55
55
|
identifier = payload[:virtual_path]
|
56
56
|
else
|
57
57
|
identifier = payload[:identifier]
|
@@ -31,15 +31,15 @@ module NewRelic
|
|
31
31
|
return log_without_newrelic_instrumentation(*args, &block)
|
32
32
|
end
|
33
33
|
|
34
|
-
sql, name,
|
35
|
-
metric = metric_for_name(NewRelic::Helper.correctly_encoded(name)) ||
|
36
|
-
metric_for_sql(NewRelic::Helper.correctly_encoded(sql))
|
34
|
+
sql, name, _ = args
|
35
|
+
metric = ActiveRecordHelper.metric_for_name(NewRelic::Helper.correctly_encoded(name)) ||
|
36
|
+
ActiveRecordHelper.metric_for_sql(NewRelic::Helper.correctly_encoded(sql))
|
37
37
|
|
38
38
|
if !metric
|
39
39
|
log_without_newrelic_instrumentation(*args, &block)
|
40
40
|
else
|
41
41
|
metrics = [metric, remote_service_metric].compact
|
42
|
-
metrics += rollup_metrics_for(metric)
|
42
|
+
metrics += ActiveRecordHelper.rollup_metrics_for(metric)
|
43
43
|
self.class.trace_execution_scoped(metrics) do
|
44
44
|
t0 = Time.now
|
45
45
|
begin
|
@@ -60,50 +60,9 @@ module NewRelic
|
|
60
60
|
|
61
61
|
def remote_service_metric
|
62
62
|
if @config && @config[:adapter]
|
63
|
-
|
64
|
-
host = @config[:host] || 'localhost'
|
65
|
-
"RemoteService/sql/#{type}/#{host}"
|
63
|
+
ActiveRecordHelper.remote_service_metric(@config[:adapter], @config[:host])
|
66
64
|
end
|
67
65
|
end
|
68
|
-
|
69
|
-
def metric_for_name(name)
|
70
|
-
if name && (parts = name.split " ") && parts.size == 2
|
71
|
-
model = parts.first
|
72
|
-
operation = parts.last.downcase
|
73
|
-
op_name = case operation
|
74
|
-
when 'load', 'count', 'exists' then 'find'
|
75
|
-
when 'indexes', 'columns' then nil # fall back to DirectSQL
|
76
|
-
when 'destroy', 'find', 'save', 'create' then operation
|
77
|
-
when 'update' then 'save'
|
78
|
-
else
|
79
|
-
if model == 'Join'
|
80
|
-
operation
|
81
|
-
end
|
82
|
-
end
|
83
|
-
"ActiveRecord/#{model}/#{op_name}" if op_name
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def metric_for_sql(sql)
|
88
|
-
metric = NewRelic::Agent::Transaction.database_metric_name
|
89
|
-
if metric.nil?
|
90
|
-
if sql =~ /^(select|update|insert|delete|show)/i
|
91
|
-
# Could not determine the model/operation so let's find a better
|
92
|
-
# metric. If it doesn't match the regex, it's probably a show
|
93
|
-
# command or some DDL which we'll ignore.
|
94
|
-
metric = "Database/SQL/#{$1.downcase}"
|
95
|
-
else
|
96
|
-
metric = "Database/SQL/other"
|
97
|
-
end
|
98
|
-
end
|
99
|
-
metric
|
100
|
-
end
|
101
|
-
|
102
|
-
def rollup_metrics_for(metric)
|
103
|
-
metrics = ["ActiveRecord/all"]
|
104
|
-
metrics << "ActiveRecord/#{$1}" if metric =~ /ActiveRecord\/\w+\/(\w+)/
|
105
|
-
metrics
|
106
|
-
end
|
107
66
|
end
|
108
67
|
end
|
109
68
|
end
|
@@ -113,8 +72,9 @@ DependencyDetection.defer do
|
|
113
72
|
@name = :active_record
|
114
73
|
|
115
74
|
depends_on do
|
116
|
-
defined?(::ActiveRecord) &&
|
117
|
-
::ActiveRecord::VERSION
|
75
|
+
defined?(::ActiveRecord) && defined?(::ActiveRecord::Base) &&
|
76
|
+
(!defined?(::ActiveRecord::VERSION) ||
|
77
|
+
::ActiveRecord::VERSION::MAJOR.to_i <= 3)
|
118
78
|
end
|
119
79
|
|
120
80
|
depends_on do
|
@@ -52,8 +52,16 @@ module NewRelic
|
|
52
52
|
# If the metric name is in the form of "ActiveRecord/action"
|
53
53
|
# this returns merely: [ "ActiveRecord/all" ]
|
54
54
|
def rollup_metrics_for(metric)
|
55
|
-
metrics = [
|
55
|
+
metrics = []
|
56
|
+
|
57
|
+
# If we're outside of a web transaction, don't record any rollup
|
58
|
+
# database metrics. This is to prevent metrics from background tasks
|
59
|
+
# from polluting the metrics used to drive overview graphs.
|
60
|
+
if NewRelic::Agent::Transaction.recording_web_transaction?
|
61
|
+
metrics << "ActiveRecord/all"
|
62
|
+
end
|
56
63
|
metrics << "ActiveRecord/#{$1}" if metric =~ /ActiveRecord\/[\w|\:]+\/(\w+)/
|
64
|
+
|
57
65
|
metrics
|
58
66
|
end
|
59
67
|
|
@@ -310,7 +310,7 @@ module NewRelic
|
|
310
310
|
return yield if !(NewRelic::Agent.is_execution_traced? || options[:force])
|
311
311
|
options[:metric] = true if options[:metric].nil?
|
312
312
|
options[:deduct_call_time_from_parent] = true if options[:deduct_call_time_from_parent].nil?
|
313
|
-
|
313
|
+
_, expected_scope = NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScoped.trace_execution_scoped_header(options, txn.start_time.to_f)
|
314
314
|
|
315
315
|
begin
|
316
316
|
NewRelic::Agent::BusyCalculator.dispatcher_start txn.start_time
|
@@ -338,11 +338,12 @@ module NewRelic
|
|
338
338
|
metric_names = Array(metrics)
|
339
339
|
first_name = metric_names.shift
|
340
340
|
scope = NewRelic::Agent.instance.stats_engine.scope_name
|
341
|
-
|
341
|
+
end_time = Time.now
|
342
|
+
NewRelic::Agent::MethodTracer::InstanceMethods::TraceExecutionScoped.trace_execution_scoped_footer(txn.start_time.to_f, first_name, metric_names, expected_scope, scope, options, end_time.to_f)
|
342
343
|
NewRelic::Agent::BusyCalculator.dispatcher_finish
|
343
344
|
# Look for a transaction in the thread local and process it.
|
344
345
|
# Clear the thread local when finished to ensure it only gets called once.
|
345
|
-
txn = Transaction.stop(txn_name)
|
346
|
+
txn = Transaction.stop(txn_name, end_time)
|
346
347
|
txn.record_apdex(txn_name) unless ignore_apdex?
|
347
348
|
|
348
349
|
NewRelic::Agent::TransactionInfo.get.ignore_end_user = true if ignore_enduser?
|