newrelic_rpm 3.13.0.299 → 3.13.1.300
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|