newrelic_rpm 4.4.0.336 → 4.5.0.337

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +25 -25
  3. data/CHANGELOG.md +38 -0
  4. data/lib/new_relic/agent.rb +41 -9
  5. data/lib/new_relic/agent/agent.rb +9 -3
  6. data/lib/new_relic/agent/cross_app_tracing.rb +1 -7
  7. data/lib/new_relic/agent/database.rb +2 -1
  8. data/lib/new_relic/agent/datastores.rb +10 -2
  9. data/lib/new_relic/agent/instrumentation/active_job.rb +4 -0
  10. data/lib/new_relic/agent/instrumentation/active_record.rb +1 -1
  11. data/lib/new_relic/agent/instrumentation/active_record_4.rb +2 -0
  12. data/lib/new_relic/agent/instrumentation/active_record_5.rb +3 -0
  13. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +1 -1
  14. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +6 -0
  15. data/lib/new_relic/agent/instrumentation/curb.rb +1 -1
  16. data/lib/new_relic/agent/instrumentation/data_mapper.rb +1 -1
  17. data/lib/new_relic/agent/instrumentation/excon/connection.rb +1 -1
  18. data/lib/new_relic/agent/instrumentation/excon/middleware.rb +1 -1
  19. data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -1
  20. data/lib/new_relic/agent/instrumentation/memcache.rb +1 -1
  21. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +2 -2
  22. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +1 -1
  23. data/lib/new_relic/agent/instrumentation/rails4/action_controller.rb +3 -0
  24. data/lib/new_relic/agent/instrumentation/rails4/action_view.rb +2 -0
  25. data/lib/new_relic/agent/instrumentation/rails5/action_cable.rb +3 -0
  26. data/lib/new_relic/agent/instrumentation/rails5/action_controller.rb +3 -0
  27. data/lib/new_relic/agent/instrumentation/rails5/action_view.rb +3 -1
  28. data/lib/new_relic/agent/instrumentation/redis.rb +3 -3
  29. data/lib/new_relic/agent/instrumentation/typhoeus.rb +1 -1
  30. data/lib/new_relic/agent/method_tracer.rb +4 -0
  31. data/lib/new_relic/agent/method_tracer_helpers.rb +1 -1
  32. data/lib/new_relic/agent/prepend_supportability.rb +16 -0
  33. data/lib/new_relic/agent/transaction.rb +2 -0
  34. data/lib/new_relic/agent/transaction/external_request_segment.rb +12 -3
  35. data/lib/new_relic/supportability_helper.rb +63 -0
  36. data/lib/new_relic/version.rb +1 -1
  37. data/lib/sequel/extensions/newrelic_instrumentation.rb +1 -1
  38. data/lib/sequel/plugins/newrelic_instrumentation.rb +1 -1
  39. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b9d189b04c1171316153a227be91c6abad18f00a
4
- data.tar.gz: 2b1c100c3778ba5fa95937d6d87bbe9949fb99a1
3
+ metadata.gz: 5163342ef18117639611f7ff1658dbd48aaaae2c
4
+ data.tar.gz: d2d78f11f66675e6887ea6a9a8ec3606d5e45704
5
5
  SHA512:
6
- metadata.gz: e77e92639fc53364aaf68627c4d41f1bc9e61ad6f2ce1978732d206a3b7eaf84ee72f06a934a92087179b3c534ea4803d7da5fe6d134416bd32b14f1e7532483
7
- data.tar.gz: 566143ee90b3f3c027cb4201824766986d62c66cc78f2311da53861f23dcd272deb528dabceb36efd37db5fcc8e9f8b28f45d12f3729362feea58044dbe87b76
6
+ metadata.gz: 3c371c48d1eaddd30865ee2d1fc1f3fef8fc55182c30d35be4d04b858d276132540f9ffb65f23ec5d231afc0be8991545032b2ef3628add899d1a3c473d7e7e6
7
+ data.tar.gz: 075fc7e970ac1c0d99ee4152550551cc85f3f764bfdd8ee6643f021710242ab2d47985d4c259f4adbd4544ae74826e2d900b1a9152bb882098f58d36d2e0aacb
@@ -32,10 +32,10 @@ notifications:
32
32
 
33
33
  rvm:
34
34
  # Run slowest builds first to try and optimize overall cycle time.
35
- - jruby-9.1.12.0
36
- - 2.4.1
37
- - 2.3.4
38
- - 2.2.7
35
+ - jruby-9.1.13.0
36
+ - 2.4.2
37
+ - 2.3.5
38
+ - 2.2.8
39
39
  - 2.1.10
40
40
  - 2.0.0-p648
41
41
 
@@ -81,39 +81,39 @@ matrix:
81
81
  exclude:
82
82
  # Unsupported Rails/Ruby combinations
83
83
  # 2.4
84
- - rvm: 2.4.1
84
+ - rvm: 2.4.2
85
85
  env: TYPE=UNIT ENVIRONMENT=rails21
86
- - rvm: 2.4.1
86
+ - rvm: 2.4.2
87
87
  env: TYPE=UNIT ENVIRONMENT=rails22
88
- - rvm: 2.4.1
88
+ - rvm: 2.4.2
89
89
  env: TYPE=UNIT ENVIRONMENT=rails23
90
- - rvm: 2.4.1
90
+ - rvm: 2.4.2
91
91
  env: TYPE=UNIT ENVIRONMENT=rails30
92
- - rvm: 2.4.1
92
+ - rvm: 2.4.2
93
93
  env: TYPE=UNIT ENVIRONMENT=rails31
94
- - rvm: 2.4.1
94
+ - rvm: 2.4.2
95
95
  env: TYPE=UNIT ENVIRONMENT=rails32
96
- - rvm: 2.4.1
96
+ - rvm: 2.4.2
97
97
  env: TYPE=UNIT ENVIRONMENT=rails40
