newrelic_rpm 3.17.0.325 → 3.17.1.326

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +21 -0
  3. data/lib/new_relic/agent/datastores/metric_helper.rb +3 -11
  4. data/lib/new_relic/agent/hostname.rb +18 -0
  5. data/lib/new_relic/agent/instrumentation/active_record.rb +3 -7
  6. data/lib/new_relic/agent/instrumentation/active_record_helper.rb +10 -12
  7. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +5 -7
  8. data/lib/new_relic/agent/instrumentation/memcache.rb +2 -45
  9. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +157 -0
  10. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +34 -17
  11. data/lib/new_relic/agent/instrumentation/redis.rb +51 -11
  12. data/lib/new_relic/agent/traced_method_stack.rb +4 -0
  13. data/lib/new_relic/agent/transaction/datastore_segment.rb +27 -5
  14. data/lib/new_relic/agent/transaction/tracing.rb +4 -0
  15. data/lib/new_relic/version.rb +1 -1
  16. data/lib/tasks/config.rake +2 -1
  17. data/test/helpers/mongo_metric_builder.rb +11 -4
  18. data/test/multiverse/suites/memcached/dalli_test.rb +82 -1
  19. data/test/multiverse/suites/memcached/memcache_test_cases.rb +21 -8
  20. data/test/multiverse/suites/memcached/memcached_test.rb +21 -1
  21. data/test/multiverse/suites/mongo/mongo2_instrumentation_test.rb +33 -17
  22. data/test/multiverse/suites/redis/redis_instrumentation_test.rb +99 -7
  23. data/test/new_relic/agent/hostname_test.rb +23 -0
  24. data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +11 -0
  25. data/test/new_relic/agent/instrumentation/mongodb_command_subscriber_test.rb +37 -0
  26. data/test/new_relic/agent/transaction/datastore_segment_test.rb +12 -0
  27. data/test/new_relic/agent/transaction/tracing_test.rb +8 -0
  28. metadata +3 -2
@@ -5,6 +5,32 @@
5
5
  require 'new_relic/agent/datastores'
6
6
  require 'new_relic/agent/datastores/redis'
7
7
 
8
+ module NewRelic
9
+ module Agent
10
+ module Instrumentation
11
+ module Redis
12
+ extend self
13
+
14
+ UNKNOWN = "unknown".freeze
15
+
16
+ def host_for(client)
17
+ client.path ? NewRelic::Agent::Hostname.get : NewRelic::Agent::Hostname.get_external(client.host)
18
+ rescue => e
19
+ NewRelic::Agent.logger.debug "Failed to retrieve Redis host: #{e}"
20
+ UNKNOWN
21
+ end
22
+
23
+ def port_path_or_id_for(client)
24
+ client.path || client.port
25
+ rescue => e
26
+ NewRelic::Agent.logger.debug "Failed to retrieve Redis port_path_or_id: #{e}"
27
+ UNKNOWN
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+
8
34
  DependencyDetection.defer do
9
35
  # Why not :redis? newrelic-redis used that name, so avoid conflicting
10
36
  named :redis_instrumentation
@@ -32,14 +58,16 @@ DependencyDetection.defer do
32
58
  operation = args[0][0]
33
59
  statement = ::NewRelic::Agent::Datastores::Redis.format_command(args[0])
34
60
 
35
- if statement
36
- callback = Proc.new do |result, _, elapsed|
37
- NewRelic::Agent::Datastores.notice_statement(statement, elapsed)
38
- end
39
- end
61
+ hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
62
+ port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
40
63
 
41
- NewRelic::Agent::Datastores.wrap(NewRelic::Agent::Datastores::Redis::PRODUCT_NAME, operation, nil, callback) do
64
+ segment = NewRelic::Agent::Transaction.start_datastore_segment(NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
65
+ operation, nil, hostname, port_path_or_id, db)
66
+ begin
67
+ segment.notice_nosql_statement(statement) if statement
42
68
  call_without_new_relic(*args, &block)
69
+ ensure
70
+ segment.finish
43
71
  end
44
72
  end
45
73
 
@@ -50,20 +78,32 @@ DependencyDetection.defer do
50
78
  operation = pipeline.is_a?(::Redis::Pipeline::Multi) ? NewRelic::Agent::Datastores::Redis::MULTI_OPERATION : NewRelic::Agent::Datastores::Redis::PIPELINE_OPERATION
