newrelic_rpm 9.10.2 → 9.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cef71bbfaac5e07f6d5b0862fccb3bf35e4c99251ce5fec00143036c89c964f8
4
- data.tar.gz: e5521d0958408d97494625b155f2dcb97736d02994f7b7dfdc58143dabc73dee
3
+ metadata.gz: cc36449c6f2ea3322f353181809c05d3e84e28f85fb15544c82e088946384046
4
+ data.tar.gz: f8fa907597f05f47c5dbe9c38a005cb1d09f971183aa7075664e6ade029186fc
5
5
  SHA512:
6
- metadata.gz: 28a45e748a241b3bfb2c93bb19500cda6bc433c9c428e56f4cbcc92ff5c12d8f6d0198ab87d3a910f11539695fc8d0a4935c65ea5869d6bf36b66ae2b012c3a7
7
- data.tar.gz: 35426f77a90e9f10b2be825538482a5bda1d074cc4d3c22acd1df007774f21a190b10696ad962fe34e30db0dd57d0a5bcadb3db6d5bc97edad0dcfba88db9a19
6
+ metadata.gz: 622cdf275eb70aa1f57e027f2e73559855c17c4351741c80ec0db8ae45b773f2d7aa2831ae562e228b24a71a0532ae93dced167be3ecfdd3561886224d212070
7
+ data.tar.gz: a68a148e494bfc0e5f9da3c369eb56f7170664e78ffd12cc178e77b7361da39edefbc967b5c71c2905b993b5d4075b2189abc3ec7692081d6b4dd422149902f3
data/CHANGELOG.md CHANGED
@@ -1,12 +1,28 @@
1
1
  # New Relic Ruby Agent Release Notes
2
2
 