98
- - rvm: 2.4.1
98
+ - rvm: 2.4.2
99
99
  env: TYPE=UNIT ENVIRONMENT=rails41
100
- - rvm: 2.4.1
100
+ - rvm: 2.4.2
101
101
  env: TYPE=UNIT ENVIRONMENT=rails42
102
102
 
103
103
  # 2.3
104
- - rvm: 2.3.4
104
+ - rvm: 2.3.5
105
105
  env: TYPE=UNIT ENVIRONMENT=rails21
106
- - rvm: 2.3.4
106
+ - rvm: 2.3.5
107
107
  env: TYPE=UNIT ENVIRONMENT=rails22
108
- - rvm: 2.3.4
108
+ - rvm: 2.3.5
109
109
  env: TYPE=UNIT ENVIRONMENT=rails23
110
110
 
111
111
  # 2.2
112
- - rvm: 2.2.7
112
+ - rvm: 2.2.8
113
113
  env: TYPE=UNIT ENVIRONMENT=rails21
114
- - rvm: 2.2.7
114
+ - rvm: 2.2.8
115
115
  env: TYPE=UNIT ENVIRONMENT=rails22
116
- - rvm: 2.2.7
116
+ - rvm: 2.2.8
117
117
  env: TYPE=UNIT ENVIRONMENT=rails23
118
118
 
119
119
  # 2.1
@@ -141,15 +141,15 @@ matrix:
141
141
  env: TYPE=UNIT ENVIRONMENT=rails51
142
142
 
143
143
  # jruby 9.0
144
- - rvm: jruby-9.1.12.0
144
+ - rvm: jruby-9.1.13.0
145
145
  env: TYPE=UNIT ENVIRONMENT=rails21
146
- - rvm: jruby-9.1.12.0
146
+ - rvm: jruby-9.1.13.0
147
147
  env: TYPE=UNIT ENVIRONMENT=rails22
148
- - rvm: jruby-9.1.12.0
148
+ - rvm: jruby-9.1.13.0
149
149
  env: TYPE=UNIT ENVIRONMENT=rails23
150
- - rvm: jruby-9.1.12.0
150
+ - rvm: jruby-9.1.13.0
151
151
  env: TYPE=UNIT ENVIRONMENT=rails30
152
- - rvm: jruby-9.1.12.0
152
+ - rvm: jruby-9.1.13.0
153
153
  env: TYPE=UNIT ENVIRONMENT=rails31
154
- - rvm: jruby-9.1.12.0
154
+ - rvm: jruby-9.1.13.0
155
155
  env: TYPE=UNIT ENVIRONMENT=rails32
@@ -1,5 +1,43 @@
1
1
  # New Relic Ruby Agent Release Notes #
2
2
 
3
+ ## v4.5.0 ##
4
+
5
+ * Send synthetics headers even when CAT disabled
6
+
7
+ The agent now sends synthetics headers whenever they are received from an
8
+ external request, even if cross-application tracing is disabled.
9
+
10
+ * Bugfix for DelayedJob Daemonization
11
+
12
+ Customers using the delayed_job script that ships with the gem may encounter
13
+ an IOError with a message indicating the stream was closed. This was due to
14
+ the agent attempting to write a byte into a Pipe that was closed during the
15
+ deamonization of the delayed_job script. This issue has been fixed.
16
+
17
+ * Collect supportability metrics for public API
18
+
19
+ The agent now collects Supportability/API/{method} metrics to track usage of
20
+ all methods in the agent's public API.
21
+
22
+ * Collect supportability metrics on `Module#prepend`
23
+
24
+ The agent now collects Supportability/PrependedModules/{Module} metrics
25
+ for ActiveRecord 4 and 5, ActionController 4 and 5, ActionView 4 and 5,
26
+ ActiveJob 5, and ActionCable 5. These help track the adoption of the
27
+ `Module#prepend` method so we can maintain compatibility with newer versions
28
+ of Ruby and Rails.
29
+
30
+ * Collect explain plans when using PostGIS ActiveRecord adapter
31
+
32
+ The agent will now collect slow SQL explain plans, if configured to, on
33
+ connections using the PostGIS adapter. Thanks Ari Pollak for the contribution!
34
+
35
+ * Lazily intialize New Relic Config
36
+
37
+ The agent will lazily initialize the New Relic config. This allows the agent
38
+ to pickup configuration from environment variables set by dotenv and similar
39
+ tools.
40
+
3
41
  ## v4.4.0 ##
4
42
 
5
43
  * Include test helper for 3rd party use
@@ -30,6 +30,7 @@ module NewRelic
30
30
  require 'new_relic/metric_spec'
31
31
  require 'new_relic/metric_data'
32
32
  require 'new_relic/noticed_error'
33
+ require 'new_relic/supportability_helper'
33
34
 
34
35
  require 'new_relic/agent/encoding_normalizer'
35
36
  require 'new_relic/agent/stats'
@@ -65,6 +66,8 @@ module NewRelic
65
66
  require 'thread'
66
67
  require 'resolv'
67
68
 
69
+ extend NewRelic::SupportabilityHelper
70
+
68
71
  # An exception that is thrown by the server if the agent license is invalid.
69
72
  class LicenseException < StandardError; end
70
73
 
@@ -120,17 +123,14 @@ module NewRelic
120
123
  @logger = log
121
124
  end
122
125
 
123
- # This needs to come after the definition of the logger method above, since
124
- # instantiating the config writes to the Logger.
125
-
126
- @config = NewRelic::Agent::Configuration::Manager.new
127
-
128
- attr_reader :config
126
+ def config
127
+ @config ||= Configuration::Manager.new
128
+ end
129
129
 
130
130
  # For testing
131
131
  # Important that we don't change the instance or we orphan callbacks
132
132
  def reset_config
133
- @config.reset_to_defaults
133
+ config.reset_to_defaults
134
134
  end
135
135
 
136
136
  # @!group Recording custom metrics