51
79
  statement = ::NewRelic::Agent::Datastores::Redis.format_pipeline_commands(pipeline.commands)
52
80
 
53
- callback = Proc.new do |result, _, elapsed|
54
- NewRelic::Agent::Datastores.notice_statement(statement, elapsed)
55
- end
81
+ hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
82
+ port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
56
83
 
57
- NewRelic::Agent::Datastores.wrap(NewRelic::Agent::Datastores::Redis::PRODUCT_NAME, operation, nil, callback) do
84
+ segment = NewRelic::Agent::Transaction.start_datastore_segment(NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
85
+ operation, nil, hostname, port_path_or_id, db)
86
+ begin
87
+ segment.notice_nosql_statement(statement)
58
88
  call_pipeline_without_new_relic(*args, &block)
89
+ ensure
90
+ segment.finish
59
91
  end
60
92
  end
61
93
 
62
94
  alias_method :connect_without_new_relic, :connect
63
95
 
64
96
  def connect(*args, &block)
65
- NewRelic::Agent::Datastores.wrap(NewRelic::Agent::Datastores::Redis::PRODUCT_NAME, NewRelic::Agent::Datastores::Redis::CONNECT) do
97
+ hostname = NewRelic::Agent::Instrumentation::Redis.host_for(self)
98
+ port_path_or_id = NewRelic::Agent::Instrumentation::Redis.port_path_or_id_for(self)
99
+
100
+ segment = NewRelic::Agent::Transaction.start_datastore_segment(NewRelic::Agent::Datastores::Redis::PRODUCT_NAME,
101
+ NewRelic::Agent::Datastores::Redis::CONNECT, nil, hostname, port_path_or_id, db)
102
+
103
+ begin
66
104
  connect_without_new_relic(*args, &block)
105
+ ensure
106
+ segment.finish
67
107
  end
68
108
  end
69
109
  end
@@ -100,6 +100,10 @@ module NewRelic
100
100
  def empty?
101
101
  @stack.empty?
102
102
  end
103
+
104
+ def last
105
+ @stack.last
106
+ end
103
107
  end
104
108
  end
105
109
  end
@@ -10,18 +10,23 @@ module NewRelic
10
10
  module Agent
11
11
  class Transaction
12
12
  class DatastoreSegment < Segment
13
- attr_reader :product, :operation, :collection, :sql_statement, :host, :port_path_or_id, :database_name
13
+ attr_reader :product, :operation, :collection, :sql_statement, :nosql_statement, :port_path_or_id
14
+ attr_accessor :host, :database_name
14
15
 
15
16
  def initialize product, operation, collection = nil, host = nil, port_path_or_id = nil, database_name=nil
16
17
  @product = product
17
18
  @operation = operation
18
19
  @collection = collection
19
20
  @sql_statement = nil
21
+ @nosql_statement = nil
20
22
  @host = host
21
- @port_path_or_id = port_path_or_id
22
- @database_name = database_name
23
- super Datastores::MetricHelper.scoped_metric_for(product, operation, collection),
24
- Datastores::MetricHelper.unscoped_metrics_for(product, operation, collection, host, port_path_or_id)
23
+ self.port_path_or_id = port_path_or_id
24
+ @database_name = database_name ? database_name.to_s : nil
25
+ super Datastores::MetricHelper.scoped_metric_for(product, operation, collection)
26
+ end
27
+
28
+ def port_path_or_id= ppi
29
+ @port_path_or_id = ppi ? ppi.to_s : nil
25
30
  end
26
31
 
27
32
  def notice_sql sql
@@ -34,11 +39,22 @@ module NewRelic
34
39
  @sql_statement = Database::Statement.new sql, config, explainer, binds, name, host, port_path_or_id, database_name
35
40
  end
36
41
 
42
+ def notice_nosql_statement nosql_statement
43
+ return unless record_sql?
44
+ @nosql_statement = nosql_statement
45
+ end
46
+
37
47
  private
38
48
 
49
+ def record_metrics
50
+ @unscoped_metrics = Datastores::MetricHelper.unscoped_metrics_for(product, operation, collection, host, port_path_or_id)
51
+ super
52
+ end
53
+
39
54
  def segment_complete