3
+ ## v9.11.0
4
+
5
+ Version 9.11.0 introduces instrumentation for the aws-sdk-sqs gem, fixes a bug related to expected errors not bearing a "true" value for the "expected" attribute if expected as a result of an HTTP status code match and changes the way Stripe instrumentation metrics are named to prevent high-cardinality issues.
6
+
7
+ - **Feature: Add instrumentation for SQS**
8
+
9
+ The agent has added instrumentation for the [aws-sdk-sqs gem](https://rubygems.org/gems/aws-sdk-sqs). The agent will now record message broker spans for SQS client calls made with the aws-sdk-sqs gem. [PR#2679](https://github.com/newrelic/newrelic-ruby-agent/pull/2679)
10
+
11
+ - **Bugfix: HTTP status code based expected errors will now have an "expected" value of "true"**
12
+
13
+ Previously when an error was treated as expected by the agent as a result of a matching HTTP status code being found in the :'error_collector.expected_status_codes' configuration setting, the error would not appear with an "expected" attribute value of "true" in the errors in the errors inbox. [PR#2710](https://github.com/newrelic/newrelic-ruby-agent/pull/2710)
14
+
15
+ - **Bugfix: Stripe metric names will no longer include full request paths to limit the unique name count**
16
+
17
+ The Stripe instrumentation introduced in agent version v9.5.0 produced instrumentation metric names that used the full Stripe request path. For any significant Stripe usage, this could quickly lead to very large number of distinct metric names. Now only the API version and the category part of the request path are included in the metric name which still includes the "Stripe" opener and method (ex: "get") closer. Thanks to [@jdelStrother](https://github.com/jdelStrother) and [@jsneedles](https://github.com/jsneedles) for bringing this issue to our attention and providing terrific information explaining the problem and potential paths to resolution. [PR#2716](https://github.com/newrelic/newrelic-ruby-agent/pull/2716)
18
+
3
19
  ## v9.10.2
4
20
 
5
21
  Version 9.10.2 fixes a bug related to the new DynamoDB instrumentation and removes `Rails::Command::RakeCommand` from the default list of denylisted constants.
6
22
 
7
23
  - **Bugfix: DynamoDB instrumentation logging errors when trying to get account_id**
8
24
 
9
- When trying to access data needed to add the `account_id` to the DynamoDB span, the agent encountered an error when certain credentials classes were used. This has been fixed. Thanks to [@kichik](https://github.com/kichik) for bringing this to our attention. [PR#2864](https://github.com/newrelic/newrelic-ruby-agent/pull/2684)
25
+ When trying to access data needed to add the `account_id` to the DynamoDB span, the agent encountered an error when certain credentials classes were used. This has been fixed. Thanks to [@kichik](https://github.com/kichik) for bringing this to our attention. [PR#2684](https://github.com/newrelic/newrelic-ruby-agent/pull/2684)
10
26
 
11
27
  - **Bugfix: Remove Rails::Command::RakeCommand from the default list of autostart.denylisted_constants**
12
28
 
@@ -1458,6 +1458,14 @@ module NewRelic
1458
1458
  :allowed_from_server => false,
1459
1459
  :description => 'Controls auto-instrumentation of bunny at start-up. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
1460
1460
  },
1461
+ :'instrumentation.aws_sqs' => {
1462
+ :default => 'auto',
1463
+ :public => true,
1464
+ :type => String,
1465
+ :dynamic_name => true,
1466
+ :allowed_from_server => false,
1467
+ :description => 'Controls auto-instrumentation of the aws-sdk-sqs library at start-up. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
1468
+ },
1461
1469
  :'instrumentation.dynamodb' => {
1462
1470
  :default => 'auto',
1463
1471
  :public => true,
@@ -237,7 +237,8 @@ module NewRelic
237
237
  end
238
238
 
239
239
  def notice_segment_error(segment, exception, options = {})
240
- return if skip_notice_error?(exception)
240
+ status_code = process_http_status_code(exception, options)
241
+ return if skip_notice_error?(exception, status_code)
241
242
 
242
243
  options.merge!(segment.llm_event.error_attributes(exception)) if segment.llm_event
243
244
 
@@ -250,15 +251,13 @@ module NewRelic
250
251
 
251
252
  # See NewRelic::Agent.notice_error for options and commentary
252
253
  def notice_error(exception, options = {}, span_id = nil)
253
- state = ::NewRelic::Agent::Tracer.state
254
- transaction = state.current_transaction
255
- status_code = transaction&.http_response_code
256
-
254
+ status_code = process_http_status_code(exception, options)
257
255
  return if skip_notice_error?(exception, status_code)
258
256
 
259
257
  tag_exception(exception)
260
258
 
261
- if options[:expected] || @error_filter.expected?(exception, status_code)
259
+ state = ::NewRelic::Agent::Tracer.state
260
+ if options[:expected]
262
261
  increment_expected_error_count!(state, exception)
263
262
  else
264
263
  increment_error_count!(state, exception, options)
@@ -266,10 +265,8 @@ module NewRelic
266
265
 
267
266
  noticed_error = create_noticed_error(exception, options)
268
267
  error_trace_aggregator.add_to_error_queue(noticed_error)
269
- transaction = state.current_transaction
270
- payload = transaction&.payload
271
- span_id ||= transaction&.current_segment ? transaction.current_segment.guid : nil
272
- error_event_aggregator.record(noticed_error, payload, span_id)
268
+ span_id ||= state.current_transaction&.current_segment&.guid
269
+ error_event_aggregator.record(noticed_error, state.current_transaction&.payload, span_id)
273
270
  exception
274
271
  rescue => e
275
272
  ::NewRelic::Agent.logger.warn("Failure when capturing error '#{exception}':", e)
@@ -359,6 +356,13 @@ module NewRelic
359
356
  def error_group_callback
360
357
  NewRelic::Agent.error_group_callback
361
358
  end
359
+
360
+ def process_http_status_code(exception, options)
361
+ status_code = ::NewRelic::Agent::Tracer.state.current_transaction&.http_response_code
362
+ options[:expected] = true if !options[:expected] && @error_filter.expected?(exception, status_code)
363
+
364
+ status_code
365
+ end
362
366
  end
363
367
  end
364
368
  end
@@ -0,0 +1,37 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module AwsSqs::Chain
7
+ def self.instrument!
8
+ ::Aws::SQS::Client.class_eval do
9
+ include NewRelic::Agent::Instrumentation::AwsSqs
10
+
11
+ alias_method(:send_message_without_new_relic, :send_message)
12
+
13
+ def send_message(*args)
14
+ send_message_with_new_relic(*args) do
15
+ send_message_without_new_relic(*args)
16
+ end
17
+ end
18
+
19
+ alias_method(:send_message_batch_without_new_relic, :send_message_batch)
20
+
21
+ def send_message_batch(*args)
22
+ send_message_batch_with_new_relic(*args) do
23
+ send_message_batch_without_new_relic(*args)
24
+ end
25
+ end
26
+
27
+ alias_method(:receive_message_without_new_relic, :receive_message)
28
+
29
+ def receive_message(*args)
30
+ receive_message_with_new_relic(*args) do
31
+ receive_message_without_new_relic(*args)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,67 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module AwsSqs
7
+ MESSAGING_LIBRARY = 'SQS'
8
+
9
+ def send_message_with_new_relic(*args)
10
+ with_tracing(:produce, args) do
11
+ yield
12
+ end
13
+ end
14
+
15
+ def send_message_batch_with_new_relic(*args)
16
+ with_tracing(:produce, args) do
17
+ yield
18
+ end
19
+ end
20
+
21
+ def receive_message_with_new_relic(*args)
22
+ with_tracing(:consume, args) do
23
+ yield
24
+ end
25
+ end
26
+
27
+ def with_tracing(action, params)
28
+ segment = nil
29
+ begin
30
+ info = get_url_info(params[0])
31
+ segment = NewRelic::Agent::Tracer.start_message_broker_segment(
32
+ action: action,
33
+ library: MESSAGING_LIBRARY,
34
+ destination_type: :queue,
35
+ destination_name: info[:queue_name]
36
+ )
37
+ add_aws_attributes(segment, info)
38
+ rescue => e
39
+ NewRelic::Agent.logger.error('Error starting message broker segment in Aws::SQS::Client', e)
40
+ end
41
+ NewRelic::Agent::Tracer.capture_segment_error(segment) do
42
+ yield
43
+ end
44
+ ensure
45
+ segment&.finish
46
+ end
47
+
48
+ private
49
+
50
+ def add_aws_attributes(segment, info)
51
+ return unless segment
52
+
53
+ segment.add_agent_attribute('messaging.system', 'aws_sqs')
54
+ segment.add_agent_attribute('cloud.region', config&.region)
55
+ segment.add_agent_attribute('cloud.account.id', info[:account_id])
56
+ segment.add_agent_attribute('messaging.destination.name', info[:queue_name])
57
+ end
58
+
59
+ def get_url_info(params)
60
+ split = params[:queue_url].split('/')
61
+ {
62
+ queue_name: split.last,
63
+ account_id: split[-2]
64
+ }
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,21 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module AwsSqs::Prepend
7
+ include NewRelic::Agent::Instrumentation::AwsSqs
8
+
9
+ def send_message(*args)
10
+ send_message_with_new_relic(*args) { super }
11
+ end
12
+
13
+ def send_message_batch(*args)
14
+ send_message_batch_with_new_relic(*args) { super }
15
+ end
16
+
17
+ def receive_message(*args)
18
+ receive_message_with_new_relic(*args) { super }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require_relative 'aws_sqs/instrumentation'
6
+ require_relative 'aws_sqs/chain'
7
+ require_relative 'aws_sqs/prepend'
8
+
9
+ DependencyDetection.defer do
10
+ named :aws_sqs
11
+
12
+ depends_on do
13
+ defined?(Aws::SQS::Client)
14
+ end
15
+
16
+ executes do
17
+ NewRelic::Agent.logger.info('Installing aws-sdk-sqs instrumentation')
18
+
19
+ if use_prepend?
20
+ prepend_instrument Aws::SQS::Client, NewRelic::Agent::Instrumentation::AwsSqs::Prepend
21
+ else
22
+ chain_instrument NewRelic::Agent::Instrumentation::AwsSqs::Chain
23
+ end
24
+ end
25
+ end
@@ -10,6 +10,7 @@ module NewRelic
10
10
  EVENT_ATTRIBUTES = %i[http_status method num_retries path request_id].freeze
11
11
  ATTRIBUTE_NAMESPACE = 'stripe.user_data'
12
12
  ATTRIBUTE_FILTER_TYPES = %i[include exclude].freeze
13
+ PATH_PORTION_PATTERN = %r{^/([^/]+/[^/]+)(?:/|\z)}.freeze
13
14
 
14
15
  def start_segment(event)
15
16
  return unless is_execution_traced?
@@ -39,7 +40,27 @@ module NewRelic
39
40
  end
40
41
 
41
42
  def metric_name(event)
42
- "Stripe#{event.path}/#{event.method}"
43
+ # Grab only the first 2 items from the slash (/) delimited event path.
44
+ # These items are the API version string and the category. Grabbing
45
+ # any more of the path will result in unique method names that will
46
+ # easily grow to be too numerous to sort through in the UI and
47
+ # possibly even violate default New Relic metric count thresholds.
48
+ # See newrelic/newrelic-ruby-agent#2654 and
49
+ # newrelic/newrelic-ruby-agent#2709 for more details.
50
+ #
51
+ # In Ruby v3.4 benchmarks, using regex to get at the first two path
52
+ # elements was seen as more performant than using String#split.
53
+ #
54
+ # Regex legend:
55
+ #
56
+ # ^ = starts with
57
+ # / = a literal '/'
58
+ # () = capture
59
+ # (?:) = don't capture
60
+ # [^/]+ = 1 or more characters that are not '/'
61
+ # /|\z = a literal '/' OR the end of the string
62
+ path_portion = event.path =~ PATH_PORTION_PATTERN ? Regexp.last_match(1) : NewRelic::UNKNOWN
63
+ "Stripe/#{path_portion}/#{event.method}"
43
64
  end
44
65
 
45
66
  def add_stripe_attributes(segment, event)
@@ -6,8 +6,8 @@
6
6
  module NewRelic
7
7
  module VERSION # :nodoc:
8
8
  MAJOR = 9
9
- MINOR = 10
10
- TINY = 2
9
+ MINOR = 11
10
+ TINY = 0
11
11
 
12
12
  STRING = "#{MAJOR}.#{MINOR}.#{TINY}"
13
13
  end
@@ -0,0 +1,31 @@
1
+ # This file is distributed under New Relic's license terms.
2
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
+ # frozen_string_literal: true
4
+
5
+ require 'yaml'
6
+ require_relative 'helpers/version_bump'
7
+
8
+ # gha = GitHub Actions
9
+ namespace :gha do
10
+ # See .github/versions.yml
11
+ desc 'Update 3rd party action versions across all workflows'
12
+ task :update_versions do
13
+ gh_dir = File.expand_path('../../../.github', __FILE__)
14
+ info = YAML.load_file(File.join(gh_dir, 'versions.yml'))
15
+ workflows = Dir.glob(File.join(gh_dir, 'workflows', '*.yml'))
16
+ workflows.each do |workflow|
17
+ original = File.read(workflow)
18
+ modified = original.dup
19
+ info.each do |action, settings|
20
+ modified.gsub!(/uses: #{action}.*$/, "uses: #{action}@#{settings[:sha]} # tag #{settings[:tag]}")
21
+ end
22
+
23
+ if original != modified
24
+ File.open(workflow, 'w') { |f| f.puts modified }
25
+ puts "Updated #{workflow} with changes"
26
+ else
27
+ puts "#{workflow} remains unchanged"
28
+ end
29
+ end
30
+ end
31
+ end
data/newrelic.yml CHANGED
@@ -407,6 +407,10 @@ common: &default_settings
407
407
  # prepend, chain, disabled.
408
408
  # instrumentation.async_http: auto
409
409
 
410
+ # Controls auto-instrumentation of the aws-sdk-sqs library at start-up. May be one
411
+ # of: auto, prepend, chain, disabled.
412
+ # instrumentation.aws_sqs: auto
413
+
410
414
  # Controls auto-instrumentation of bunny at start-up. May be one of: auto,
411
415
  # prepend, chain, disabled.
412
416
  # instrumentation.bunny: auto
data/newrelic_rpm.gemspec CHANGED
@@ -56,6 +56,8 @@ Gem::Specification.new do |s|
56
56
  s.add_development_dependency 'minitest', "#{RUBY_VERSION >= '2.7.0' ? '5.3.3' : '4.7.5'}"
57
57
  s.add_development_dependency 'minitest-stub-const', '0.6'
58
58
  s.add_development_dependency 'mocha', '~> 1.16'
59
+ s.add_development_dependency 'mutex_m' # used by Minitest, not included in Rubies above v3.3
60
+ s.add_development_dependency 'ostruct' # used by Rack, not included in Rubies above v3.4
59
61
  s.add_development_dependency 'pry' if ENV['ENABLE_PRY']
60
62
  s.add_development_dependency 'rack'
61
63
  s.add_development_dependency 'rake', '12.3.3'
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: 9.10.2
4
+ version: 9.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanna McClure
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2024-06-06 00:00:00.000000000 Z
14
+ date: 2024-06-20 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -69,6 +69,34 @@ dependencies:
69
69
  - - "~>"
70
70
  - !ruby/object:Gem::Version
71
71
  version: '1.16'
72
+ - !ruby/object:Gem::Dependency
73
+ name: mutex_m
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ - !ruby/object:Gem::Dependency
87
+ name: ostruct
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ type: :development
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
72
100
  - !ruby/object:Gem::Dependency
73
101
  name: rack
74
102
  requirement: !ruby/object:Gem::Requirement
@@ -364,6 +392,10 @@ files:
364
392
  - lib/new_relic/agent/instrumentation/async_http/chain.rb
365
393
  - lib/new_relic/agent/instrumentation/async_http/instrumentation.rb
366
394
  - lib/new_relic/agent/instrumentation/async_http/prepend.rb
395
+ - lib/new_relic/agent/instrumentation/aws_sqs.rb
396
+ - lib/new_relic/agent/instrumentation/aws_sqs/chain.rb
397
+ - lib/new_relic/agent/instrumentation/aws_sqs/instrumentation.rb
398
+ - lib/new_relic/agent/instrumentation/aws_sqs/prepend.rb
367
399
  - lib/new_relic/agent/instrumentation/bunny.rb
368
400
  - lib/new_relic/agent/instrumentation/bunny/chain.rb
369
401
  - lib/new_relic/agent/instrumentation/bunny/instrumentation.rb
@@ -671,6 +703,7 @@ files:
671
703
  - lib/tasks/bump_version.rake
672
704
  - lib/tasks/config.rake
673
705
  - lib/tasks/coverage_report.rake
706
+ - lib/tasks/gha.rake
674
707
  - lib/tasks/helpers/config.html.erb
675
708
  - lib/tasks/helpers/config.text.erb
676
709
  - lib/tasks/helpers/format.rb
@@ -723,7 +756,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
723
756
  - !ruby/object:Gem::Version
724
757
  version: 1.3.1
725
758
  requirements: []
726
- rubygems_version: 3.5.9
759
+ rubygems_version: 3.5.11
727
760
  signing_key:
728
761
  specification_version: 4
729
762
  summary: New Relic Ruby Agent