@@ -152,6 +152,8 @@ module NewRelic
152
152
  #
153
153
  # @api public
154
154
  def record_metric(metric_name, value) #THREAD_LOCAL_ACCESS
155
+ record_api_supportability_metric(:record_metric)
156
+
155
157
  return unless agent
156
158
 
157
159
  if value.is_a?(Hash)
@@ -179,8 +181,8 @@ module NewRelic
179
181
  def increment_metric(metric_name, amount=1) #THREAD_LOCAL_ACCESS
180
182
  return unless agent
181
183
 
182
- agent.stats_engine.tl_record_unscoped_metrics(metric_name) do |stats|
183
- stats.increment_count(amount)
184
+ { 'Supportability/API/increment_metric' => 1, metric_name => amount }.each do |metric, increment_amount|
185
+ agent.stats_engine.tl_record_unscoped_metrics(metric) {|stats| stats.increment_count(increment_amount) }
184
186
  end
185
187
  end
186
188
 
@@ -200,6 +202,8 @@ module NewRelic
200
202
  # @api public
201
203
  #
202
204
  def ignore_error_filter(&block)
205
+ record_api_supportability_metric(:ignore_error_filter)
206
+
203
207
  if block
204
208
  NewRelic::Agent::ErrorCollector.ignore_error_filter = block
205
209
  else
@@ -236,6 +240,7 @@ module NewRelic
236
240
  # @api public
237
241
  #
238
242
  def notice_error(exception, options={})
243
+ record_api_supportability_metric(:notice_error)
239
244
 
240
245
  if options.has_key?(:trace_only)