40
55
  add_segment_parameters
41
56
  notice_sql_statement if sql_statement
57
+ notice_statement if nosql_statement
42
58
  end
43
59
 
44
60
  def add_segment_parameters
@@ -65,6 +81,12 @@ module NewRelic
65
81
  def notice_sql_statement
66
82
  NewRelic::Agent.instance.transaction_sampler.notice_sql_statement(sql_statement, duration)
67
83
  NewRelic::Agent.instance.sql_sampler.notice_sql_statement(sql_statement.dup, name, duration)
84
+ nil
85
+ end
86
+
87
+ def notice_statement
88
+ NewRelic::Agent.instance.transaction_sampler.notice_nosql_statement(nosql_statement, duration)
89
+ nil
68
90
  end
69
91
 
70
92
  def record_sql?
@@ -47,6 +47,10 @@ module NewRelic
47
47
  def segment_complete segment
48
48
  state.traced_method_stack.pop_frame(state, segment, segment.name, segment.end_time, segment.record_metrics?)
49
49
  end
50
+
51
+ def current_segment
52
+ state.traced_method_stack.last
53
+ end
50
54
  end
51
55
  end
52
56
  end
@@ -12,7 +12,7 @@ module NewRelic
12
12
 
13
13
  MAJOR = 3
14
14
  MINOR = 17
15
- TINY = 0
15
+ TINY = 1
16
16
 
17
17
  begin
18
18
  require File.join(File.dirname(__FILE__), 'build')
@@ -23,9 +23,10 @@ namespace :newrelic do
23
23
 
24
24
  def output(format)
25
25
  config_hash = build_config_hash
26
- flatten_config_hash(config_hash)
26
+ sections = flatten_config_hash(config_hash)
27
27
 
28
28
  puts build_erb(format).result(binding)
29
+ sections # silences unused warning to return this
29
30
  end
30
31
 
31
32
  def build_config_hash
@@ -7,10 +7,17 @@ require 'new_relic/agent/datastores/mongo/metric_translator'
7
7
  module NewRelic
8
8
  module TestHelpers
9
9
  module MongoMetricBuilder
10
- def build_test_metrics(name)
11
- NewRelic::Agent::Datastores::MetricHelper.metrics_for("MongoDB",
12
- name,
13
- @collection_name)
10
+ def build_test_metrics(name, instance_metrics=false)
11
+ host = nil
12
+ port = nil
13
+
14
+ if instance_metrics
15
+ host = NewRelic::Agent::Hostname.get
16
+ port = 27017
17
+ end
18
+
19
+ NewRelic::Agent::Datastores::MetricHelper.metrics_for(
20
+ "MongoDB", name, @collection_name, host, port)
14
21
  end
15
22
 
16
23
  def metrics_with_attributes(metrics, attributes = { :call_count => 1 })
@@ -8,9 +8,91 @@ if defined?(Dalli)
8
8
  class DalliTest < Minitest::Test
9
9
  include MemcacheTestCases
10
10
 
11
+ MULTI_OPERATIONS = [:get_multi, :get_multi_cas]
12
+
11
13
  def setup
12
14
  @cache = Dalli::Client.new("127.0.0.1:11211", :socket_timeout => 2.0)
13
15
  end
