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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -0
  3. data/CHANGELOG +36 -1
  4. data/lib/new_relic/agent/agent.rb +0 -1
  5. data/lib/new_relic/agent/database.rb +1 -1
  6. data/lib/new_relic/agent/datastores/mongo.rb +8 -7
  7. data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +49 -0
  8. data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +2 -2
  9. data/lib/new_relic/agent/error_collector.rb +12 -51
  10. data/lib/new_relic/agent/error_trace_aggregator.rb +89 -0
  11. data/lib/new_relic/agent/instrumentation/active_record.rb +1 -1
  12. data/lib/new_relic/agent/instrumentation/active_record_4.rb +1 -1
  13. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +26 -1
  14. data/lib/new_relic/agent/instrumentation/mongo.rb +16 -1
  15. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +74 -0
  16. data/lib/new_relic/agent/supported_versions.rb +15 -1
  17. data/lib/new_relic/agent/system_info.rb +5 -0
  18. data/lib/new_relic/recipes/capistrano3.rb +1 -1
  19. data/lib/new_relic/recipes/capistrano_legacy.rb +1 -1
  20. data/lib/new_relic/version.rb +1 -1
  21. data/newrelic_rpm.gemspec +1 -1
  22. data/test/environments/lib/environments/runner.rb +1 -0
  23. data/test/fixtures/cross_agent_tests/proc_cpuinfo/README.md +4 -0
  24. data/test/fixtures/cross_agent_tests/proc_cpuinfo/malformed_file.txt +3 -0
  25. data/test/multiverse/lib/multiverse/suite.rb +4 -4
  26. data/test/multiverse/suites/active_record/active_record_test.rb +67 -26
  27. data/test/multiverse/suites/agent_only/start_up_test.rb +17 -3
  28. data/test/multiverse/suites/config_file_loading/Envfile +1 -1
  29. data/test/multiverse/suites/mongo/Envfile +3 -1
  30. data/test/multiverse/suites/mongo/mongo2_instrumentation_test.rb +344 -0
  31. data/test/multiverse/suites/mongo/mongo_connection_test.rb +2 -1
  32. data/test/multiverse/suites/mongo/mongo_instrumentation_test.rb +2 -1
  33. data/test/multiverse/suites/mongo/mongo_unsupported_version_test.rb +1 -1
  34. data/test/multiverse/suites/rails/rails3_app/app_rails3_plus.rb +7 -0
  35. data/test/multiverse/suites/sidekiq/Envfile +1 -1
  36. data/test/new_relic/agent/agent/start_test.rb +0 -5
  37. data/test/new_relic/agent/database_test.rb +8 -1
  38. data/test/new_relic/agent/datastores/mongo/event_formatter_test.rb +154 -0
  39. data/test/new_relic/agent/error_collector_test.rb +0 -13
  40. data/test/new_relic/agent/error_trace_aggregator_test.rb +30 -0
  41. data/test/new_relic/agent/instrumentation/mongodb_command_subscriber_test.rb +72 -0
  42. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +24 -22
  43. data/test/new_relic/agent/system_info_test.rb +9 -1
  44. data/test/new_relic/rack/error_collector_test.rb +1 -2
  45. 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
- install_mongo_instrumentation
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 => [">= 1.8.0", "< 2.0.0"],
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)}"
@@ -12,7 +12,7 @@ module NewRelic
12
12
 
13
13
  MAJOR = 3
14
14
  MINOR = 13
15
- TINY = 0
15
+ TINY = 1
16
16
 
17
17
  begin
18
18
  require File.join(File.dirname(__FILE__), 'build')
@@ -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.
@@ -0,0 +1,3 @@
1
+ This is a random text file that does NOT adhere to the /proc/cpuinfo format.
2
+ xxxYYYZZz
3
+
@@ -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 defined?(::ActiveRecord::VERSION) && ::ActiveRecord::VERSION::MAJOR >= 3
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 defined?(::ActiveRecord::VERSION) && ::ActiveRecord::VERSION::MAJOR >= 4
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.each {|noise| output.gsub!(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
- output.gsub!(GIT_NOISE, "")
68
- output.chomp!
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('../../../../')
@@ -1,7 +1,9 @@
1
1
  if RUBY_VERSION >= '1.9.3'
2
+ gemfile <<-RB
3
+ gem 'mongo', '~>2.1.0'
4
+ RB
2
5
  gemfile <<-RB
3
6
  gem 'mongo', '~>2.0.1'
4
- gem 'bson_ext', :platforms => :ruby
5
7
  RB
6
8
  end
7
9
 
@@ -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