241
246
  NewRelic::Agent.logger.log_once(:warn, :trace_only_deprecated,
@@ -276,9 +281,12 @@ module NewRelic
276
281
  # @api public
277
282
  #
278
283
  def record_custom_event(event_type, event_attrs)
284
+ record_api_supportability_metric(:record_custom_event)
285
+
279
286
  if agent && NewRelic::Agent.config[:'custom_insights_events.enabled']
280
287
  agent.custom_event_aggregator.record(event_type, event_attrs)
281
288
  end
289
+
282
290
  nil
283
291
  end
284
292
 
@@ -304,6 +312,8 @@ module NewRelic
304
312
  # @api public
305
313
  #
306
314
  def manual_start(options={})
315
+ record_api_supportability_metric(:manual_start)
316
+
307
317
  raise "Options must be a hash" unless Hash === options
308
318
  NewRelic::Control.instance.init_plugin({ :agent_enabled => true, :sync_startup => true }.merge(options))
309
319
  end
@@ -334,6 +344,7 @@ module NewRelic
334
344
  # @api public
335
345
  #
336
346
  def after_fork(options={})
347
+ record_api_supportability_metric(:after_fork)
337
348
  agent.after_fork(options) if agent
338
349
  end
339
350
 
@@ -345,6 +356,7 @@ module NewRelic
345
356
  # @api public
346
357
  #
347
358
  def shutdown(options={})
359
+ record_api_supportability_metric(:shutdown)
348
360
  agent.shutdown if agent
349
361
  end
350
362
 
@@ -354,6 +366,7 @@ module NewRelic
354
366
  # @api public
355
367
  def drop_buffered_data
356
368
  agent.drop_buffered_data if agent
369
+ record_api_supportability_metric(:drop_buffered_data)
357
370
  end
358
371
 
359
372
  # Add instrumentation files to the agent. The argument should be
@@ -366,6 +379,7 @@ module NewRelic
366
379
  # @api public
367
380
  #
368
381
  def add_instrumentation(file_pattern)
382
+ record_api_supportability_metric(:add_instrumentation)
369
383
  NewRelic::Control.instance.add_instrumentation file_pattern
370
384
  end
371
385
 
@@ -373,6 +387,7 @@ module NewRelic
373
387
  #
374
388
  # @api public
375
389
  def require_test_helper
390
+ record_api_supportability_metric(:require_test_helper)
376
391
  require File.expand_path('../../../test/agent_helper', __FILE__)
377
392
  end
378
393
 
@@ -393,6 +408,7 @@ module NewRelic
393
408
  # @api public
394
409
  #
395
410
  def set_sql_obfuscator(type = :replace, &block)
411
+ record_api_supportability_metric(:set_sql_obfuscator)
396
412
  NewRelic::Agent::Database.set_sql_obfuscator(type, &block)
397
413
  end
398
414
 
@@ -407,6 +423,7 @@ module NewRelic
407
423
  # @api public
408
424
  #
409
425
  def ignore_transaction
426
+ record_api_supportability_metric(:ignore_transaction)
410
427
  txn = NewRelic::Agent::Transaction.tl_current
411
428
  txn.ignore! if txn
412
429
  end
@@ -417,6 +434,7 @@ module NewRelic
417
434
  # @api public
418
435
  #
419
436
  def ignore_apdex
437
+ record_api_supportability_metric(:ignore_apdex)
420
438
  txn = NewRelic::Agent::Transaction.tl_current
421
439
  txn.ignore_apdex! if txn
422
440
  end
@@ -427,6 +445,7 @@ module NewRelic
427
445
  # @api public
428
446
  #
429
447
  def ignore_enduser
448
+ record_api_supportability_metric(:ignore_enduser)
430
449
  txn = NewRelic::Agent::Transaction.tl_current
431
450
  txn.ignore_enduser! if txn
432
451
  end
@@ -439,6 +458,8 @@ module NewRelic
439
458
  # @api public
440
459
  #
441
460
  def disable_all_tracing
461
+ record_api_supportability_metric(:disable_all_tracing)
462
+
442
463
  return yield unless agent
443
464
 
444
465
  begin
@@ -455,6 +476,8 @@ module NewRelic
455
476
  # @api public
456
477
  #
457
478
  def disable_transaction_tracing
479
+ record_api_supportability_metric(:disable_transaction_tracing)
480
+
458
481
  return yield unless agent
459
482
 
460
483
  state = agent.set_record_tt(false)
@@ -477,6 +500,8 @@ module NewRelic
477
500
  # @api public
478
501
  #
479
502
  def disable_sql_recording
503
+ record_api_supportability_metric(:disable_sql_recording)
504
+
480
505
  return yield unless agent
481
506
 
482
507
  state = agent.set_record_sql(false)
@@ -519,6 +544,8 @@ module NewRelic
519
544
  # @api public
520
545
  #
521
546
  def add_custom_attributes(params) #THREAD_LOCAL_ACCESS
547
+ record_api_supportability_metric(:add_custom_attributes)
548
+
522
549
  if params.is_a? Hash
523
550
  txn = Transaction.tl_current
524
551
  txn.add_custom_attributes(params) if txn
@@ -555,6 +582,7 @@ module NewRelic
555
582
  # @api public
556
583
  #
557
584
  def set_transaction_name(name, options={})
585
+ record_api_supportability_metric(:set_transaction_name)
558
586
  Transaction.set_overriding_transaction_name(name, options[:category])
559
587
  end
560
588
 
@@ -564,6 +592,8 @@ module NewRelic
564
592
  # @api public
565
593
  #
566
594
  def get_transaction_name #THREAD_LOCAL_ACCESS
595
+ record_api_supportability_metric(:get_transaction_name)
596
+
567
597
  txn = Transaction.tl_current
568
598
  if txn
569
599
  namer = Instrumentation::ControllerInstrumentation::TransactionNamer
@@ -621,6 +651,8 @@ module NewRelic
621
651
  # @api public
622
652
  #
623
653
  def browser_timing_header
654
+ record_api_supportability_metric(:browser_timing_header)
655
+
624
656
  return "" unless agent
625
657
  agent.javascript_instrumentor.browser_timing_header
626
658
  end
@@ -74,7 +74,8 @@ module NewRelic
74
74
  @waited_on_connect = nil
75
75
  @connected_pid = nil
76
76
 
77
- @wait_on_connect_reader, @wait_on_connect_writer = IO.pipe
77
+ @wait_on_connect_mutex = Mutex.new
78
+ @wait_on_connect_condition = ConditionVariable.new
78
79
 
79
80
  setup_attribute_filter
80
81
  end
@@ -862,7 +863,9 @@ module NewRelic
862
863
  end
863
864
 
864
865
  def signal_connected
865
- @wait_on_connect_writer << "."
866
+ @wait_on_connect_mutex.synchronize do
867
+ @wait_on_connect_condition.signal
868
+ end
866
869
  end
867
870
 
868
871
  def wait_on_connect(timeout)
@@ -870,7 +873,10 @@ module NewRelic
870
873
 
871
874
  @waited_on_connect = true
872
875
  NewRelic::Agent.logger.debug("Waiting on connect to complete.")
873
- IO.select([@wait_on_connect_reader], nil, nil, timeout)
876
+
877
+ @wait_on_connect_mutex.synchronize do
878
+ @wait_on_connect_condition.wait(@wait_on_connect_mutex, timeout)
879
+ end
874
880
 
875
881
  unless connected?
876
882
  raise WaitOnConnectTimeout, "Agent was unable to connect in #{timeout} seconds."
@@ -18,9 +18,6 @@ module NewRelic
18
18
  # The cross app transaction header for "outgoing" calls
19
19
  NR_TXN_HEADER = 'X-NewRelic-Transaction'.freeze
20
20
 
21
- # The cross app synthetics header
22
- NR_SYNTHETICS_HEADER = 'X-NewRelic-Synthetics'.freeze
23
-
24
21
  NR_MESSAGE_BROKER_ID_HEADER = 'NewRelicID'.freeze
25
22
  NR_MESSAGE_BROKER_TXN_HEADER = 'NewRelicTransaction'.freeze
26
23
  NR_MESSAGE_BROKER_SYNTHETICS_HEADER = 'NewRelicSynthetics'.freeze
@@ -61,15 +58,12 @@ module NewRelic
61
58
  @obfuscator ||= NewRelic::Agent::Obfuscator.new(NewRelic::Agent.config[:encoding_key])
62
59
  end
63
60
 
64
- def insert_request_headers(request, txn_guid, trip_id, path_hash, synthetics_header)
61
+ def insert_request_headers request, txn_guid, trip_id, path_hash
65
62
  cross_app_id = NewRelic::Agent.config[:cross_process_id]
66
63
  txn_data = ::JSON.dump([txn_guid, false, trip_id, path_hash])
67
64
 
68
65
  request[NR_ID_HEADER] = obfuscator.obfuscate(cross_app_id)
69
66
  request[NR_TXN_HEADER] = obfuscator.obfuscate(txn_data)
70
- if synthetics_header
71
- request[NR_SYNTHETICS_HEADER] = synthetics_header
72
- end
73
67
  end
74
68
 
75
69
  def response_has_crossapp_header?(response)
@@ -231,13 +231,14 @@ module NewRelic
231
231
 
232
232
  private
233
233
 
234
+ POSTGIS_PREFIX = 'postgis'.freeze
234
235
  POSTGRES_PREFIX = 'postgres'.freeze
235
236
  MYSQL_PREFIX = 'mysql'.freeze
236
237
  MYSQL2_PREFIX = 'mysql2'.freeze
237
238
  SQLITE_PREFIX = 'sqlite'.freeze
238
239
 
239
240
  def symbolized_adapter(adapter)
240
- if adapter.start_with? POSTGRES_PREFIX
241
+ if adapter.start_with?(POSTGRES_PREFIX) || adapter == POSTGIS_PREFIX
241
242
  :postgres
242
243
  elsif adapter == MYSQL_PREFIX
243
244
  :mysql
@@ -34,6 +34,8 @@ module NewRelic
34
34
  # @api public
35
35
  #
36
36
  def self.trace(clazz, method_name, product, operation = method_name)
37
+ NewRelic::Agent.record_api_supportability_metric(:trace)
38
+
37
39
  clazz.class_eval do
38
40
  method_name_without_newrelic = "#{method_name}_without_newrelic"
39
41
 
@@ -49,7 +51,7 @@ module NewRelic
49
51
  begin
50
52
  send(method_name_without_newrelic, *args, &blk)
51
53
  ensure
52
- segment.finish
54
+ segment.finish if segment
53
55
  end
54
56
  end
55
57
 
@@ -103,6 +105,8 @@ module NewRelic
103
105
  # @api public
104
106
  #
105
107
  def self.wrap(product, operation, collection = nil, callback = nil)
108
+ NewRelic::Agent.record_api_supportability_metric(:wrap)
109
+
106
110
  return yield unless operation
107
111
 
108
112
  segment = NewRelic::Agent::Transaction.start_datastore_segment(product, operation, collection)
@@ -114,7 +118,7 @@ module NewRelic
114
118
  elapsed_time = (Time.now - segment.start_time).to_f
115
119
  callback.call(result, segment.name, elapsed_time)
116
120
  end
117
- segment.finish
121
+ segment.finish if segment
118
122
  end
119
123
  end
120
124
 
@@ -147,6 +151,8 @@ module NewRelic
147
151
  # @api public
148
152
  #
149
153
  def self.notice_sql(query, scoped_metric, elapsed)
154
+ NewRelic::Agent.record_api_supportability_metric(:notice_sql)
155
+
150
156
  state = TransactionState.tl_get
151
157
  if (txn = state.current_transaction) && (segment = txn.current_segment) && segment.respond_to?(:notice_sql)
152
158
  segment.notice_sql(query)
@@ -178,6 +184,8 @@ module NewRelic
178
184
  # @api public
179
185
  #
180
186
  def self.notice_statement(statement, elapsed)
187
+ NewRelic::Agent.record_api_supportability_metric(:notice_statement)
188
+
181
189
  # Settings may change eventually, but for now we follow the same
182
190
  # capture rules as SQL for non-SQL statements.
183
191
  state = TransactionState.tl_get
@@ -2,6 +2,8 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
 
5
+ require 'new_relic/agent/prepend_supportability'
6
+
5
7
  DependencyDetection.defer do
6
8
  named :activejob
7
9
 
@@ -19,6 +21,8 @@ DependencyDetection.defer do
19
21
  ::ActiveJob::Base.around_perform do |job, block|
20
22
  ::NewRelic::Agent::Instrumentation::ActiveJobHelper.perform(job, block)
21
23
  end
24
+
25
+ ::NewRelic::Agent::PrependSupportability.record_metrics_for(::ActiveJob::Base)
22
26
  end
23
27
  end
24
28
 
@@ -66,7 +66,7 @@ module NewRelic
66
66
  begin
67
67
  log_without_newrelic_instrumentation(*args, &block)
68
68
  ensure
69
- segment.finish
69
+ segment.finish if segment
70
70
  end
71
71
  end
72
72
  end
@@ -2,6 +2,7 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
  require 'new_relic/agent/instrumentation/active_record_subscriber'
5
+ require 'new_relic/agent/prepend_supportability'
5
6
 
6
7
  DependencyDetection.defer do
7
8
  named :active_record_4
@@ -26,6 +27,7 @@ DependencyDetection.defer do
26
27
  NewRelic::Agent::Instrumentation::ActiveRecordSubscriber.new)