16
+
17
+ if ::NewRelic::Agent::Instrumentation::Memcache::Dalli.supports_datastore_instances?
18
+
19
+ def test_get_multi_in_web_with_capture_memcache_keys
20
+ with_config(:capture_memcache_keys => true) do
21
+ key = set_key_for_testcase
22
+ in_web_transaction("Controller/#{self.class}/action") do
23
+ @cache.get_multi(key)
24
+ end
25
+ trace = last_transaction_trace
26
+ segment = find_node_with_name trace, 'Datastore/operation/Memcached/get_multi_request'
27
+ assert_equal "get_multi_request [\"#{key}\"]", segment[:statement]
28
+ end
29
+ end
30
+
31
+ def test_assign_instance_to_with_ip_and_port
32
+ NewRelic::Agent::Hostname.stubs(:get).returns("jonan.pizza_cube")
33
+ segment = mock('datastore_segment')
34
+ segment.expects(:host=).with('jonan.pizza_cube')
35
+ segment.expects(:port_path_or_id=).with(11211)
36
+ server = ::Dalli::Server.new '127.0.0.1:11211'
37
+ ::NewRelic::Agent::Instrumentation::Memcache::Dalli.assign_instance_to(segment, server)
38
+ end
39
+
40
+ def test_assign_instance_to_with_name_and_port
41
+ NewRelic::Agent::Hostname.stubs(:get).returns("jonan.pizza_cube")
42
+ segment = mock('datastore_segment')
43
+ segment.expects(:host=).with('jonan.gummy_planet')
44
+ segment.expects(:port_path_or_id=).with(11211)
45
+ server = ::Dalli::Server.new 'jonan.gummy_planet:11211'
46
+ ::NewRelic::Agent::Instrumentation::Memcache::Dalli.assign_instance_to(segment, server)
47
+ end
48
+
49
+ def test_assign_instance_to_with_unix_domain_socket
50
+ NewRelic::Agent::Hostname.stubs(:get).returns("jonan.pizza_cube")
51
+ segment = mock('datastore_segment')
52
+ segment.expects(:host=).with('jonan.pizza_cube')
53
+ segment.expects(:port_path_or_id=).with('/tmp/jonanfs.sock')
54
+ server = ::Dalli::Server.new '/tmp/jonanfs.sock'
55
+ ::NewRelic::Agent::Instrumentation::Memcache::Dalli.assign_instance_to(segment, server)
56
+ end
57
+
58
+ def test_assign_instance_to_when_exception_raised
59
+ NewRelic::Agent::Hostname.stubs(:get).raises("oops")
60
+ segment = mock('datastore_segment')
61
+ segment.expects(:host=).with('unknown')
62
+ segment.expects(:port_path_or_id=).with('unknown')
63
+ server = ::Dalli::Server.new '/tmp/jonanfs.sock'
64
+ ::NewRelic::Agent::Instrumentation::Memcache::Dalli.assign_instance_to(segment, server)
65
+ end
66
+
67
+ end
68
+
69
+ def instance_metric
70
+ "Datastore/instance/Memcached/#{NewRelic::Agent::Hostname.get}/11211"
71
+ end
72
+
73
+ def expected_web_metrics(command)
74
+ if ::NewRelic::Agent::Instrumentation::Memcache::Dalli.supports_datastore_instances?
75
+ datastore_command = MULTI_OPERATIONS.include?(command) ? :get_multi_request : command
76
+ metrics = super(datastore_command)
77
+ metrics.unshift instance_metric
78
+ metrics.unshift "Ruby/Memcached/Dalli/#{command}" if command != datastore_command
79
+ metrics
80
+ else
81
+ super
82
+ end
83
+ end
84
+
85
+ def expected_bg_metrics(command)
86
+ if ::NewRelic::Agent::Instrumentation::Memcache::Dalli.supports_datastore_instances?
87
+ datastore_command = MULTI_OPERATIONS.include?(command) ? :get_multi_request : command
88
+ metrics = super(datastore_command)
89
+ metrics.unshift instance_metric
90
+ metrics.unshift "Ruby/Memcached/Dalli/#{command}" if command != datastore_command
91
+ metrics
92
+ else
93
+ super
94
+ end
95
+ end
14
96
  end
15
97
 
16
98
  if Dalli::VERSION >= '2.7'
@@ -50,7 +132,6 @@ if defined?(Dalli)
50
132
  assert_equal value.values.first.first, @cache.get(@cas_key)
51
133
  end
52
134
 
53
-
54
135
  def test_set_cas
55
136
  expected_metrics = expected_web_metrics(:set_cas)
56
137
 
@@ -48,7 +48,7 @@ module MemcacheTestCases
48
48
  end
49
49
 
50
50
  def assert_memcache_metrics_recorded(expected_metrics)
51
- assert_metrics_recorded_exclusive expected_metrics, :filter => /^memcache.*/i
51
+ assert_metrics_recorded_exclusive expected_metrics, :filter => /^datastore.*/i
52
52
  end
53
53
 
54
54
  def test_get_in_web
@@ -289,14 +289,27 @@ module MemcacheTestCases
289
289
  end
290
290
 
