newrelic_rpm 3.13.0.299 → 3.13.1.300
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -0
- data/CHANGELOG +36 -1
- data/lib/new_relic/agent/agent.rb +0 -1
- data/lib/new_relic/agent/database.rb +1 -1
- data/lib/new_relic/agent/datastores/mongo.rb +8 -7
- data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +49 -0
- data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +2 -2
- data/lib/new_relic/agent/error_collector.rb +12 -51
- data/lib/new_relic/agent/error_trace_aggregator.rb +89 -0
- data/lib/new_relic/agent/instrumentation/active_record.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record_4.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +26 -1
- data/lib/new_relic/agent/instrumentation/mongo.rb +16 -1
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +74 -0
- data/lib/new_relic/agent/supported_versions.rb +15 -1
- data/lib/new_relic/agent/system_info.rb +5 -0
- data/lib/new_relic/recipes/capistrano3.rb +1 -1
- data/lib/new_relic/recipes/capistrano_legacy.rb +1 -1
- data/lib/new_relic/version.rb +1 -1
- data/newrelic_rpm.gemspec +1 -1
- data/test/environments/lib/environments/runner.rb +1 -0
- data/test/fixtures/cross_agent_tests/proc_cpuinfo/README.md +4 -0
- data/test/fixtures/cross_agent_tests/proc_cpuinfo/malformed_file.txt +3 -0
- data/test/multiverse/lib/multiverse/suite.rb +4 -4
- data/test/multiverse/suites/active_record/active_record_test.rb +67 -26
- data/test/multiverse/suites/agent_only/start_up_test.rb +17 -3
- data/test/multiverse/suites/config_file_loading/Envfile +1 -1
- data/test/multiverse/suites/mongo/Envfile +3 -1
- data/test/multiverse/suites/mongo/mongo2_instrumentation_test.rb +344 -0
- data/test/multiverse/suites/mongo/mongo_connection_test.rb +2 -1
- data/test/multiverse/suites/mongo/mongo_instrumentation_test.rb +2 -1
- data/test/multiverse/suites/mongo/mongo_unsupported_version_test.rb +1 -1
- data/test/multiverse/suites/rails/rails3_app/app_rails3_plus.rb +7 -0
- data/test/multiverse/suites/sidekiq/Envfile +1 -1
- data/test/new_relic/agent/agent/start_test.rb +0 -5
- data/test/new_relic/agent/database_test.rb +8 -1
- data/test/new_relic/agent/datastores/mongo/event_formatter_test.rb +154 -0
- data/test/new_relic/agent/error_collector_test.rb +0 -13
- data/test/new_relic/agent/error_trace_aggregator_test.rb +30 -0
- data/test/new_relic/agent/instrumentation/mongodb_command_subscriber_test.rb +72 -0
- data/test/new_relic/agent/stats_engine/metric_stats_test.rb +24 -22
- data/test/new_relic/agent/system_info_test.rb +9 -1
- data/test/new_relic/rack/error_collector_test.rb +1 -2
- metadata +10 -2
@@ -11,12 +11,27 @@ DependencyDetection.defer do
|
|
11
11
|
|
12
12
|
depends_on do
|
13
13
|
require 'new_relic/agent/datastores/mongo'
|
14
|
+
if NewRelic::Agent::Datastores::Mongo.is_unsupported_2x?
|
15
|
+
NewRelic::Agent.logger.log_once(:info, :mongo2, 'Detected unsupported Mongo 2, upgrade your Mongo Driver to 2.1 or newer for instrumentation')
|
16
|
+
end
|
14
17
|
NewRelic::Agent::Datastores::Mongo.is_supported_version?
|
15
18
|
end
|
16
19
|
|
17
20
|
executes do
|
18
21
|
NewRelic::Agent.logger.info 'Installing Mongo instrumentation'
|
19
|
-
|
22
|
+
if NewRelic::Agent::Datastores::Mongo.is_monitoring_enabled?
|
23
|
+
install_mongo_command_subscriber
|
24
|
+
else
|
25
|
+
install_mongo_instrumentation
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def install_mongo_command_subscriber
|
30
|
+
require 'new_relic/agent/instrumentation/mongodb_command_subscriber'
|
31
|
+
Mongo::Monitoring::Global.subscribe(
|
32
|
+
Mongo::Monitoring::COMMAND,
|
33
|
+
NewRelic::Agent::Instrumentation::MongodbCommandSubscriber.new
|
34
|
+
)
|
20
35
|
end
|
21
36
|
|
22
37
|
def install_mongo_instrumentation
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under New Relic's license terms.
|
3
|
+
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
|
+
require 'new_relic/agent/datastores/mongo/event_formatter'
|
5
|
+
|
6
|
+
module NewRelic
|
7
|
+
module Agent
|
8
|
+
module Instrumentation
|
9
|
+
class MongodbCommandSubscriber
|
10
|
+
|
11
|
+
MONGODB = 'MongoDB'.freeze
|
12
|
+
|
13
|
+
def started(event)
|
14
|
+
begin
|
15
|
+
return unless NewRelic::Agent.tl_is_execution_traced?
|
16
|
+
operations[event.operation_id] = event
|
17
|
+
rescue Exception => e
|
18
|
+
log_notification_error('started', e)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def completed(event)
|
23
|
+
begin
|
24
|
+
state = NewRelic::Agent::TransactionState.tl_get
|
25
|
+
return unless state.is_execution_traced?
|
26
|
+
started_event = operations.delete(event.operation_id)
|
27
|
+
|
28
|
+
base, *other_metrics = metrics(started_event)
|
29
|
+
|
30
|
+
NewRelic::Agent.instance.stats_engine.tl_record_scoped_and_unscoped_metrics(
|
31
|
+
base, other_metrics, event.duration
|
32
|
+
)
|
33
|
+
|
34
|
+
NewRelic::Agent.instance.transaction_sampler.notice_nosql_statement(
|
35
|
+
generate_statement(started_event), event.duration
|
36
|
+
)
|
37
|
+
rescue Exception => e
|
38
|
+
log_notification_error('completed', e)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
alias :succeeded :completed
|
43
|
+
alias :failed :completed
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def collection(event)
|
48
|
+
event.command.values.first
|
49
|
+
end
|
50
|
+
|
51
|
+
def metrics(event)
|
52
|
+
NewRelic::Agent::Datastores::MetricHelper.metrics_for(MONGODB, event.command_name, collection(event))
|
53
|
+
end
|
54
|
+
|
55
|
+
def log_notification_error(event_type, error)
|
56
|
+
NewRelic::Agent.logger.error("Error during MongoDB #{event_type} event:")
|
57
|
+
NewRelic::Agent.logger.log_exception(:error, error)
|
58
|
+
end
|
59
|
+
|
60
|
+
def operations
|
61
|
+
@operations ||= {}
|
62
|
+
end
|
63
|
+
|
64
|
+
def generate_statement(event)
|
65
|
+
NewRelic::Agent::Datastores::Mongo::EventFormatter.format(
|
66
|
+
event.command_name,
|
67
|
+
event.database_name,
|
68
|
+
event.command
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -148,12 +148,26 @@ module NewRelic
|
|
148
148
|
:mongo =>
|
149
149
|
{
|
150
150
|
:type => :database,
|
151
|
-
:supported => ["
|
151
|
+
:supported => ["~>1.8", "~>2.1"],
|
152
152
|
:url => "https://rubygems.org/gems/mongo",
|
153
153
|
:feed => "https://rubygems.org/gems/mongo/versions.atom"
|
154
154
|
},
|
155
|
+
:redis =>
|
156
|
+
{
|
157
|
+
:type => :database,
|
158
|
+
:supported => ["~> 3.0"],
|
159
|
+
:url => "https://rubygems.org/gems/redis",
|
160
|
+
:feed => "https://rubygems.org/gems/redis/versions.atom"
|
161
|
+
},
|
155
162
|
|
156
163
|
# Background Jobs
|
164
|
+
:rake =>
|
165
|
+
{
|
166
|
+
:type => :background,
|
167
|
+
:supported => ["~> 10.0"],
|
168
|
+
:url => "https://rubygems.org/gems/rake",
|
169
|
+
:feed => "https://rubygems.org/gems/rake/versions.atom"
|
170
|
+
},
|
157
171
|
:resque =>
|
158
172
|
{
|
159
173
|
:type => :background,
|
@@ -113,6 +113,11 @@ module NewRelic
|
|
113
113
|
if num_physical_cores == 0
|
114
114
|
num_logical_processors = total_processors
|
115
115
|
|
116
|
+
if total_processors == 0
|
117
|
+
# Likely a malformed file.
|
118
|
+
num_logical_processors = nil
|
119
|
+
end
|
120
|
+
|
116
121
|
if total_processors == 1
|
117
122
|
# Some older, single-core processors might not list ids,
|
118
123
|
# so we'll just mark them all 1.
|
@@ -58,7 +58,7 @@ namespace :newrelic do
|
|
58
58
|
current_revision = fetch(:current_revision)
|
59
59
|
|
60
60
|
if scm == :git
|
61
|
-
log_command = "git log --no-color --pretty=format:' * %an: %s' " +
|
61
|
+
log_command = "git --no-pager log --no-color --pretty=format:' * %an: %s' " +
|
62
62
|
"--abbrev-commit --no-merges #{previous_revision}..#{current_revision}"
|
63
63
|
`#{log_command}`
|
64
64
|
end
|
@@ -58,7 +58,7 @@ make_notify_task = Proc.new do
|
|
58
58
|
from_revision = source.next_revision(current_revision)
|
59
59
|
|
60
60
|
if scm == :git
|
61
|
-
log_command = "git log --no-color --pretty=format:' * %an: %s' " +
|
61
|
+
log_command = "git --no-pager log --no-color --pretty=format:' * %an: %s' " +
|
62
62
|
"--abbrev-commit --no-merges #{previous_revision}..#{real_revision}"
|
63
63
|
else
|
64
64
|
log_command = "#{source.log(from_revision)}"
|
data/lib/new_relic/version.rb
CHANGED
data/newrelic_rpm.gemspec
CHANGED
@@ -61,7 +61,7 @@ EOS
|
|
61
61
|
|
62
62
|
if RUBY_PLATFORM == 'java'
|
63
63
|
s.add_development_dependency 'activerecord-jdbcsqlite3-adapter'
|
64
|
-
s.add_development_dependency 'jruby-openssl'
|
64
|
+
s.add_development_dependency 'jruby-openssl', '~> 0.9.10' unless JRUBY_VERSION > '1.7'
|
65
65
|
else
|
66
66
|
s.add_development_dependency 'sqlite3'
|
67
67
|
end
|
@@ -18,6 +18,7 @@ module Environments
|
|
18
18
|
"ree" => ["rails40", "rails41", "rails42"],
|
19
19
|
"jruby-1.6" => ["rails40", "rails41", "rails42"],
|
20
20
|
"jruby-1.7" => ["rails21", "rails22", "rails23"],
|
21
|
+
"jruby-9.0" => ["rails21", "rails22", "rails23", "rails30", "rails31", "rails32"],
|
21
22
|
"rbx-2.0" => ["rails21", "rails22", "rails23", "rails30", "rails31", "rails32"],
|
22
23
|
}
|
23
24
|
|
@@ -22,3 +22,7 @@ should produce the following expected values:
|
|
22
22
|
If any of `A`, `B`, or `C` are the character `X` instead of an integer, then
|
23
23
|
processing code should not return a value (return `null`, return `nil`,
|
24
24
|
raise an exception... whatever makes most sense for your agent).
|
25
|
+
|
26
|
+
There is a malformed.txt file which is a random file that does not adhere to
|
27
|
+
any /proc/cpuinfo format. The expected result is `null` for packages, cores and
|
28
|
+
processors.
|
@@ -172,7 +172,7 @@ module Multiverse
|
|
172
172
|
f.puts ' source "https://rubygems.org"' unless local
|
173
173
|
f.print gemfile_text
|
174
174
|
f.puts newrelic_gemfile_line unless gemfile_text =~ /^\s*gem .newrelic_rpm./
|
175
|
-
f.puts jruby_openssl_line unless gemfile_text =~ /^\s*gem .jruby-openssl./
|
175
|
+
f.puts jruby_openssl_line unless gemfile_text =~ /^\s*gem .jruby-openssl./ || (defined?(JRUBY_VERSION) && JRUBY_VERSION > '1.7')
|
176
176
|
f.puts minitest_line unless gemfile_text =~ /^\s*gem .minitest[^_]./
|
177
177
|
|
178
178
|
rbx_gemfile_lines(f, gemfile_text)
|
@@ -184,8 +184,8 @@ module Multiverse
|
|
184
184
|
|
185
185
|
# Pry 0.10.0 breaks compatibility with Ruby 1.8.7 :(
|
186
186
|
f.puts " gem 'pry', '~> #{pry_version}'"
|
187
|
-
f.puts " gem 'pry-byebug'" if RUBY_VERSION >= "2.0.0"
|
188
|
-
f.puts " gem 'pry-stack_explorer'"
|
187
|
+
f.puts " gem 'pry-byebug'" if RUBY_VERSION >= "2.0.0" && RUBY_ENGINE == "ruby"
|
188
|
+
f.puts " gem 'pry-stack_explorer'" if RUBY_ENGINE == "ruby"
|
189
189
|
end
|
190
190
|
end
|
191
191
|
puts yellow("Gemfile.#{env_index} set to:") if verbose?
|
@@ -212,7 +212,7 @@ module Multiverse
|
|
212
212
|
end
|
213
213
|
|
214
214
|
def jruby_openssl_line
|
215
|
-
"gem 'jruby-openssl', :require => false, :platforms => [:jruby]"
|
215
|
+
"gem 'jruby-openssl', '~> 0.9.10', :require => false, :platforms => [:jruby]"
|
216
216
|
end
|
217
217
|
|
218
218
|
def minitest_line
|
@@ -9,11 +9,76 @@ class ActiveRecordInstrumentationTest < Minitest::Test
|
|
9
9
|
include MultiverseHelpers
|
10
10
|
setup_and_teardown_agent
|
11
11
|
|
12
|
+
module VersionHelpers
|
13
|
+
def active_record_major_version
|
14
|
+
if defined?(::ActiveRecord::VERSION::MAJOR)
|
15
|
+
::ActiveRecord::VERSION::MAJOR.to_i
|
16
|
+
else
|
17
|
+
2
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def active_record_minor_version
|
22
|
+
if defined?(::ActiveRecord::VERSION::MINOR)
|
23
|
+
::ActiveRecord::VERSION::MINOR.to_i
|
24
|
+
else
|
25
|
+
1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def active_record_version
|
30
|
+
if defined?(::ActiveRecord::VERSION::MINOR)
|
31
|
+
NewRelic::VersionNumber.new(::ActiveRecord::VERSION::STRING)
|
32
|
+
else
|
33
|
+
NewRelic::VersionNumber.new("2.1.0") # Can't tell between 2.1 and 2.2. Meh.
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
include VersionHelpers
|
39
|
+
extend VersionHelpers
|
40
|
+
|
12
41
|
def after_setup
|
13
42
|
super
|
14
43
|
NewRelic::Agent.drop_buffered_data
|
15
44
|
end
|
16
45
|
|
46
|
+
def test_metrics_for_calculation_methods
|
47
|
+
in_web_transaction do
|
48
|
+
Order.count
|
49
|
+
Order.average(:id)
|
50
|
+
Order.minimum(:id)
|
51
|
+
Order.maximum(:id)
|
52
|
+
Order.sum(:id)
|
53
|
+
end
|
54
|
+
|
55
|
+
if active_record_major_version >= 3
|
56
|
+
assert_activerecord_metrics(Order, 'select', :call_count => 5)
|
57
|
+
else
|
58
|
+
assert_generic_rollup_metrics('select')
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
if active_record_version >= NewRelic::VersionNumber.new('3.2.0')
|
63
|
+
def test_metrics_for_pluck
|
64
|
+
in_web_transaction do
|
65
|
+
Order.pluck(:id)
|
66
|
+
end
|
67
|
+
|
68
|
+
assert_activerecord_metrics(Order, 'select')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
if active_record_version >= NewRelic::VersionNumber.new('4.0.0')
|
73
|
+
def test_metrics_for_ids
|
74
|
+
in_web_transaction do
|
75
|
+
Order.ids
|
76
|
+
end
|
77
|
+
|
78
|
+
assert_activerecord_metrics(Order, 'select')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
17
82
|
def test_metrics_for_create
|
18
83
|
in_web_transaction do
|
19
84
|
Order.create(:name => 'bob')
|
@@ -157,7 +222,7 @@ class ActiveRecordInstrumentationTest < Minitest::Test
|
|
157
222
|
end
|
158
223
|
|
159
224
|
# delete and touch did not exist in AR 2.2
|
160
|
-
if
|
225
|
+
if active_record_version >= NewRelic::VersionNumber.new('3.0.0')
|
161
226
|
def test_metrics_for_delete
|
162
227
|
in_web_transaction do
|
163
228
|
order = Order.create("name" => "burt")
|
@@ -256,7 +321,7 @@ class ActiveRecordInstrumentationTest < Minitest::Test
|
|
256
321
|
end
|
257
322
|
|
258
323
|
# update & update! didn't become public until 4.0
|
259
|
-
if
|
324
|
+
if active_record_version >= NewRelic::VersionNumber.new('4.0.0')
|
260
325
|
def test_metrics_for_update
|
261
326
|
in_web_transaction do
|
262
327
|
order = Order.create(:name => "wendy")
|
@@ -525,30 +590,6 @@ class ActiveRecordInstrumentationTest < Minitest::Test
|
|
525
590
|
NewRelic::Agent::Instrumentation::ActiveRecordHelper::PRODUCT_NAMES[adapter.to_s]
|
526
591
|
end
|
527
592
|
|
528
|
-
def active_record_major_version
|
529
|
-
if defined?(::ActiveRecord::VERSION::MAJOR)
|
530
|
-
::ActiveRecord::VERSION::MAJOR.to_i
|
531
|
-
else
|
532
|
-
2
|
533
|
-
end
|
534
|
-
end
|
535
|
-
|
536
|
-
def active_record_minor_version
|
537
|
-
if defined?(::ActiveRecord::VERSION::MINOR)
|
538
|
-
::ActiveRecord::VERSION::MINOR.to_i
|
539
|
-
else
|
540
|
-
1
|
541
|
-
end
|
542
|
-
end
|
543
|
-
|
544
|
-
def active_record_version
|
545
|
-
if defined?(::ActiveRecord::VERSION::MINOR)
|
546
|
-
NewRelic::VersionNumber.new(::ActiveRecord::VERSION::STRING)
|
547
|
-
else
|
548
|
-
NewRelic::VersionNumber.new("2.1.0") # Can't tell between 2.1 and 2.2. Meh.
|
549
|
-
end
|
550
|
-
end
|
551
|
-
|
552
593
|
def assert_activerecord_metrics(model, operation, stats={})
|
553
594
|
assert_metrics_recorded({
|
554
595
|
"Datastore/statement/#{current_product}/#{model}/#{operation}" => stats,
|
@@ -7,6 +7,10 @@ require 'open3'
|
|
7
7
|
|
8
8
|
class StartUpTest < Minitest::Test
|
9
9
|
GIT_NOISE = "fatal: Not a git repository (or any of the parent directories): .git\n"
|
10
|
+
JRUBY_9000_NOISE = [
|
11
|
+
/uri\:classloader\:\/jruby\/kernel\/kernel\.rb\:\d*\: warning: unsupported exec option: close_others/, # https://github.com/jruby/jruby/issues/1913
|
12
|
+
/.*\/lib\/ruby\/stdlib\/jar_dependencies.rb:\d*: warning: shadowing outer local variable - (group_id|artifact_id)/, #https://github.com/mkristian/jar-dependencies/commit/65c71261b1522f7b10fcb95de42ea4799de3a83a
|
13
|
+
]
|
10
14
|
|
11
15
|
include MultiverseHelpers
|
12
16
|
|
@@ -25,7 +29,9 @@ class StartUpTest < Minitest::Test
|
|
25
29
|
GIT_NOISE,
|
26
30
|
/Exception\: java\.lang.*\n/]
|
27
31
|
|
28
|
-
expected_noise
|
32
|
+
expected_noise << JRUBY_9000_NOISE if jruby_9000
|
33
|
+
|
34
|
+
expected_noise.flatten.each {|noise| output.gsub!(noise, "")}
|
29
35
|
|
30
36
|
assert_equal '', output.chomp
|
31
37
|
end
|
@@ -64,8 +70,12 @@ class StartUpTest < Minitest::Test
|
|
64
70
|
'NEW_RELIC_PORT' => $collector.port.to_s) do
|
65
71
|
|
66
72
|
output = `bundle exec ruby -w script/warnings.rb 2>&1`
|
67
|
-
|
68
|
-
|
73
|
+
expected_noise = [GIT_NOISE]
|
74
|
+
|
75
|
+
expected_noise << JRUBY_9000_NOISE if jruby_9000
|
76
|
+
|
77
|
+
expected_noise.flatten.each {|noise| output.gsub!(noise, "")}
|
78
|
+
output.strip!
|
69
79
|
|
70
80
|
assert_equal NewRelic::VERSION::STRING, output
|
71
81
|
end
|
@@ -79,4 +89,8 @@ class StartUpTest < Minitest::Test
|
|
79
89
|
problems = output.scan(/ERROR : .*/)
|
80
90
|
assert_empty problems
|
81
91
|
end
|
92
|
+
|
93
|
+
def jruby_9000
|
94
|
+
defined?(JRUBY_VERSION) && NewRelic::VersionNumber.new(JRUBY_VERSION) >= "9.0.0"
|
95
|
+
end
|
82
96
|
end
|
@@ -6,7 +6,7 @@ gemfile <<-RB
|
|
6
6
|
gem 'fakefs', :require => 'fakefs/safe'
|
7
7
|
|
8
8
|
# Because we delay the agent, order of jruby-openssl matters
|
9
|
-
gem 'jruby-openssl', :platforms => [:jruby]
|
9
|
+
gem 'jruby-openssl', '~> 0.9.10', :platforms => [:jruby]
|
10
10
|
|
11
11
|
# don't start the agent
|
12
12
|
gem 'newrelic_rpm', :require => false, :path => File.expand_path('../../../../')
|
@@ -0,0 +1,344 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under New Relic's license terms.
|
3
|
+
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
|
+
|
5
|
+
require 'mongo'
|
6
|
+
require 'newrelic_rpm'
|
7
|
+
require 'new_relic/agent/datastores/mongo'
|
8
|
+
require 'helpers/mongo_metric_builder'
|
9
|
+
|
10
|
+
if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
|
11
|
+
NewRelic::Agent::Datastores::Mongo.is_monitoring_enabled?
|
12
|
+
module NewRelic
|
13
|
+
module Agent
|
14
|
+
module Instrumentation
|
15
|
+
class Mongo2InstrumentationTest < Minitest::Test
|
16
|
+
include Mongo
|
17
|
+
include TestHelpers::MongoMetricBuilder
|
18
|
+
|
19
|
+
def setup
|
20
|
+
@database_name = "multiverse"
|
21
|
+
@client = Mongo::Client.new(["#{$mongo.host}:#{$mongo.port}"], :database => @database_name)
|
22
|
+
@database = @client.database
|
23
|
+
|
24
|
+
@collection_name = "tribbles-#{SecureRandom.hex(16)}"
|
25
|
+
@collection = @database.collection(@collection_name)
|
26
|
+
|
27
|
+
@tribbles = [{'name' => 'soterios johnson'}, {'name' => 'wes mantooth'}]
|
28
|
+
|
29
|
+
NewRelic::Agent::Transaction.stubs(:recording_web_transaction?).returns(true)
|
30
|
+
NewRelic::Agent.drop_buffered_data
|
31
|
+
end
|
32
|
+
|
33
|
+
def teardown
|
34
|
+
NewRelic::Agent.drop_buffered_data
|
35
|
+
@collection.drop
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_records_metrics_for_insert_one
|
39
|
+
@collection.insert_one(@tribbles.first)
|
40
|
+
|
41
|
+
metrics = build_test_metrics(:insert)
|
42
|
+
expected = metrics_with_attributes(metrics)
|
43
|
+
|
44
|
+
assert_metrics_recorded(expected)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_records_metrics_for_insert_many
|
48
|
+
@collection.insert_many(@tribbles)
|
49
|
+
|
50
|
+
metrics = build_test_metrics(:insert)
|
51
|
+
expected = metrics_with_attributes(metrics)
|
52
|
+
|
53
|
+
assert_metrics_recorded(expected)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_records_metrics_for_delete_one
|
57
|
+
@collection.insert_one(@tribbles.first)
|
58
|
+
NewRelic::Agent.drop_buffered_data
|
59
|
+
|
60
|
+
@collection.delete_one(@tribbles.first)
|
61
|
+
|
62
|
+
metrics = build_test_metrics(:delete)
|
63
|
+
expected = metrics_with_attributes(metrics)
|
64
|
+
|
65
|
+
assert_metrics_recorded(expected)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_records_metrics_for_delete_many
|
69
|
+
@collection.insert_one(@tribbles.first)
|
70
|
+
NewRelic::Agent.drop_buffered_data
|
71
|
+
|
72
|
+
@collection.delete_many(@tribbles.first)
|
73
|
+
|
74
|
+
metrics = build_test_metrics(:delete)
|
75
|
+
expected = metrics_with_attributes(metrics)
|
76
|
+
|
77
|
+
assert_metrics_recorded(expected)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_records_metrics_for_replace_one
|
81
|
+
@collection.insert_one(@tribbles.first)
|
82
|
+
NewRelic::Agent.drop_buffered_data
|
83
|
+
|
84
|
+
@collection.replace_one(@tribbles[0], @tribbles[1])
|
85
|
+
|
86
|
+
metrics = build_test_metrics(:update)
|
87
|
+
expected = metrics_with_attributes(metrics)
|
88
|
+
|
89
|
+
assert_metrics_recorded(expected)
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_records_metrics_for_update_one
|
93
|
+
@collection.insert_one(@tribbles.first)
|
94
|
+
NewRelic::Agent.drop_buffered_data
|
95
|
+
|
96
|
+
@collection.update_one(@tribbles[0], "$set" => @tribbles[1])
|
97
|
+
|
98
|
+
metrics = build_test_metrics(:update)
|
99
|
+
expected = metrics_with_attributes(metrics)
|
100
|
+
|
101
|
+
assert_metrics_recorded(expected)
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_records_metrics_for_update_many
|
105
|
+
@collection.insert_one(@tribbles.first)
|
106
|
+
NewRelic::Agent.drop_buffered_data
|
107
|
+
|
108
|
+
@collection.update_many(@tribbles[0], "$set" => @tribbles[1])
|
109
|
+
|
110
|
+
metrics = build_test_metrics(:update)
|
111
|
+
expected = metrics_with_attributes(metrics)
|
112
|
+
|
113
|
+
assert_metrics_recorded(expected)
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_records_metrics_for_find
|
117
|
+
@collection.insert_one(@tribbles.first)
|
118
|
+
NewRelic::Agent.drop_buffered_data
|
119
|
+
|
120
|
+
@collection.find(@tribbles.first).to_a
|
121
|
+
|
122
|
+
metrics = build_test_metrics(:find)
|
123
|
+
expected = metrics_with_attributes(metrics)
|
124
|
+
|
125
|
+
assert_metrics_recorded(expected)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_records_metrics_for_find_one_and_delete
|
129
|
+
@collection.insert_one(@tribbles.first)
|
130
|
+
NewRelic::Agent.drop_buffered_data
|
131
|
+
|
132
|
+
@collection.find_one_and_delete(@tribbles.first)
|
133
|
+
|
134
|
+
metrics = build_test_metrics(:findandmodify)
|
135
|
+
expected = metrics_with_attributes(metrics)
|
136
|
+
|
137
|
+
assert_metrics_recorded(expected)
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_records_metrics_for_find_one_and_replace
|
141
|
+
@collection.insert_one(@tribbles.first)
|
142
|
+
NewRelic::Agent.drop_buffered_data
|
143
|
+
|
144
|
+
@collection.find_one_and_replace(@tribbles[0], @tribbles[1])
|
145
|
+
|
146
|
+
metrics = build_test_metrics(:findandmodify)
|
147
|
+
expected = metrics_with_attributes(metrics)
|
148
|
+
|
149
|
+
assert_metrics_recorded(expected)
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_records_metrics_for_find_one_and_update
|
153
|
+
@collection.insert_one(@tribbles.first)
|
154
|
+
NewRelic::Agent.drop_buffered_data
|
155
|
+
|
156
|
+
@collection.find_one_and_update(@tribbles[0], "$set" => @tribbles[1])
|
157
|
+
|
158
|
+
metrics = build_test_metrics(:findandmodify)
|
159
|
+
expected = metrics_with_attributes(metrics)
|
160
|
+
|
161
|
+
assert_metrics_recorded(expected)
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_records_metrics_for_distinct
|
165
|
+
@collection.distinct('name')
|
166
|
+
|
167
|
+
metrics = build_test_metrics(:distinct)
|
168
|
+
expected = metrics_with_attributes(metrics)
|
169
|
+
|
170
|
+
assert_metrics_recorded(expected)
|
171
|
+
end
|
172
|
+
|
173
|
+
def test_records_metrics_for_count
|
174
|
+
@collection.count
|
175
|
+
|
176
|
+
metrics = build_test_metrics(:count)
|
177
|
+
expected = metrics_with_attributes(metrics)
|
178
|
+
|
179
|
+
assert_metrics_recorded(expected)
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_drop_collection
|
183
|
+
@collection.drop
|
184
|
+
|
185
|
+
metrics = build_test_metrics(:drop)
|
186
|
+
expected = metrics_with_attributes(metrics)
|
187
|
+
|
188
|
+
assert_metrics_recorded(expected)
|
189
|
+
end
|
190
|
+
|
191
|
+
def test_web_scoped_metrics
|
192
|
+
in_web_transaction("webby") do
|
193
|
+
@collection.insert_one(@tribbles.first)
|
194
|
+
end
|
195
|
+
|
196
|
+
metric = statement_metric(:insert)
|
197
|
+
assert_metrics_recorded([[metric, "webby"]])
|
198
|
+
end
|
199
|
+
|
200
|
+
def statement_metric(action)
|
201
|
+
metrics = build_test_metrics(action)
|
202
|
+
metrics.select { |m| m.start_with?("Datastore/statement") }.first
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_background_scoped_metrics
|
206
|
+
in_background_transaction("backed-up") do
|
207
|
+
@collection.insert_one(@tribbles.first)
|
208
|
+
end
|
209
|
+
|
210
|
+
metric = statement_metric(:insert)
|
211
|
+
assert_metrics_recorded([[metric, "backed-up"]])
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_notices_nosql
|
215
|
+
node = nil
|
216
|
+
|
217
|
+
in_transaction do
|
218
|
+
@collection.insert_one(@tribbles.first)
|
219
|
+
|
220
|
+
node = find_last_transaction_node
|
221
|
+
end
|
222
|
+
|
223
|
+
expected = {
|
224
|
+
:database => @database_name,
|
225
|
+
:collection => @collection_name,
|
226
|
+
'insert' => @collection_name,
|
227
|
+
:operation => :insert,
|
228
|
+
'writeConcern' => { :w => 1 },
|
229
|
+
'ordered' => true
|
230
|
+
}
|
231
|
+
|
232
|
+
result = node.params[:statement]
|
233
|
+
|
234
|
+
assert_equal expected, result
|
235
|
+
end
|
236
|
+
|
237
|
+
def test_noticed_nosql_includes_operation
|
238
|
+
node = nil
|
239
|
+
|
240
|
+
in_transaction do
|
241
|
+
@collection.insert_one(@tribbles.first)
|
242
|
+
node = find_last_transaction_node
|
243
|
+
end
|
244
|
+
|
245
|
+
query = node.params[:statement]
|
246
|
+
|
247
|
+
assert_equal :insert, query[:operation]
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_noticed_nosql_includes_update_one_operation
|
251
|
+
node = nil
|
252
|
+
|
253
|
+
in_transaction do
|
254
|
+
@collection.update_one(@tribbles[0], @tribbles[1])
|
255
|
+
|
256
|
+
node = find_last_transaction_node
|
257
|
+
end
|
258
|
+
|
259
|
+
query = node.params[:statement]
|
260
|
+
|
261
|
+
assert_equal :update, query[:operation]
|
262
|
+
end
|
263
|
+
|
264
|
+
def test_noticed_nosql_includes_find_operation
|
265
|
+
node = nil
|
266
|
+
|
267
|
+
in_transaction do
|
268
|
+
@collection.insert_one(@tribbles.first)
|
269
|
+
@collection.find(@tribbles.first).to_a
|
270
|
+
node = find_last_transaction_node
|
271
|
+
end
|
272
|
+
|
273
|
+
query = node.params[:statement]
|
274
|
+
|
275
|
+
assert_equal 'find', query[:operation]
|
276
|
+
end
|
277
|
+
|
278
|
+
def test_noticed_nosql_does_not_contain_documents
|
279
|
+
node = nil
|
280
|
+
|
281
|
+
in_transaction do
|
282
|
+
@collection.insert_one(@tribbles.first)
|
283
|
+
node = find_last_transaction_node
|
284
|
+
end
|
285
|
+
|
286
|
+
statement = node.params[:statement]
|
287
|
+
|
288
|
+
refute statement.keys.include?(:documents), "Noticed NoSQL should not include documents: #{statement}"
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_noticed_nosql_does_not_contain_selector_values
|
292
|
+
@collection.insert_one({'password' => '$ecret'})
|
293
|
+
node = nil
|
294
|
+
|
295
|
+
in_transaction do
|
296
|
+
@collection.find({'password' => '$ecret'}).to_a
|
297
|
+
node = find_last_transaction_node
|
298
|
+
end
|
299
|
+
|
300
|
+
statement = node.params[:statement]
|
301
|
+
|
302
|
+
refute statement.inspect.include?('$secret')
|
303
|
+
|
304
|
+
assert_equal '?', statement['filter']['password']
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_web_requests_record_all_web_metric
|
308
|
+
NewRelic::Agent::Transaction.stubs(:recording_web_transaction?).returns(true)
|
309
|
+
@collection.insert_one(@tribbles.first)
|
310
|
+
|
311
|
+
metrics = build_test_metrics(:insert)
|
312
|
+
expected = metrics_with_attributes(metrics)
|
313
|
+
|
314
|
+
assert_metrics_recorded(expected)
|
315
|
+
end
|
316
|
+
|
317
|
+
def test_web_requests_do_not_record_all_other_metric
|
318
|
+
NewRelic::Agent::Transaction.stubs(:recording_web_transaction?).returns(true)
|
319
|
+
@collection.insert_one(@tribbles.first)
|
320
|
+
|
321
|
+
assert_metrics_not_recorded(['Datastore/allOther'])
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_other_requests_record_all_other_metric
|
325
|
+
NewRelic::Agent::Transaction.stubs(:recording_web_transaction?).returns(false)
|
326
|
+
@collection.insert_one(@tribbles.first)
|
327
|
+
|
328
|
+
metrics = build_test_metrics(:insert)
|
329
|
+
expected = metrics_with_attributes(metrics)
|
330
|
+
|
331
|
+
assert_metrics_recorded(expected)
|
332
|
+
end
|
333
|
+
|
334
|
+
def test_other_requests_do_not_record_all_web_metric
|
335
|
+
NewRelic::Agent::Transaction.stubs(:recording_web_transaction?).returns(false)
|
336
|
+
@collection.insert_one(@tribbles.first)
|
337
|
+
|
338
|
+
assert_metrics_not_recorded(['Datastore/allWeb'])
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|