27
28
 
28
29
  ActiveSupport.on_load(:active_record) do
30
+ ::NewRelic::Agent::PrependSupportability.record_metrics_for(::ActiveRecord::Base, ::ActiveRecord::Relation)
29
31
  ::NewRelic::Agent::Instrumentation::ActiveRecordHelper.instrument_additional_methods
30
32
  end
31
33
  end
@@ -2,6 +2,7 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
  require 'new_relic/agent/instrumentation/active_record_subscriber'
5
+ require 'new_relic/agent/prepend_supportability'
5
6
 
6
7
  module NewRelic
7
8
  module Agent
@@ -78,6 +79,8 @@ DependencyDetection.defer do
78
79
  end
79
80
 
80
81
  executes do
82
+ ::NewRelic::Agent::PrependSupportability.record_metrics_for(::ActiveRecord::Base, ::ActiveRecord::Relation)
83
+
81
84
  ActiveSupport::Notifications.subscribe('sql.active_record',
82
85
  NewRelic::Agent::Instrumentation::ActiveRecordSubscriber.new)
83
86
 
@@ -134,7 +134,7 @@ module NewRelic
134
134
  if txn = state.current_transaction
135
135
  txn.add_segment @segment
136
136
  end
137
- @segment.finish
137
+ @segment.finish if @segment
138
138
  end
139
139
 
140
140
  def state
@@ -55,6 +55,7 @@ module NewRelic
55
55
  # @api public
56
56
  #
57
57
  def newrelic_ignore(specifiers={})
58
+ NewRelic::Agent.record_api_supportability_metric(:newrelic_ignore)
58
59
  newrelic_ignore_aspect(NR_DO_NOT_TRACE_KEY, specifiers)
59
60
  end
60
61
  # Have NewRelic omit apdex measurements on the given actions. Typically used for
@@ -64,11 +65,13 @@ module NewRelic
64
65
  # @api public
65
66
  #
66
67
  def newrelic_ignore_apdex(specifiers={})
68
+ NewRelic::Agent.record_api_supportability_metric(:newrelic_ignore_apdex)
67
69
  newrelic_ignore_aspect(NR_IGNORE_APDEX_KEY, specifiers)
68
70
  end
69
71
 
70
72
  # @api public
71
73
  def newrelic_ignore_enduser(specifiers={})