291
291
  def test_cas_in_background
292
- key = set_key_for_testcase(1)
293
- expected_metrics = expected_bg_metrics(:cas)
292
+ key = set_key_for_testcase(1)
293
+ expected_metrics = expected_bg_metrics(:cas)
294
294
 
295
- in_background_transaction("OtherTransaction/Background/#{self.class}/bg_task") do
296
- @cache.cas(key) {|val| val += 2}
297
- end
295
+ in_background_transaction("OtherTransaction/Background/#{self.class}/bg_task") do
296
+ @cache.cas(key) {|val| val += 2}
297
+ end
298
+
299
+ assert_memcache_metrics_recorded expected_metrics
300
+ assert_equal 3, @cache.get(key)
301
+ end
298
302
 
299
- assert_memcache_metrics_recorded expected_metrics
300
- assert_equal 3, @cache.get(key)
303
+ def test_get_in_web_with_capture_memcache_keys
304
+ with_config(:capture_memcache_keys => true) do
305
+ key = set_key_for_testcase
306
+ in_web_transaction("Controller/#{self.class}/action") do
307
+ @cache.get(key)
308
+ end
309
+ trace = last_transaction_trace
310
+ segment = find_node_with_name trace, 'Datastore/operation/Memcached/get'
311
+ assert_equal "get \"#{key}\"", segment[:statement]
301
312
  end
313
+ end
314
+
302
315
  end
@@ -12,11 +12,26 @@ if defined?(Memcached)
12
12
  @cache = Memcached.new('localhost', :support_cas => true)
13
13
  end
14
14
 
15
+ def additional_web_metrics_for command
16
+ [
17
+ "Datastore/operation/Memcached/#{command}",
18
+ ["Datastore/operation/Memcached/#{command}", "Controller/#{self.class}/action"]
19
+ ]
20
+ end
21
+
22
+ def additional_bg_metrics_for command
23
+ [
24
+ "Datastore/operation/Memcached/#{command}",
25
+ ["Datastore/operation/Memcached/#{command}", "OtherTransaction/Background/#{self.class}/bg_task"]
26
+ ]
27
+ end
28
+
15
29
  def test_get_in_web
16
30
  if Memcached::VERSION >= '1.8.0'
17
31
  key = set_key_for_testcase
18
32
 
19
33
  expected_metrics = expected_web_metrics(:single_get)
34
+ expected_metrics += additional_web_metrics_for(:get)
20
35
 
21
36
  in_web_transaction("Controller/#{self.class}/action") do
22
37
  @cache.get(key)
@@ -33,6 +48,7 @@ if defined?(Memcached)
33
48
  key = set_key_for_testcase
34
49
 
35
50
  expected_metrics = expected_web_metrics(:multi_get)
51
+ expected_metrics += additional_web_metrics_for(:get)
36
52
 
37
53
  in_web_transaction("Controller/#{self.class}/action") do
38
54
  @cache.get([key])
@@ -72,6 +88,7 @@ if defined?(Memcached)
72
88
 
73
89
  if Memcached::VERSION >= '1.8.0'
74
90
  expected_metrics = (expected_web_metrics(:single_get) + expected_web_metrics(:single_cas)).uniq
91
+ expected_metrics += additional_web_metrics_for(:cas)
75
92
  else
76
93
  expected_metrics = expected_web_metrics(:cas)
77
94
  end
@@ -89,6 +106,7 @@ if defined?(Memcached)
89
106
  key = set_key_for_testcase
90
107
 
91
108
  expected_metrics = expected_bg_metrics(:single_get)
109
+ expected_metrics += additional_bg_metrics_for(:get)
92
110
 
93
111
  in_background_transaction("OtherTransaction/Background/#{self.class}/bg_task") do
94
112
  @cache.get(key)
@@ -106,6 +124,7 @@ if defined?(Memcached)
106
124
  key = set_key_for_testcase
107
125
 
108
126
  expected_metrics = expected_bg_metrics(:multi_get)
127
+ expected_metrics += additional_bg_metrics_for(:get)
109
128
 
110
129
  in_background_transaction("OtherTransaction/Background/#{self.class}/bg_task") do
111
130
  @cache.get([key])
