newrelic_rpm 2.9.9 → 2.10.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of newrelic_rpm might be problematic. Click here for more details.
- data/CHANGELOG +117 -49
- data/bin/mongrel_rpm +2 -2
- data/install.rb +42 -33
- data/lib/new_relic/agent.rb +149 -39
- data/lib/new_relic/agent/agent.rb +139 -122
- data/lib/new_relic/agent/busy_calculator.rb +91 -0
- data/lib/new_relic/agent/collection_helper.rb +11 -2
- data/lib/new_relic/agent/error_collector.rb +33 -27
- data/lib/new_relic/agent/instrumentation/active_record_instrumentation.rb +30 -26
- data/lib/new_relic/agent/instrumentation/authlogic.rb +8 -0
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +316 -105
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +22 -0
- data/lib/new_relic/agent/instrumentation/memcache.rb +18 -12
- data/lib/new_relic/agent/instrumentation/merb/errors.rb +2 -1
- data/lib/new_relic/agent/instrumentation/metric_frame.rb +258 -0
- data/lib/new_relic/agent/instrumentation/net.rb +7 -11
- data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rack.rb +109 -0
- data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +6 -5
- data/lib/new_relic/agent/instrumentation/rails/errors.rb +7 -7
- data/lib/new_relic/agent/instrumentation/sinatra.rb +46 -0
- data/lib/new_relic/agent/method_tracer.rb +305 -150
- data/lib/new_relic/agent/sampler.rb +34 -0
- data/lib/new_relic/agent/samplers/cpu_sampler.rb +11 -1
- data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +37 -0
- data/lib/new_relic/agent/samplers/memory_sampler.rb +22 -10
- data/lib/new_relic/agent/samplers/object_sampler.rb +24 -0
- data/lib/new_relic/agent/shim_agent.rb +10 -0
- data/lib/new_relic/agent/stats_engine.rb +16 -278
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +118 -0
- data/lib/new_relic/agent/stats_engine/samplers.rb +81 -0
- data/lib/new_relic/agent/stats_engine/transactions.rb +149 -0
- data/lib/new_relic/agent/transaction_sampler.rb +73 -67
- data/lib/new_relic/agent/worker_loop.rb +69 -68
- data/lib/new_relic/commands/deployments.rb +4 -6
- data/lib/new_relic/control.rb +121 -60
- data/lib/new_relic/control/external.rb +13 -0
- data/lib/new_relic/control/merb.rb +2 -0
- data/lib/new_relic/control/rails.rb +16 -6
- data/lib/new_relic/control/ruby.rb +8 -5
- data/lib/new_relic/control/sinatra.rb +18 -0
- data/lib/new_relic/delayed_job_injection.rb +25 -0
- data/lib/new_relic/histogram.rb +89 -0
- data/lib/new_relic/local_environment.rb +64 -30
- data/lib/new_relic/metric_data.rb +15 -6
- data/lib/new_relic/metric_parser.rb +14 -1
- data/lib/new_relic/metric_parser/active_record.rb +14 -0
- data/lib/new_relic/metric_parser/controller.rb +5 -2
- data/lib/new_relic/metric_parser/external.rb +50 -0
- data/lib/new_relic/metric_parser/other_transaction.rb +15 -0
- data/lib/new_relic/metric_parser/web_frontend.rb +14 -0
- data/lib/new_relic/metric_spec.rb +39 -20
- data/lib/new_relic/metrics.rb +9 -7
- data/lib/new_relic/noticed_error.rb +6 -8
- data/lib/new_relic/rack/metric_app.rb +5 -4
- data/lib/new_relic/rack/{newrelic.ru → mongrel_rpm.ru} +4 -4
- data/lib/new_relic/rack/newrelic.yml +1 -0
- data/lib/new_relic/{rack.rb → rack_app.rb} +0 -0
- data/lib/new_relic/recipes.rb +1 -1
- data/lib/new_relic/stats.rb +40 -26
- data/lib/new_relic/transaction_analysis.rb +5 -2
- data/lib/new_relic/transaction_sample.rb +134 -55
- data/lib/new_relic/version.rb +27 -20
- data/lib/new_relic_api.rb +67 -47
- data/lib/newrelic_rpm.rb +5 -5
- data/lib/tasks/tests.rake +2 -0
- data/newrelic.yml +69 -29
- data/test/active_record_fixtures.rb +2 -2
- data/test/config/newrelic.yml +4 -7
- data/test/config/test_control.rb +1 -2
- data/test/new_relic/agent/active_record_instrumentation_test.rb +115 -31
- data/test/new_relic/agent/agent_controller_test.rb +274 -0
- data/test/new_relic/agent/agent_test_controller.rb +42 -6
- data/test/new_relic/agent/busy_calculator_test.rb +79 -0
- data/test/new_relic/agent/collection_helper_test.rb +10 -3
- data/test/new_relic/agent/error_collector_test.rb +35 -17
- data/test/new_relic/agent/method_tracer_test.rb +60 -20
- data/test/new_relic/agent/metric_data_test.rb +2 -2
- data/test/new_relic/agent/metric_frame_test.rb +51 -0
- data/test/new_relic/agent/net_instrumentation_test.rb +77 -0
- data/test/new_relic/agent/{agent_test.rb → rpm_agent_test.rb} +26 -5
- data/test/new_relic/agent/stats_engine/metric_stats_test.rb +79 -0
- data/test/new_relic/{samplers_test.rb → agent/stats_engine/samplers_test.rb} +23 -22
- data/test/new_relic/agent/{stats_engine_test.rb → stats_engine/stats_engine_test.rb} +19 -101
- data/test/new_relic/agent/task_instrumentation_test.rb +176 -0
- data/test/new_relic/agent/transaction_sample_builder_test.rb +2 -2
- data/test/new_relic/agent/transaction_sample_test.rb +53 -38
- data/test/new_relic/agent/transaction_sampler_test.rb +101 -33
- data/test/new_relic/agent/worker_loop_test.rb +16 -14
- data/test/new_relic/control_test.rb +26 -13
- data/test/new_relic/metric_parser_test.rb +31 -1
- data/test/new_relic/metric_spec_test.rb +2 -2
- data/test/new_relic/stats_test.rb +0 -8
- data/test/new_relic/version_number_test.rb +31 -1
- data/test/test_helper.rb +37 -1
- data/ui/controllers/newrelic_controller.rb +19 -11
- data/ui/helpers/google_pie_chart.rb +5 -11
- data/ui/helpers/newrelic_helper.rb +40 -35
- data/ui/views/layouts/newrelic_default.rhtml +7 -7
- data/ui/views/newrelic/_sample.rhtml +5 -1
- data/ui/views/newrelic/images/new-relic-rpm-desktop.gif +0 -0
- data/ui/views/newrelic/images/textmate.png +0 -0
- data/ui/views/newrelic/index.rhtml +13 -1
- data/ui/views/newrelic/show_sample.rhtml +5 -2
- data/ui/views/newrelic/stylesheets/style.css +54 -3
- metadata +65 -145
- data/Manifest +0 -143
- data/Rakefile +0 -22
- data/init.rb +0 -38
- data/lib/new_relic/agent/instrumentation/dispatcher_instrumentation.rb +0 -127
- data/lib/new_relic/agent/instrumentation/error_instrumentation.rb +0 -14
- data/lib/new_relic/agent/instrumentation/merb/dispatcher.rb +0 -13
- data/lib/new_relic/agent/instrumentation/rails/dispatcher.rb +0 -38
- data/lib/new_relic/agent/patch_const_missing.rb +0 -125
- data/lib/new_relic/agent/samplers/mongrel_sampler.rb +0 -22
- data/lib/new_relic/metric_parser/database.rb +0 -23
- data/newrelic_rpm.gemspec +0 -35
- data/test/new_relic/agent/classloader_patch_test.rb +0 -56
- data/test/new_relic/agent/controller_test.rb +0 -107
- data/test/new_relic/agent/dispatcher_instrumentation_test.rb +0 -70
data/lib/newrelic_rpm.rb
CHANGED
@@ -10,15 +10,15 @@
|
|
10
10
|
# dependency 'newrelic_rpm'
|
11
11
|
# in the Merb config/init.rb
|
12
12
|
#
|
13
|
+
# For Sinatra, do
|
14
|
+
# require 'newrelic_rpm'
|
15
|
+
# after requiring 'sinatra'.
|
16
|
+
#
|
13
17
|
# For other frameworks, or to manage the agent manually, invoke NewRelic::Agent#manual_start
|
14
18
|
# directly.
|
15
19
|
#
|
16
20
|
require 'new_relic/control'
|
17
21
|
|
18
|
-
def log!(message)
|
19
|
-
STDERR.puts "[NewRelic] #{message}"
|
20
|
-
end
|
21
|
-
|
22
22
|
# After verison 2.0 of Rails we can access the configuration directly.
|
23
23
|
# We need it to add dev mode routes after initialization finished.
|
24
24
|
if defined? Rails.configuration
|
@@ -34,7 +34,7 @@ elsif defined? Merb
|
|
34
34
|
NewRelic::Control.instance.init_plugin
|
35
35
|
end
|
36
36
|
end
|
37
|
-
end
|
37
|
+
end
|
38
38
|
else
|
39
39
|
NewRelic::Control.instance.init_plugin
|
40
40
|
end
|
data/lib/tasks/tests.rake
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# run unit tests for the NewRelic Agent
|
2
|
+
|
2
3
|
if defined? Rake::TestTask
|
3
4
|
namespace :test do
|
4
5
|
AGENT_HOME = File.expand_path(File.join(File.dirname(__FILE__), "..",".."))
|
@@ -9,5 +10,6 @@ if defined? Rake::TestTask
|
|
9
10
|
t.verbose = true
|
10
11
|
end
|
11
12
|
Rake::Task['test:newrelic'].comment = "Run the unit tests for the Agent"
|
13
|
+
task :default => :newrelic
|
12
14
|
end
|
13
15
|
end
|
data/newrelic.yml
CHANGED
@@ -14,7 +14,7 @@ common: &default_settings
|
|
14
14
|
# New Relic RPM service.
|
15
15
|
license_key: '<%= license_key %>'
|
16
16
|
|
17
|
-
# Agent Enabled
|
17
|
+
# Agent Enabled (Rails Only)
|
18
18
|
# Use this setting to force the agent to run or not run.
|
19
19
|
# Default is 'auto' which means the agent will install and run only
|
20
20
|
# if a valid dispatcher such as Mongrel is running. This prevents
|
@@ -29,15 +29,19 @@ common: &default_settings
|
|
29
29
|
# into a RPM "application" on your home dashboard page. If you want
|
30
30
|
# to map this instance into multiple apps, like "AJAX Requests" and
|
31
31
|
# "All UI" then specify a semicolon separated list of up to three
|
32
|
-
# distinct names.
|
33
|
-
#
|
32
|
+
# distinct names. If you comment this out, it defaults to the
|
33
|
+
# capitalized RAILS_ENV (i.e., Production, Staging, etc)
|
34
34
|
app_name: My Application
|
35
35
|
|
36
|
-
# When
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
|
36
|
+
# When "true", the agent collects performance data about your
|
37
|
+
# application and reports this data to the NewRelic RPM service at
|
38
|
+
# newrelic.com. This global switch is normally overridden for each
|
39
|
+
# environment below. (formerly called 'enabled')
|
40
|
+
monitor_mode: true
|
41
|
+
|
42
|
+
# Developer mode should be off in every environment but
|
43
|
+
# development as it has very high overhead in memory.
|
44
|
+
developer_mode: false
|
41
45
|
|
42
46
|
# The newrelic agent generates its own log file to keep its logging
|
43
47
|
# information separate from that of your application. Specify its
|
@@ -88,9 +92,12 @@ common: &default_settings
|
|
88
92
|
|
89
93
|
|
90
94
|
# Tells transaction tracer and error collector (when enabled)
|
91
|
-
# whether or not to capture HTTP params. When true,
|
92
|
-
#
|
93
|
-
#
|
95
|
+
# whether or not to capture HTTP params. When true, frameworks can
|
96
|
+
# exclude HTTP parameters from being captured.
|
97
|
+
# Rails: the RoR filter_parameter_logging excludes parameters
|
98
|
+
# Java: create a config setting called "ignored_params" and set it to
|
99
|
+
# a comma separated list of HTTP parameter names.
|
100
|
+
# ex: ignored_params: credit_card, ssn, password
|
94
101
|
capture_params: false
|
95
102
|
|
96
103
|
|
@@ -124,6 +131,15 @@ common: &default_settings
|
|
124
131
|
# then capture and send to RPM the current stack trace. This is
|
125
132
|
# helpful for pinpointing where long SQL calls originate from
|
126
133
|
stack_trace_threshold: 0.500
|
134
|
+
|
135
|
+
# Determines whether the agent will capture query plans for slow
|
136
|
+
# SQL queries. Only supported in mysql and postgres. Should be
|
137
|
+
# set to false when using other adapters.
|
138
|
+
# explain_enabled: true
|
139
|
+
|
140
|
+
# Threshold for query execution time below which query plans will not
|
141
|
+
# not be captured. Relevant only when `explain_enabled` is true.
|
142
|
+
# explain_threshold: 0.5
|
127
143
|
|
128
144
|
# Error collector captures information about uncaught exceptions and
|
129
145
|
# sends them to RPM for viewing
|
@@ -134,43 +150,67 @@ common: &default_settings
|
|
134
150
|
# product levels
|
135
151
|
enabled: true
|
136
152
|
|
137
|
-
#
|
138
|
-
# around the place of the error when errors are View
|
153
|
+
# Rails Only - tells error collector whether or not to capture a
|
154
|
+
# source snippet around the place of the error when errors are View
|
155
|
+
# related.
|
139
156
|
capture_source: true
|
140
157
|
|
141
158
|
# To stop specific errors from reporting to RPM, set this property
|
142
|
-
# to comma separated values
|
159
|
+
# to comma separated values. Default is to ignore routing errors
|
160
|
+
# which are how 404's get triggered.
|
143
161
|
#
|
144
|
-
|
162
|
+
ignore_errors: ActionController::RoutingError
|
145
163
|
|
146
164
|
# (Advanced) Uncomment this to ensure the cpu and memory samplers
|
147
165
|
# won't run. Useful when you are using the agent to monitor an
|
148
166
|
# external resource
|
149
167
|
# disable_samplers: true
|
168
|
+
|
169
|
+
# If you aren't interested in visibility in these areas, you can disable
|
170
|
+
# the instrumentation to reduce overhead.
|
171
|
+
#
|
172
|
+
# disable_view_instrumentation: true
|
173
|
+
# disable_activerecord_instrumentation: true
|
174
|
+
# disable_memcache_instrumentation: true
|
175
|
+
# disable_dj: true
|
176
|
+
|
177
|
+
# Certain types of instrumentation such as GC stats will not work if
|
178
|
+
# you are running multi-threaded. Please let us know.
|
179
|
+
# multi_threaded = false
|
150
180
|
|
151
|
-
#
|
181
|
+
# Application Environments
|
182
|
+
# ------------------------------------------
|
183
|
+
# Environment specific settings are in this section.
|
184
|
+
# For Rails applications, RAILS_ENV is used to determine the environment
|
185
|
+
# For Java applications, pass -Dnewrelic.environment <environment> to set
|
186
|
+
# the environment
|
152
187
|
|
153
188
|
# NOTE if your application has other named environments, you should
|
154
189
|
# provide newrelic conifguration settings for these enviromnents here.
|
155
190
|
|
156
191
|
development:
|
157
192
|
<<: *default_settings
|
158
|
-
# Turn off communication to RPM service in development mode
|
193
|
+
# Turn off communication to RPM service in development mode (also
|
194
|
+
# 'enabled').
|
159
195
|
# NOTE: for initial evaluation purposes, you may want to temporarily
|
160
196
|
# turn the agent on in development mode.
|
161
|
-
|
162
|
-
|
163
|
-
#
|
164
|
-
# performance information on the last 100 transactions you have
|
165
|
-
# executed since starting the mongrel.
|
166
|
-
#
|
167
|
-
|
197
|
+
monitor_mode: false
|
198
|
+
|
199
|
+
# Rails Only - when running in Developer Mode, the New Relic Agent will
|
200
|
+
# present performance information on the last 100 transactions you have
|
201
|
+
# executed since starting the mongrel.
|
202
|
+
# NOTE: There is substantial overhead when running in developer mode.
|
203
|
+
# Do not use for production or load testing.
|
204
|
+
developer_mode: true
|
205
|
+
|
206
|
+
# Enable textmate links
|
207
|
+
# textmate: true
|
168
208
|
|
169
209
|
test:
|
170
210
|
<<: *default_settings
|
171
|
-
#
|
211
|
+
# It almost never makes sense to turn on the agent when running
|
172
212
|
# unit, functional or integration tests or the like.
|
173
|
-
|
213
|
+
monitor_mode: false
|
174
214
|
|
175
215
|
# Turn on the agent in production for 24x7 monitoring. NewRelic
|
176
216
|
# testing shows an average performance impact of < 5 ms per
|
@@ -178,12 +218,12 @@ test:
|
|
178
218
|
# incurring any user-visible performance degredation.
|
179
219
|
production:
|
180
220
|
<<: *default_settings
|
181
|
-
|
221
|
+
monitor_mode: true
|
182
222
|
|
183
|
-
#
|
223
|
+
# Many applications have a staging environment which behaves
|
184
224
|
# identically to production. Support for that environment is provided
|
185
225
|
# here. By default, the staging environment has the agent turned on.
|
186
226
|
staging:
|
187
227
|
<<: *default_settings
|
188
|
-
|
228
|
+
monitor_mode: true
|
189
229
|
app_name: My Application (Staging)
|
@@ -39,9 +39,9 @@ module ActiveRecordFixtures
|
|
39
39
|
has_and_belongs_to_many :orders, :class_name => 'ActiveRecordFixtures::Order'
|
40
40
|
def self.setup
|
41
41
|
connection.create_table self.table_name, :force => true do |t|
|
42
|
-
|
42
|
+
# no other columns
|
43
43
|
end
|
44
|
-
connection.create_table 'orders_shipments', :force => true do |t|
|
44
|
+
connection.create_table 'orders_shipments', :force => true, :id => false do |t|
|
45
45
|
t.column :order_id, :integer
|
46
46
|
t.column :shipment_id, :integer
|
47
47
|
end
|
data/test/config/newrelic.yml
CHANGED
@@ -8,11 +8,11 @@ test:
|
|
8
8
|
<<: *default_settings
|
9
9
|
host: localhost
|
10
10
|
port: 3000
|
11
|
-
log_level:
|
11
|
+
log_level: info
|
12
12
|
capture_params: true
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
agent_enabled: false
|
14
|
+
monitor_mode: false
|
15
|
+
developer_mode: true
|
16
16
|
disable_samplers: true
|
17
17
|
api_host: 127.0.0.1
|
18
18
|
api_port: 443
|
@@ -29,9 +29,6 @@ test:
|
|
29
29
|
yval: yes
|
30
30
|
sval: sure
|
31
31
|
|
32
|
-
# checks for loading classes on the background thread
|
33
|
-
check_bg_loading: true
|
34
|
-
|
35
32
|
transaction_tracer:
|
36
33
|
record_sql: raw
|
37
34
|
transaction_threshold: Apdex_f # case insensitive
|
data/test/config/test_control.rb
CHANGED
@@ -2,23 +2,28 @@ require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper
|
|
2
2
|
require 'active_record_fixtures'
|
3
3
|
|
4
4
|
class ActiveRecordInstrumentationTest < Test::Unit::TestCase
|
5
|
-
|
5
|
+
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
|
6
6
|
def setup
|
7
|
+
super
|
7
8
|
NewRelic::Agent.manual_start
|
8
|
-
NewRelic::Agent.instance.stats_engine.clear_stats
|
9
9
|
ActiveRecordFixtures.setup
|
10
|
-
NewRelic::Agent.instance.transaction_sampler.
|
10
|
+
NewRelic::Agent.instance.transaction_sampler.reset!
|
11
|
+
NewRelic::Agent.instance.stats_engine.clear_stats
|
11
12
|
rescue
|
12
13
|
puts e
|
13
14
|
puts e.backtrace.join("\n")
|
14
15
|
end
|
15
16
|
|
16
17
|
def teardown
|
18
|
+
super
|
17
19
|
ActiveRecordFixtures.teardown
|
20
|
+
NewRelic::Agent.shutdown
|
18
21
|
end
|
22
|
+
|
19
23
|
def test_agent_setup
|
20
24
|
assert NewRelic::Agent.instance.class == NewRelic::Agent::Agent
|
21
25
|
end
|
26
|
+
|
22
27
|
def test_finder
|
23
28
|
ActiveRecordFixtures::Order.create :id => 0, :name => 'jeff'
|
24
29
|
ActiveRecordFixtures::Order.find(:all)
|
@@ -27,6 +32,9 @@ class ActiveRecordInstrumentationTest < Test::Unit::TestCase
|
|
27
32
|
ActiveRecordFixtures::Order.find_all_by_name "jeff"
|
28
33
|
s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
|
29
34
|
assert_equal 2, s.call_count
|
35
|
+
ActiveRecordFixtures::Order.exists?(["name=?", 'jeff'])
|
36
|
+
s = NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find")
|
37
|
+
assert_equal 3, s.call_count if NewRelic::Control.instance.rails_version > '2.3.4'
|
30
38
|
end
|
31
39
|
|
32
40
|
# multiple duplicate find calls should only cause metric trigger on the first
|
@@ -55,18 +63,18 @@ class ActiveRecordInstrumentationTest < Test::Unit::TestCase
|
|
55
63
|
# metrics = NewRelic::Agent.instance.stats_engine.metrics.select { |mname| mname =~ /ActiveRecord\/ActiveRecordFixtures::Order\// }.sort
|
56
64
|
expected = %W[
|
57
65
|
ActiveRecord/all
|
58
|
-
ActiveRecord/create
|
59
66
|
ActiveRecord/find
|
60
|
-
ActiveRecord/ActiveRecordFixtures::Order/create
|
61
67
|
ActiveRecord/ActiveRecordFixtures::Order/find
|
62
68
|
]
|
69
|
+
expected += %W[Database/SQL/insert] if defined?(JRuby)
|
70
|
+
expected += %W[ActiveRecord/create Database/SQL/other ActiveRecord/ActiveRecordFixtures::Order/create] unless defined?(JRuby)
|
63
71
|
expected += %W[ActiveRecord/save ActiveRecord/ActiveRecordFixtures::Order/save] if NewRelic::Control.instance.rails_version < '2.1.0'
|
64
72
|
compare_metrics expected, metrics
|
65
73
|
assert_equal 1, NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find").call_count
|
66
|
-
assert_equal 1, NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/create").call_count
|
74
|
+
assert_equal (defined?(JRuby) ? 0 : 1), NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/create").call_count
|
67
75
|
end
|
68
76
|
def test_join_metrics
|
69
|
-
m = ActiveRecordFixtures::Order.create :
|
77
|
+
m = ActiveRecordFixtures::Order.create :name => 'jeff'
|
70
78
|
m = ActiveRecordFixtures::Order.find(m.id)
|
71
79
|
s = m.shipments.create
|
72
80
|
m.shipments.to_a
|
@@ -75,57 +83,104 @@ class ActiveRecordInstrumentationTest < Test::Unit::TestCase
|
|
75
83
|
metrics = NewRelic::Agent.instance.stats_engine.metrics
|
76
84
|
# This doesn't work on hudson because the sampler metrics creep in.
|
77
85
|
# metrics = NewRelic::Agent.instance.stats_engine.metrics.select { |mname| mname =~ /ActiveRecord\/ActiveRecordFixtures::Order\// }.sort
|
78
|
-
|
86
|
+
expected_metrics = %W[
|
79
87
|
ActiveRecord/all
|
80
88
|
ActiveRecord/destroy
|
81
89
|
ActiveRecord/ActiveRecordFixtures::Order/destroy
|
82
90
|
Database/SQL/insert
|
83
91
|
Database/SQL/delete
|
84
|
-
ActiveRecord/create
|
85
92
|
ActiveRecord/find
|
86
|
-
ActiveRecord/ActiveRecordFixtures::Order/create
|
87
93
|
ActiveRecord/ActiveRecordFixtures::Order/find
|
88
94
|
ActiveRecord/ActiveRecordFixtures::Shipment/find
|
95
|
+
]
|
96
|
+
|
97
|
+
expected_metrics += %W[Database/SQL/other Database/SQL/show ActiveRecord/create
|
89
98
|
ActiveRecord/ActiveRecordFixtures::Shipment/create
|
90
|
-
|
99
|
+
ActiveRecord/ActiveRecordFixtures::Order/create
|
100
|
+
] unless defined? JRuby
|
101
|
+
|
102
|
+
compare_metrics expected_metrics, metrics
|
103
|
+
# This number may be different with different db adapters, not sure
|
104
|
+
# assert_equal 17, NewRelic::Agent.get_stats("ActiveRecord/all").call_count
|
105
|
+
assert_equal NewRelic::Agent.get_stats("ActiveRecord/all").total_exclusive_time, NewRelic::Agent.get_stats("ActiveRecord/all").total_call_time unless defined?(RUBY_DESCRIPTION) && RUBY_DESCRIPTION =~ /Enterprise Edition/
|
91
106
|
assert_equal 1, NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Order/find").call_count
|
92
107
|
assert_equal 1, NewRelic::Agent.get_stats("ActiveRecord/ActiveRecordFixtures::Shipment/find").call_count
|
93
|
-
assert_equal 1, NewRelic::Agent.get_stats("Database/SQL/insert").call_count
|
108
|
+
assert_equal 1, NewRelic::Agent.get_stats("Database/SQL/insert").call_count unless defined? JRuby
|
109
|
+
assert_equal 3, NewRelic::Agent.get_stats("Database/SQL/insert").call_count if defined? JRuby
|
94
110
|
assert_equal 1, NewRelic::Agent.get_stats("Database/SQL/delete").call_count
|
95
111
|
end
|
96
112
|
def test_direct_sql
|
97
|
-
|
113
|
+
assert_nil NewRelic::Agent::Instrumentation::MetricFrame.current
|
114
|
+
assert_equal nil, NewRelic::Agent.instance.stats_engine.scope_name
|
115
|
+
assert_equal 0, NewRelic::Agent.instance.stats_engine.metrics.size, NewRelic::Agent.instance.stats_engine.metrics.inspect
|
116
|
+
ActiveRecordFixtures::Order.connection.select_rows "select * from #{ActiveRecordFixtures::Order.table_name}"
|
98
117
|
metrics = NewRelic::Agent.instance.stats_engine.metrics
|
99
118
|
compare_metrics %W[
|
100
119
|
ActiveRecord/all
|
101
120
|
Database/SQL/select
|
102
121
|
], metrics
|
103
|
-
assert_equal 1, NewRelic::Agent.
|
122
|
+
assert_equal 1, NewRelic::Agent.instance.stats_engine.get_stats_no_scope("Database/SQL/select").call_count, NewRelic::Agent.instance.stats_engine.get_stats_no_scope("Database/SQL/select")
|
104
123
|
end
|
105
124
|
|
106
|
-
def
|
125
|
+
def test_other_sql
|
126
|
+
list = ActiveRecordFixtures::Order.connection.execute "begin"
|
127
|
+
metrics = NewRelic::Agent.instance.stats_engine.metrics
|
128
|
+
compare_metrics %W[
|
129
|
+
ActiveRecord/all
|
130
|
+
Database/SQL/other
|
131
|
+
], metrics
|
132
|
+
assert_equal 1, NewRelic::Agent.get_stats_no_scope("Database/SQL/other").call_count
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_show_sql
|
136
|
+
list = ActiveRecordFixtures::Order.connection.execute "show tables"
|
137
|
+
metrics = NewRelic::Agent.instance.stats_engine.metrics
|
138
|
+
compare_metrics %W[
|
139
|
+
ActiveRecord/all
|
140
|
+
Database/SQL/show
|
141
|
+
], metrics
|
142
|
+
assert_equal 1, NewRelic::Agent.get_stats_no_scope("Database/SQL/show").call_count
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_blocked_instrumentation
|
107
146
|
ActiveRecordFixtures::Order.add_delay
|
108
|
-
|
109
|
-
|
147
|
+
NewRelic::Agent.disable_all_tracing do
|
148
|
+
perform_action_with_newrelic_trace :name => 'bogosity' do
|
149
|
+
ActiveRecordFixtures::Order.find(:all)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
assert_nil NewRelic::Agent.instance.transaction_sampler.last_sample
|
153
|
+
metrics = NewRelic::Agent.instance.stats_engine.metrics
|
154
|
+
compare_metrics [], metrics
|
155
|
+
end
|
156
|
+
def test_run_explains
|
157
|
+
perform_action_with_newrelic_trace :name => 'bogosity' do
|
158
|
+
ActiveRecordFixtures::Order.add_delay
|
159
|
+
ActiveRecordFixtures::Order.find(:all)
|
160
|
+
end
|
110
161
|
sample = NewRelic::Agent.instance.transaction_sampler.last_sample
|
111
162
|
|
112
|
-
segment = sample.root_segment.called_segments.first.called_segments.first
|
163
|
+
segment = sample.root_segment.called_segments.first.called_segments.first.called_segments.first
|
113
164
|
assert_match /^SELECT \* FROM ["`]?#{ActiveRecordFixtures::Order.table_name}["`]?$/i, segment.params[:sql].strip
|
114
165
|
NewRelic::TransactionSample::Segment.any_instance.expects(:explain_sql).returns([])
|
115
166
|
sample = sample.prepare_to_send(:obfuscate_sql => true, :explain_enabled => true, :explain_sql => 0.0)
|
116
167
|
segment = sample.root_segment.called_segments.first.called_segments.first
|
117
168
|
end
|
118
169
|
def test_prepare_to_send
|
119
|
-
|
120
|
-
|
121
|
-
|
170
|
+
perform_action_with_newrelic_trace :name => 'bogosity' do
|
171
|
+
ActiveRecordFixtures::Order.add_delay
|
172
|
+
ActiveRecordFixtures::Order.find(:all)
|
173
|
+
end
|
122
174
|
sample = NewRelic::Agent.instance.transaction_sampler.last_sample
|
175
|
+
assert_not_nil sample
|
176
|
+
assert_equal 3, sample.count_segments, sample.to_s
|
123
177
|
#
|
124
|
-
sql_segment = sample.root_segment.called_segments.first.called_segments.first
|
178
|
+
sql_segment = sample.root_segment.called_segments.first.called_segments.first.called_segments.first rescue nil
|
179
|
+
assert_not_nil sql_segment, sample.to_s
|
125
180
|
assert_match /^SELECT /, sql_segment.params[:sql]
|
126
181
|
assert sql_segment.duration > 0.0, "Segment duration must be greater than zero."
|
127
182
|
sample = sample.prepare_to_send(:record_sql => :raw, :explain_enabled => true, :explain_sql => 0.0)
|
128
|
-
sql_segment = sample.root_segment.called_segments.first.called_segments.first
|
183
|
+
sql_segment = sample.root_segment.called_segments.first.called_segments.first.called_segments.first
|
129
184
|
assert_match /^SELECT /, sql_segment.params[:sql]
|
130
185
|
explanations = sql_segment.params[:explanation]
|
131
186
|
if isMysql? || isPostgres?
|
@@ -135,13 +190,16 @@ class ActiveRecordInstrumentationTest < Test::Unit::TestCase
|
|
135
190
|
end
|
136
191
|
end
|
137
192
|
def test_transaction
|
138
|
-
|
139
|
-
|
193
|
+
sample = NewRelic::Agent.instance.transaction_sampler.reset!
|
194
|
+
perform_action_with_newrelic_trace :name => 'bogosity' do
|
195
|
+
ActiveRecordFixtures::Order.add_delay
|
196
|
+
ActiveRecordFixtures::Order.find(:all)
|
197
|
+
end
|
140
198
|
|
141
199
|
sample = NewRelic::Agent.instance.transaction_sampler.last_sample
|
142
200
|
|
143
201
|
sample = sample.prepare_to_send(:obfuscate_sql => true, :explain_enabled => true, :explain_sql => 0.0)
|
144
|
-
segment = sample.root_segment.called_segments.first.called_segments.first
|
202
|
+
segment = sample.root_segment.called_segments.first.called_segments.first.called_segments.first
|
145
203
|
assert_nil segment.params[:sql], "SQL should have been removed."
|
146
204
|
explanations = segment.params[:explanation]
|
147
205
|
if isMysql? || isPostgres?
|
@@ -177,12 +235,38 @@ class ActiveRecordInstrumentationTest < Test::Unit::TestCase
|
|
177
235
|
end
|
178
236
|
end
|
179
237
|
|
180
|
-
|
181
|
-
def
|
182
|
-
|
183
|
-
|
184
|
-
|
238
|
+
# This is to make sure the all metric is recorded for exceptional cases
|
239
|
+
def test_error_handling
|
240
|
+
# have the AR select throw an error
|
241
|
+
ActiveRecordFixtures::Order.connection.stubs(:log_info).with do | sql, x, y |
|
242
|
+
raise "Error" if sql =~ /select/
|
243
|
+
true
|
244
|
+
end
|
245
|
+
ActiveRecordFixtures::Order.connection.select_rows "select * from #{ActiveRecordFixtures::Order.table_name}" rescue nil
|
246
|
+
metrics = NewRelic::Agent.instance.stats_engine.metrics
|
247
|
+
compare_metrics %W[
|
248
|
+
ActiveRecord/all
|
249
|
+
Database/SQL/select
|
250
|
+
], metrics
|
251
|
+
assert_equal 1, NewRelic::Agent.get_stats("Database/SQL/select").call_count
|
252
|
+
assert_equal 1, NewRelic::Agent.get_stats("ActiveRecord/all").call_count
|
185
253
|
end
|
254
|
+
|
255
|
+
def test_rescue_handling
|
256
|
+
begin
|
257
|
+
ActiveRecordFixtures::Order.transaction do
|
258
|
+
raise ActiveRecord::ActiveRecordError.new('preserve-me!')
|
259
|
+
end
|
260
|
+
rescue ActiveRecord::ActiveRecordError => e
|
261
|
+
assert_equal 'preserve-me!', e.message
|
262
|
+
rescue
|
263
|
+
fail "Rescue2: Got something COMPLETELY unexpected: $!:#{$!.inspect}"
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
267
|
+
|
268
|
+
private
|
269
|
+
|
186
270
|
def isPostgres?
|
187
271
|
ActiveRecordFixtures::Order.configurations[RAILS_ENV]['adapter'] =~ /postgres/
|
188
272
|
end
|