74
+ NewRelic::Agent.record_api_supportability_metric(:newrelic_ignore_enduser)
72
75
  newrelic_ignore_aspect(NR_IGNORE_ENDUSER_KEY, specifiers)
73
76
  end
74
77
 
@@ -156,6 +159,8 @@ module NewRelic
156
159
  # @api public
157
160
  #
158
161
  def add_transaction_tracer(method, options={})
162
+ NewRelic::Agent.record_api_supportability_metric(:add_transaction_tracer)
163
+
159
164
  # The metric path:
160
165
  options[:name] ||= method.to_s
161
166
 
@@ -337,6 +342,7 @@ module NewRelic
337
342
  # @api public
338
343
  #
339
344
  def perform_action_with_newrelic_trace(*args, &block) #THREAD_LOCAL_ACCESS
345
+ NewRelic::Agent.record_api_supportability_metric(:perform_action_with_newrelic_trace)
340
346
  state = NewRelic::Agent::TransactionState.tl_get
341
347
  state.request = newrelic_request(args)
342
348
 
@@ -172,7 +172,7 @@ DependencyDetection.defer do
172
172
  begin
173
173
  segment.read_response_headers wrapped_response
174
174
  ensure
175
- segment.finish
175
+ segment.finish if segment
176
176
  # Make sure the existing completion callback is run, and restore the
177
177
  # on_complete callback to how it was before.
178
178
  original_callback.call(finished_request) if original_callback
@@ -164,7 +164,7 @@ module NewRelic
164
164
 
165
165
  raise
166
166
  ensure
167
- segment.finish
167
+ segment.finish if segment
168
168
  end
169
169
  end
170
170
  end
@@ -31,7 +31,7 @@ module ::Excon
31
31
 
32
32
  response
33
33
  ensure
34
- segment.finish
34
+ segment.finish if segment
35
35
  end
36
36
  end
37
37
 
@@ -53,7 +53,7 @@ module ::Excon
53
53
  segment.read_response_headers wrapped_response
54
54
  end
55
55
  ensure
56
- segment.finish
56
+ segment.finish if segment
57
57
  end
58
58
  end
59
59
  end
@@ -44,7 +44,7 @@ DependencyDetection.defer do
44
44
 
45
45
  response
46
46
  ensure
47
- segment.finish
47
+ segment.finish if segment
48
48
  end
49
49
  end
50
50
 
@@ -48,7 +48,7 @@ module NewRelic
48
48
  if NewRelic::Agent.config[:capture_memcache_keys]
49
49
  segment.notice_nosql_statement "#{method_name} #{args.first.inspect}"
50
50
  end
51
- segment.finish
51
+ segment.finish if segment
52
52
  end
53
53
  end
54
54
 
@@ -68,7 +68,7 @@ module NewRelic
68
68
  if ::NewRelic::Agent.config[:capture_memcache_keys]
69
69
  segment.notice_nosql_statement "#{SEND_MULTIGET_METRIC_NAME} #{keys.inspect}"
70
70
  end
71
- segment.finish
71
+ segment.finish if segment
72
72
  end
73
73
  end
74
74
  end
@@ -86,7 +86,7 @@ module NewRelic
86
86
  begin
87
87
  __send__ method_name_without, *args, &block
88
88
  ensure
89
- segment.finish
89
+ segment.finish if segment
90
90
  end
91
91
  end
92
92
 
@@ -24,7 +24,7 @@ module NewRelic
24
24
  state = NewRelic::Agent::TransactionState.tl_get
25
25
  return unless state.is_execution_traced?
26
26
  segment = segments.delete(event.operation_id)
27
- segment.finish
27
+ segment.finish if segment
28
28
  rescue Exception => e
29
29
  log_notification_error('completed', e)
30
30
  end
@@ -2,6 +2,7 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
  require 'new_relic/agent/instrumentation/action_controller_subscriber'
5
+ require 'new_relic/agent/prepend_supportability'
5
6
 
6
7
 
7
8
  DependencyDetection.defer do
@@ -25,5 +26,7 @@ DependencyDetection.defer do
25
26
  end
26
27
  NewRelic::Agent::Instrumentation::ActionControllerSubscriber \
27
28
  .subscribe(/^process_action.action_controller$/)
29
+
30
+ ::NewRelic::Agent::PrependSupportability.record_metrics_for(::ActionController::Base)
28
31
  end
29
32
  end
@@ -2,6 +2,7 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
  require 'new_relic/agent/instrumentation/action_view_subscriber'
5
+ require 'new_relic/agent/prepend_supportability'
5
6
 
6
7
  DependencyDetection.defer do
7
8
  @name = :rails4_view
@@ -21,5 +22,6 @@ DependencyDetection.defer do
21
22
 
22
23
  executes do
23
24
  NewRelic::Agent::Instrumentation::ActionViewSubscriber.subscribe(/render_.+\.action_view$/)
25
+ NewRelic::Agent::PrependSupportability.record_metrics_for(::ActionView::Base, ::ActionView::Template, ::ActionView::Renderer)
24
26
  end
25
27
  end
@@ -2,6 +2,7 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
  require 'new_relic/agent/instrumentation/action_cable_subscriber'
5
+ require 'new_relic/agent/prepend_supportability'
5
6
 
6
7
  DependencyDetection.defer do
7
8
  @name = :rails5_action_cable
@@ -25,5 +26,7 @@ DependencyDetection.defer do
25
26
  # enumerate the specific events we want so that we do not get unexpected additions in the future
26
27
  ActiveSupport::Notifications.subscribe(/(perform_action|transmit)\.action_cable/,
27
28
  NewRelic::Agent::Instrumentation::ActionCableSubscriber.new)
29
+
30
+ ::NewRelic::Agent::PrependSupportability.record_metrics_for(::ActionCable::Engine, ::ActionCable::RemoteConnections)
28
31
  end
29
32
  end
@@ -2,6 +2,7 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
  require 'new_relic/agent/instrumentation/action_controller_subscriber'