@@ -144,6 +163,7 @@ if defined?(Memcached)
144
163
  key = set_key_for_testcase(1)
145
164
  if Memcached::VERSION >= '1.8.0'
146
165
  expected_metrics = (expected_bg_metrics(:single_get) + expected_bg_metrics(:single_cas)).uniq
166
+ expected_metrics += additional_bg_metrics_for(:cas)
147
167
  else
148
168
  expected_metrics = expected_bg_metrics(:cas)
149
169
  end
@@ -156,4 +176,4 @@ if defined?(Memcached)
156
176
  assert_equal 3, @cache.get(key)
157
177
  end
158
178
  end
159
- end
179
+ end
@@ -38,7 +38,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
38
38
  def test_records_metrics_for_insert_one
39
39
  @collection.insert_one(@tribbles.first)
40
40
 
41
- metrics = build_test_metrics(:insert)
41
+ metrics = build_test_metrics(:insert, true)
42
42
  expected = metrics_with_attributes(metrics)
43
43
 
44
44
  assert_metrics_recorded(expected)
@@ -47,7 +47,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
47
47
  def test_records_metrics_for_insert_many
48
48
  @collection.insert_many(@tribbles)
49
49
 
50
- metrics = build_test_metrics(:insert)
50
+ metrics = build_test_metrics(:insert, true)
51
51
  expected = metrics_with_attributes(metrics)
52
52
 
53
53
  assert_metrics_recorded(expected)
@@ -59,7 +59,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
59
59
 
60
60
  @collection.delete_one(@tribbles.first)
61
61
 
62
- metrics = build_test_metrics(:delete)
62
+ metrics = build_test_metrics(:delete, true)
63
63
  expected = metrics_with_attributes(metrics)
64
64
 
65
65
  assert_metrics_recorded(expected)
@@ -71,7 +71,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
71
71
 
72
72
  @collection.delete_many(@tribbles.first)
73
73
 
74
- metrics = build_test_metrics(:delete)
74
+ metrics = build_test_metrics(:delete, true)
75
75
  expected = metrics_with_attributes(metrics)
76
76
 
77
77
  assert_metrics_recorded(expected)
@@ -83,7 +83,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
83
83
 
84
84
  @collection.replace_one(@tribbles[0], @tribbles[1])
85
85
 
86
- metrics = build_test_metrics(:update)
86
+ metrics = build_test_metrics(:update, true)
87
87
  expected = metrics_with_attributes(metrics)
88
88
 
89
89
  assert_metrics_recorded(expected)
@@ -95,7 +95,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
95
95
 
96
96
  @collection.update_one(@tribbles[0], "$set" => @tribbles[1])
97
97
 
98
- metrics = build_test_metrics(:update)
98
+ metrics = build_test_metrics(:update, true)
99
99
  expected = metrics_with_attributes(metrics)
100
100
 
101
101
  assert_metrics_recorded(expected)
@@ -107,7 +107,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
107
107
 
108
108
  @collection.update_many(@tribbles[0], "$set" => @tribbles[1])
109
109
 
110
- metrics = build_test_metrics(:update)
110
+ metrics = build_test_metrics(:update, true)
111
111
  expected = metrics_with_attributes(metrics)
112
112
 
113
113
  assert_metrics_recorded(expected)
@@ -119,7 +119,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
119
119
 
120
120
  @collection.find(@tribbles.first).to_a
121
121
 
122
- metrics = build_test_metrics(:find)
122
+ metrics = build_test_metrics(:find, true)
123
123
  expected = metrics_with_attributes(metrics)
124
124
 
125
125
  assert_metrics_recorded(expected)
@@ -131,7 +131,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
131
131
 
132
132
  @collection.find_one_and_delete(@tribbles.first)
133
133
 
134
- metrics = build_test_metrics(:findandmodify)
134
+ metrics = build_test_metrics(:findandmodify, true)
135
135
  expected = metrics_with_attributes(metrics)
136
136
 
137
137
  assert_metrics_recorded(expected)
@@ -143,7 +143,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
143
143
 
144
144
  @collection.find_one_and_replace(@tribbles[0], @tribbles[1])
145
145
 
146
- metrics = build_test_metrics(:findandmodify)
146
+ metrics = build_test_metrics(:findandmodify, true)
147
147
  expected = metrics_with_attributes(metrics)
148
148
 
149
149
  assert_metrics_recorded(expected)
@@ -155,7 +155,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
155
155
 
156
156
  @collection.find_one_and_update(@tribbles[0], "$set" => @tribbles[1])
157
157
 
158
- metrics = build_test_metrics(:findandmodify)
158
+ metrics = build_test_metrics(:findandmodify, true)
159
159
  expected = metrics_with_attributes(metrics)
160
160
 
161
161
  assert_metrics_recorded(expected)
@@ -164,7 +164,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
164
164
  def test_records_metrics_for_distinct
165
165
  @collection.distinct('name')
166
166
 
167
- metrics = build_test_metrics(:distinct)
167
+ metrics = build_test_metrics(:distinct, true)
168
168
  expected = metrics_with_attributes(metrics)
169
169
 
170
170
  assert_metrics_recorded(expected)
@@ -173,7 +173,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
173
173
  def test_records_metrics_for_count
174
174
  @collection.count
175
175
 
176
- metrics = build_test_metrics(:count)
176
+ metrics = build_test_metrics(:count, true)
177
177
  expected = metrics_with_attributes(metrics)
178
178
 
179
179
  assert_metrics_recorded(expected)
@@ -192,6 +192,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
192
192
  "Datastore/statement/MongoDB/#{@collection_name}/getMore" => {:call_count=>2},
193
193
  "Datastore/operation/MongoDB/find" => {:call_count=>1},
194
194
  "Datastore/operation/MongoDB/getMore" => {:call_count=>2},
195
+ "Datastore/instance/MongoDB/#{NewRelic::Agent::Hostname.get}/27017" => {:call_count=>3},
195
196
  "Datastore/MongoDB/allWeb" => {:call_count=>3},
196
197
  "Datastore/MongoDB/all" => {:call_count=>3},
197
198
  "Datastore/allWeb" => { :call_count=>3},
@@ -224,10 +225,25 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
224
225
  assert_equal expected, actual
225
226
  end
226
227
 
228
+ def test_trace_nodes_have_instance_attributes
229
+ @collection.insert_one :name => "test", :active => true
230
+ NewRelic::Agent.drop_buffered_data
231
+ in_transaction "webby" do
232
+ @collection.find(:active => true).to_a
233
+ end
234
+
235
+ trace = last_transaction_trace
236
+ node = find_node_with_name_matching trace, /^Datastore\//
237
+
238
+ assert_equal NewRelic::Agent::Hostname.get, node[:host]
239
+ assert_equal '27017', node[:port_path_or_id]
240
+ assert_equal @database_name, node[:database_name]
241
+ end
242
+
227
243
  def test_drop_collection
228
244
  @collection.drop
229
245
 
230
- metrics = build_test_metrics(:drop)
246
+ metrics = build_test_metrics(:drop, true)
231
247
  expected = metrics_with_attributes(metrics)
232
248
 
233
249
  assert_metrics_recorded(expected)
@@ -243,7 +259,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
243
259
  end
244
260
 
245
261
  def statement_metric(action)
246
- metrics = build_test_metrics(action)
262
+ metrics = build_test_metrics(action, true)
247
263
  metrics.select { |m| m.start_with?("Datastore/statement") }.first
248
264
  end
249
265
 
@@ -354,7 +370,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
354
370
  NewRelic::Agent::Transaction.stubs(:recording_web_transaction?).returns(true)
355
371
  @collection.insert_one(@tribbles.first)
356
372
 
357
- metrics = build_test_metrics(:insert)
373
+ metrics = build_test_metrics(:insert, true)
358
374
  expected = metrics_with_attributes(metrics)
359
375
 
360
376
  assert_metrics_recorded(expected)
@@ -371,7 +387,7 @@ if NewRelic::Agent::Datastores::Mongo.is_supported_version? &&
371
387
  NewRelic::Agent::Transaction.stubs(:recording_web_transaction?).returns(false)
372
388
  @collection.insert_one(@tribbles.first)
373
389
 
374
- metrics = build_test_metrics(:insert)
390
+ metrics = build_test_metrics(:insert, true)
375
391
  expected = metrics_with_attributes(metrics)
376
392
 
377
393
  assert_metrics_recorded(expected)