5
+ require 'new_relic/agent/prepend_supportability'
5
6
 
6
7
 
7
8
  DependencyDetection.defer do
@@ -26,5 +27,7 @@ DependencyDetection.defer do
26
27
 
27
28
  NewRelic::Agent::Instrumentation::ActionControllerSubscriber \
28
29
  .subscribe(/^process_action.action_controller$/)
30
+
31
+ NewRelic::Agent::PrependSupportability.record_metrics_for(::ActionController::Base, ::ActionController::API)
29
32
  end
30
33
  end
@@ -2,6 +2,7 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
  require 'new_relic/agent/instrumentation/action_view_subscriber'
5
+ require 'new_relic/agent/prepend_supportability'
5
6
 
6
7
  DependencyDetection.defer do
7
8
  @name = :rails5_view
@@ -16,10 +17,11 @@ DependencyDetection.defer do
16
17
  end
17
18
 
18
19
  executes do
19
- ::NewRelic::Agent.logger.info 'Installing Rails 5 view instrumentation'
20
+ NewRelic::Agent.logger.info 'Installing Rails 5 view instrumentation'
20
21
  end
21
22
 
22
23
  executes do
23
24
  NewRelic::Agent::Instrumentation::ActionViewSubscriber.subscribe(/render_.+\.action_view$/)
25
+ NewRelic::Agent::PrependSupportability.record_metrics_for(::ActionView::Base, ::ActionView::Template, ::ActionView::Renderer)
24
26
  end
25
27
  end
@@ -68,7 +68,7 @@ DependencyDetection.defer do
68
68
  segment.notice_nosql_statement(statement) if statement
69
69
  call_without_new_relic(*args, &block)
70
70
  ensure
71
- segment.finish
71
+ segment.finish if segment
72
72
  end
73
73
  end
74
74
 
@@ -88,7 +88,7 @@ DependencyDetection.defer do
88
88
  segment.notice_nosql_statement(statement)
89
89
  call_pipeline_without_new_relic(*args, &block)
90
90
  ensure
91
- segment.finish
91
+ segment.finish if segment
92
92
  end
93
93
  end
94
94
 
@@ -104,7 +104,7 @@ DependencyDetection.defer do
104
104
  begin
105
105
  connect_without_new_relic(*args, &block)
106
106
  ensure
107
- segment.finish
107
+ segment.finish if segment
108
108
  end
109
109
  end
110
110
  end
@@ -73,7 +73,7 @@ module NewRelic::Agent::Instrumentation::TyphoeusTracing
73
73
  callback = Proc.new do
74
74
  wrapped_response = ::NewRelic::Agent::HTTPClients::TyphoeusHTTPResponse.new(request.response)
75
75
  segment.read_response_headers wrapped_response
76
- segment.finish
76
+ segment.finish if segment
77
77
  end
78
78
  request.on_complete.unshift(callback)
79
79
  end
@@ -68,6 +68,7 @@ module NewRelic
68
68
  # @api public
69
69
  #
70
70
  def trace_execution_scoped(metric_names, options={}) #THREAD_LOCAL_ACCESS
71
+ NewRelic::Agent.record_api_supportability_metric :trace_execution_scoped
71
72
  NewRelic::Agent::MethodTracerHelpers.trace_execution_scoped(metric_names, options) do
72
73
  # Using an implicit block avoids object allocation for a &block param
73
74
  yield
@@ -83,6 +84,7 @@ module NewRelic
83
84
  # @api public
84
85
  #
85
86
  def trace_execution_unscoped(metric_names, options={}) #THREAD_LOCAL_ACCESS
87
+ NewRelic::Agent.record_api_supportability_metric :trace_execution_unscoped
86
88
  return yield unless NewRelic::Agent.tl_is_execution_traced?
87
89
  t0 = Time.now
88
90
  begin
@@ -290,6 +292,8 @@ module NewRelic
290
292
  # @api public
291
293
  #
292
294
  def add_method_tracer(method_name, metric_name_code=nil, options = {})
295
+ NewRelic::Agent.record_api_supportability_metric(:add_method_tracer)
296
+
293
297
  return unless newrelic_method_exists?(method_name)
294
298
  metric_name_code ||= default_metric_name_code(method_name)
295
299
  return if traced_method_exists?(method_name, metric_name_code)
@@ -25,7 +25,7 @@ module NewRelic
25
25
  begin
26
26
  yield
27
27
  ensure
28
- segment.finish
28
+ segment.finish if segment
29
29
  end
30
30
  end
31
31
  end
@@ -0,0 +1,16 @@
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
+ module NewRelic
6
+ module Agent
7
+ module PrependSupportability
8
+ def self.record_metrics_for *classes
9
+ classes.each do |klass|
10
+ count = klass.send(:ancestors).index(klass)
11
+ ::NewRelic::Agent.record_metric("Supportability/PrependedModules/#{klass}", count) if count > 0
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -194,6 +194,8 @@ module NewRelic
194
194
  # @api public
195
195
  #
196
196
  def self.recording_web_transaction? #THREAD_LOCAL_ACCESS
197
+ NewRelic::Agent.record_api_supportability_metric(:recording_web_transaction?)
198
+
197
199
  txn = tl_current
198
200
  txn && txn.recording_web_transaction?
199
201
  end
@@ -11,6 +11,8 @@ module NewRelic
11
11
  class ExternalRequestSegment < Segment
12
12
  attr_reader :library, :uri, :procedure
13
13
 
14
+ NR_SYNTHETICS_HEADER = 'X-NewRelic-Synthetics'.freeze
15
+
14
16
  def initialize library, uri, procedure
15
17
  @library = library
16
18
  @uri = HTTPClients::URIUtil.parse_and_normalize_url(uri)
@@ -33,19 +35,22 @@ module NewRelic
33
35
  # header is used it will update the segment name to reflect the host header.
34
36
  def add_request_headers request
35
37
  process_host_header request
38
+
39
+ synthetics_header = transaction && transaction.raw_synthetics_header
40
+ insert_synthetics_header request, synthetics_header if synthetics_header
41
+
36
42
  return unless record_metrics? && CrossAppTracing.cross_app_enabled?
37
43
 
38
44
  transaction_state.is_cross_app_caller = true
39
45
  txn_guid = transaction_state.request_guid
40
46
  trip_id = transaction && transaction.cat_trip_id(transaction_state)
41
47
  path_hash = transaction && transaction.cat_path_hash(transaction_state)
42
- synthetics_header = transaction && transaction.raw_synthetics_header
43
48
 
44
- CrossAppTracing.insert_request_headers request, txn_guid, trip_id, path_hash, synthetics_header
49
+ CrossAppTracing.insert_request_headers request, txn_guid, trip_id, path_hash
45
50
  rescue => e
46
51
  NewRelic::Agent.logger.error "Error in add_request_headers", e
47
52
  end
48
-
53
+
49
54
  def read_response_headers response
50
55
  return unless record_metrics? && CrossAppTracing.cross_app_enabled?
51
56
  return unless CrossAppTracing.response_has_crossapp_header?(response)
@@ -82,6 +87,10 @@ module NewRelic
82
87
 
83
88
  private
84
89
 
90
+ def insert_synthetics_header request, header
91
+ request[NR_SYNTHETICS_HEADER] = header
92
+ end
93
+
85
94
  def segment_complete
86
95
  params[:uri] = HTTPClients::URIUtil.filter_uri(uri)
87
96
  if cross_app_request?
@@ -0,0 +1,63 @@
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
+ module NewRelic
6
+ module SupportabilityHelper
7
+
8
+ API_SUPPORTABILITY_PREFIX = 'Supportability/API/'.freeze
9
+
10
+ # pre-instantiate these strings as they may be used multiple times per
11
+ # transaction, just to eke out a bit less performance hit
12
+ #
13
+ API_SUPPORTABILITY_METRICS = [
14
+ :add_custom_attributes,
15
+ :add_instrumentation,
16
+ :add_method_tracer,
17
+ :add_transaction_tracer,
18
+ :after_fork,
19
+ :browser_timing_header,
20
+ :disable_all_tracing,
21
+ :disable_sql_recording,
22
+ :disable_transaction_tracing,
23
+ :drop_buffered_data,
24
+ :get_transaction_name,
25
+ :ignore_apdex,
26
+ :ignore_enduser,
27
+ :ignore_error_filter,
28
+ :ignore_transaction,
29
+ :increment_metric,
30
+ :manual_start,
31
+ :newrelic_ignore,
32
+ :newrelic_ignore_apdex,
33
+ :newrelic_ignore_enduser,
34
+ :notice_error,
35
+ :notice_sql,
36
+ :notice_statement,
37
+ :perform_action_with_newrelic_trace,
38
+ :record_custom_event,
39
+ :record_metric,
40
+ :recording_web_transaction?,
41
+ :require_test_helper,
42
+ :set_sql_obfuscator,
43
+ :set_transaction_name,
44
+ :shutdown,
45
+ :trace,
46
+ :trace_execution_scoped,
47
+ :trace_execution_unscoped,
48
+ :wrap
49
+ ].reduce({}) do |h,o|
50
+ h[o] = API_SUPPORTABILITY_PREFIX + o.to_s
51
+ h
52
+ end
53
+
54
+ def record_api_supportability_metric(method_name)
55
+ agent = NewRelic::Agent.agent or return
56
+ if metric = API_SUPPORTABILITY_METRICS[method_name]
57
+ agent.stats_engine.tl_record_unscoped_metrics metric, &:increment_count
58
+ else
59
+ NewRelic::Agent.logger.debug "API supportability metric not found for :#{method_name}"
60
+ end
61
+ end
62
+ end
63
+ end
@@ -11,7 +11,7 @@ module NewRelic
11
11
  end
12
12
 
13
13
  MAJOR = 4
14
- MINOR = 4
14
+ MINOR = 5
15
15
  TINY = 0
16
16
 
17
17
  begin
@@ -53,7 +53,7 @@ module Sequel
53
53
  super(*args, &blk)
54
54
  ensure
55
55
  notice_sql(sql)
56
- segment.finish
56
+ segment.finish if segment
57
57
  end
58
58
  end
59
59
 
@@ -28,7 +28,7 @@ module Sequel
28
28
  begin
29
29
  NewRelic::Agent.disable_all_tracing { super(*args, &block) }
30
30
  ensure
31
- segment.finish
31
+ segment.finish if segment
32
32
  end
33
33
  end
34
34
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newrelic_rpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.0.336
4
+ version: 4.5.0.337
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Wear
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2017-08-14 00:00:00.000000000 Z
14
+ date: 2017-09-22 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: rake
@@ -302,6 +302,7 @@ files:
302
302
  - lib/new_relic/agent/payload_metric_mapping.rb
303
303
  - lib/new_relic/agent/pipe_channel_manager.rb
304
304
  - lib/new_relic/agent/pipe_service.rb
305
+ - lib/new_relic/agent/prepend_supportability.rb
305
306
  - lib/new_relic/agent/rules_engine.rb
306
307
  - lib/new_relic/agent/rules_engine/replacement_rule.rb
307
308
  - lib/new_relic/agent/rules_engine/segment_terms_rule.rb
@@ -402,6 +403,7 @@ files:
402
403
  - lib/new_relic/recipes.rb
403
404
  - lib/new_relic/recipes/capistrano3.rb
404
405
  - lib/new_relic/recipes/capistrano_legacy.rb
406
+ - lib/new_relic/supportability_helper.rb
405
407
  - lib/new_relic/version.rb
406
408
  - lib/newrelic_rpm.rb
407
409
  - lib/sequel/extensions/newrelic_instrumentation.rb