newrelic_rpm 9.10.1 → 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: 8660cb164e8b97c18397b4413d5b2ccb582c8cb377599f77b89d15920d3eb568
4
- data.tar.gz: 81e5a8617f26c196f72f57b8dbb536acafb199325af6c56676190fb7a12acfc8
3
+ metadata.gz: cc36449c6f2ea3322f353181809c05d3e84e28f85fb15544c82e088946384046
4
+ data.tar.gz: f8fa907597f05f47c5dbe9c38a005cb1d09f971183aa7075664e6ade029186fc
5
5
  SHA512:
6
- metadata.gz: 7f6aef929dcdaef485265ef0055466292a511fcb71af6720947b5fc1599f6518aca4e11b43a553df65c20c61b73cd59e8e6fbdd53683222f875c88dba5cc942b
7
- data.tar.gz: 293dcf0e5a6865e1aed9bf0f913c14cbda26251aa2141f1a5dd3a096804239496889a413b2f2d21c0009552913fc42f7a8bd52c85aa76fdf4be1b546a219f527
6
+ metadata.gz: 622cdf275eb70aa1f57e027f2e73559855c17c4351741c80ec0db8ae45b773f2d7aa2831ae562e228b24a71a0532ae93dced167be3ecfdd3561886224d212070
7
+ data.tar.gz: a68a148e494bfc0e5f9da3c369eb56f7170664e78ffd12cc178e77b7361da39edefbc967b5c71c2905b993b5d4075b2189abc3ec7692081d6b4dd422149902f3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
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
+
19
+ ## v9.10.2
20
+
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.
22
+
23
+ - **Bugfix: DynamoDB instrumentation logging errors when trying to get account_id**
24
+
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)
26
+
27
+ - **Bugfix: Remove Rails::Command::RakeCommand from the default list of autostart.denylisted_constants**
28
+
29
+ The default value for the `autostart.denylisted_constants` configuration was changed in 9.10.0 to include `Rails::Command::RunnerCommand` and `Rails::Command::RakeCommand`. The inclusion of `Rails::Command::RakeCommand` prevented the agent from starting automatically when Solid Queue was started using `bin/rails solid_queue:start`. We recognize there are many commands nested within `Rails::Command::RakeCommand` and have decided to remove it from the default list. We encourage users who do not want the agent to run on `Rails::Command::RakeCommand` to add the constant to their configuration. This can be accomplished by adding the following to your `newrelic.yml` file:
30
+
31
+ ```yaml
32
+ autostart.denylisted_constants: "Rails::Command::ConsoleCommand,Rails::Command::CredentialsCommand,Rails::Command::Db::System::ChangeCommand,Rails::Command::DbConsoleCommand,Rails::Command::DestroyCommand,Rails::Command::DevCommand,Rails::Command::EncryptedCommand,Rails::Command::GenerateCommand,Rails::Command::InitializersCommand,Rails::Command::NotesCommand,Rails::Command::RakeCommand,Rails::Command::RoutesCommand,Rails::Command::RunnerCommand,Rails::Command::SecretsCommand,Rails::Console,Rails::DBConsole"
33
+ ```
34
+
35
+ Thank you, [@edariedl](https://github.com/edariedl), for reporting this issue. [Issue#2677](https://github.com/newrelic/newrelic-ruby-agent/issues/2677) [PR#2694](https://github.com/newrelic/newrelic-ruby-agent/pull/2694)
36
+
3
37
  ## v9.10.1
4
38
 
5
39
  - **Bugfix: Incompatibility with Bootstrap**
@@ -11,7 +45,7 @@ Version 9.10.1 fixes an incompatibility between the agent and the [Bootstrap](ht
11
45
  Version 9.10.0 introduces instrumentation for DynamoDB, adds a new feature to automatically apply nonces from the Rails content security policy, fixes a bug that would cause an expected error to negatively impact a transaction's Apdex, and fixes the agent's autostart logic so that by default `rails runner` and `rails db` commands will not cause the agent to start.
12
46
 
13
47
  - **Feature: Add instrumentation for DynamoDB**
14
-
48
+
15
49
  The agent has added instrumentation for the aws-sdk-dynamodb gem. The agent will now record datastore spans for DynamoDB client calls made with the aws-sdk-dynamodb gem. [PR#2642](https://github.com/newrelic/newrelic-ruby-agent/pull/2642)
16
50
 
17
51
  - **Feature: Automatically apply nonces from the Rails content security policy**
@@ -8,15 +8,21 @@ module NewRelic
8
8
  CHARACTERS = %w[A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 2 3 4 5 6 7].freeze
9
9
  HEX_MASK = '7fffffffff80'
10
10
 
11
- def self.create_arn(service, resource, config)
12
- region = config.region
13
- account_id = NewRelic::Agent::Aws.convert_access_key_to_account_id(config.credentials.access_key_id)
14
-
11
+ def self.create_arn(service, resource, region, account_id)
15
12
  "arn:aws:#{service}:#{region}:#{account_id}:#{resource}"
16
13
  rescue => e
17
14
  NewRelic::Agent.logger.warn("Failed to create ARN: #{e}")
18
15
  end
19
16
 
17
+ def self.get_account_id(config)
18
+ access_key_id = config.credentials.credentials.access_key_id if config&.credentials&.credentials&.respond_to?(:access_key_id)
19
+ return unless access_key_id
20
+
21
+ NewRelic::Agent::Aws.convert_access_key_to_account_id(access_key_id)
22
+ rescue => e
23
+ NewRelic::Agent.logger.debug("Failed to create account id: #{e}")
24
+ end
25
+
20
26
  def self.convert_access_key_to_account_id(access_key)
21
27
  decoded_key = Integer(decode_to_hex(access_key[4..-1]), 16)
22
28
  mask = Integer(HEX_MASK, 16)
@@ -480,7 +480,12 @@ module NewRelic
480
480
  :type => Boolean,
481
481
  :allowed_from_server => false,
482
482
  :description => <<~DESC
483
- Forces the exit handler that sends all cached data to collector before shutting down to be installed regardless of detecting scenarios where it generally should not be. Known use-case for this option is where Sinatra is running as an embedded service within another framework and the agent is detecting the Sinatra app and skipping the `at_exit` handler as a result. Sinatra classically runs the entire application in an `at_exit` block and would otherwise misbehave if the Agent's `at_exit` handler was also installed in those circumstances. Note: `send_data_on_exit` should also be set to `true` in tandem with this setting."
483
+ The exit handler that sends all cached data to the collector before shutting down is forcibly installed. \
484
+ This is true even when it detects scenarios where it generally should not be. The known use case for this \
485
+ option is when Sinatra runs as an embedded service within another framework. The agent detects the Sinatra \
486
+ app and skips the `at_exit` handler as a result. Sinatra classically runs the entire application in an \
487
+ `at_exit` block and would otherwise misbehave if the agent's `at_exit` handler was also installed in those \
488
+ circumstances. Note: `send_data_on_exit` should also be set to `true` in tandem with this setting.
484
489
  DESC
485
490
  },
486
491
  :high_security => {
@@ -1077,7 +1082,6 @@ module NewRelic
1077
1082
  Rails::Command::GenerateCommand
1078
1083
  Rails::Command::InitializersCommand
1079
1084
  Rails::Command::NotesCommand
1080
- Rails::Command::RakeCommand
1081
1085
  Rails::Command::RoutesCommand
1082
1086
  Rails::Command::RunnerCommand
1083
1087
  Rails::Command::SecretsCommand
@@ -1144,8 +1148,12 @@ module NewRelic
1144
1148
  :public => true,
1145
1149
  :type => Integer,
1146
1150
  :allowed_from_server => true,
1147
- :description => 'Specify a maximum number of custom events to buffer in memory at a time.',
1148
- :dynamic_name => true
1151
+ :dynamic_name => true,
1152
+ :description => <<~DESC
1153
+ * Specify a maximum number of custom events to buffer in memory at a time.'
1154
+ * When configuring the agent for [AI monitoring](/docs/ai-monitoring/intro-to-ai-monitoring), \
1155
+ set to max value `100000`. This ensures the agent captures the maximum amount of LLM events.
1156
+ DESC
1149
1157
  },
1150
1158
  # Datastore tracer
1151
1159
  :'datastore_tracer.database_name_reporting.enabled' => {
@@ -1450,6 +1458,14 @@ module NewRelic
1450
1458
  :allowed_from_server => false,
1451
1459
  :description => 'Controls auto-instrumentation of bunny at start-up. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
1452
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
+ },
1453
1469
  :'instrumentation.dynamodb' => {
1454
1470
  :default => 'auto',
1455
1471
  :public => true,
@@ -1983,8 +1999,8 @@ module NewRelic
1983
1999
  :allowed_from_server => true,
1984
2000
  :description => <<~DESC
1985
2001
  * Defines the maximum number of span events reported from a single harvest. Any Integer between `1` and `10000` is valid.'
1986
- * When configuring the agent for [AI monitoring](/docs/ai-monitoring/intro-to-ai-monitoring), set to max value `10000`.\
1987
- This ensures that the agent captures the maximum amount of distributed traces.
2002
+ * When configuring the agent for [AI monitoring](/docs/ai-monitoring/intro-to-ai-monitoring), set to max value `10000`.\
2003
+ This ensures the agent captures the maximum amount of distributed traces.
1988
2004
  DESC
1989
2005
  },
1990
2006
  # Strip exception messages
@@ -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
@@ -49,10 +49,16 @@ module NewRelic::Agent::Instrumentation
49
49
  @nr_captured_request = yield
50
50
  end
51
51
 
52
+ def nr_account_id
53
+ return @nr_account_id if defined?(@nr_account_id)
54
+
55
+ @nr_account_id = NewRelic::Agent::Aws.get_account_id(config)
56
+ end
57
+
52
58
  def get_arn(params)
53
- return unless params[:table_name]
59
+ return unless params[:table_name] && nr_account_id
54
60
 
55
- NewRelic::Agent::Aws.create_arn(PRODUCT.downcase, "table/#{params[:table_name]}", config)
61
+ NewRelic::Agent::Aws.create_arn(PRODUCT.downcase, "table/#{params[:table_name]}", config&.region, nr_account_id)
56
62
  end
57
63
  end
58
64
  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 = 1
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
@@ -31,15 +31,16 @@ class Instrumentation < Thor
31
31
 
32
32
  def scaffold(name)
33
33
  @name = name
34
+ @snake_name = snake_name(@name)
34
35
  @method = options[:method] if options[:method]
35
36
  @args = options[:args] if options[:args]
36
37
  @class_name = ::NewRelic::LanguageSupport.camelize(name)
37
- base_path = "#{INSTRUMENTATION_ROOT}#{name.downcase}"
38
+ base_path = "#{INSTRUMENTATION_ROOT}#{@snake_name}"
38
39
 
39
40
  empty_directory(base_path)
40
41
  create_instrumentation_files(base_path)
41
- append_to_default_source(name)
42
- append_to_newrelic_yml(name)
42
+ append_to_default_source(@name, @snake_name)
43
+ # append_to_newrelic_yml(@name, @snake_name) # This is now done on release, we don't need it anymore, but leaving it to be sure.
43
44
  create_tests(name)
44
45
  end
45
46
 
@@ -69,53 +70,60 @@ class Instrumentation < Thor
69
70
  def create_tests(name)
70
71
  @name = name
71
72
  @instrumentation_method_global_erb_snippet = '<%= $instrumentation_method %>'
72
- base_path = "#{MULTIVERSE_SUITE_ROOT}#{@name.downcase}"
73
+ @snake_name = snake_name(@name)
74
+ base_path = "#{MULTIVERSE_SUITE_ROOT}#{@snake_name}"
73
75
  empty_directory(base_path)
74
76
  template('templates/Envfile.tt', "#{base_path}/Envfile")
75
- template('templates/test.tt', "#{base_path}/#{@name.downcase}_instrumentation_test.rb")
77
+ template('templates/test.tt', "#{base_path}/#{@snake_name}_instrumentation_test.rb")
76
78
 
77
79
  empty_directory("#{base_path}/config")
78
80
  template('templates/newrelic.yml.tt', "#{base_path}/config/newrelic.yml")
79
81
  end
80
82
 
81
- def append_to_default_source(name)
83
+ def append_to_default_source(name, snake_name)
82
84
  insert_into_file(
83
85
  DEFAULT_SOURCE_LOCATION,
84
- config_block(name.downcase),
86
+ config_block(name, snake_name),
85
87
  after: ":description => 'Controls auto-instrumentation of bunny at start-up. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
86
88
  },\n"
87
89
  )
88
90
  end
89
91
 
90
- def append_to_newrelic_yml(name)
92
+ def append_to_newrelic_yml(name, snake_name)
91
93
  insert_into_file(
92
94
  NEWRELIC_YML_LOCATION,
93
- yaml_block(name),
95
+ yaml_block(name, snake_name),
94
96
  after: "# instrumentation.bunny: auto\n"
95
97
  )
96
98
  end
97
99
 
98
- def config_block(name)
99
- <<~CONFIG
100
- :'instrumentation.#{name.downcase}' => {
101
- :default => 'auto',
102
- :public => true,
103
- :type => String,
104
- :dynamic_name => true,
105
- :allowed_from_server => false,
106
- :description => 'Controls auto-instrumentation of the #{name} library at start-up. May be one of [auto|prepend|chain|disabled].'
107
- },
100
+ def config_block(name, snake_name)
101
+ # Don't change to <<~
102
+ # We want to preserve the whitespace so the config is correctly indented
103
+ <<-CONFIG
104
+ :'instrumentation.#{snake_name}' => {
105
+ :default => 'auto',
106
+ :public => true,
107
+ :type => String,
108
+ :dynamic_name => true,
109
+ :allowed_from_server => false,
110
+ :description => 'Controls auto-instrumentation of the #{name} library at start-up. May be one of `auto`, `prepend`, `chain`, `disabled`.'
111
+ },
108
112
  CONFIG
109
113
  end
110
114
 
111
- def yaml_block(name)
115
+ def yaml_block(name, snake_name)
112
116
  <<~HEREDOC
113
117
 
114
118
  # Controls auto-instrumentation of #{name} at start-up.
115
119
  # May be one of [auto|prepend|chain|disabled]
116
- # instrumentation.#{name.downcase}: auto
120
+ # instrumentation.#{snake_name}: auto
117
121
  HEREDOC
118
122
  end
123
+
124
+ def snake_name(name)
125
+ name.downcase.tr('-', '_')
126
+ end
119
127
  end
120
128
 
121
129
  Instrumentation.start(ARGV)
@@ -2,12 +2,12 @@
2
2
  # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
3
3
  # frozen_string_literal: true
4
4
 
5
- require_relative '<%= @name.downcase %>/instrumentation'
6
- require_relative '<%= @name.downcase %>/chain'
7
- require_relative '<%= @name.downcase %>/prepend'
5
+ require_relative '<%= @snake_name.downcase %>/instrumentation'
6
+ require_relative '<%= @snake_name.downcase %>/chain'
7
+ require_relative '<%= @snake_name.downcase %>/prepend'
8
8
 
9
9
  DependencyDetection.defer do
10
- named :<%= @name.match?(/\-|\_/) ? "'#{@name.downcase}'" : @name.downcase %>
10
+ named :<%= @name.match?(/\-|\_/) ? "'#{@snake_name}'" : @name.downcase %>
11
11
 
12
12
  depends_on do
13
13
  # The class that needs to be defined to prepend/chain onto. This can be used
@@ -6,7 +6,7 @@ development:
6
6
  monitor_mode: true
7
7
  license_key: bootstrap_newrelic_admin_license_key_000
8
8
  instrumentation:
9
- <%= @name.downcase %>: <%= @instrumentation_method_global_erb_snippet %>
9
+ <%= @snake_name %>: <%= @instrumentation_method_global_erb_snippet %>
10
10
  app_name: test
11
11
  log_level: debug
12
12
  host: 127.0.0.1
data/newrelic.yml CHANGED
@@ -116,7 +116,7 @@ common: &default_settings
116
116
  # Specify a list of constants that should prevent the agent from starting
117
117
  # automatically. Separate individual constants with a comma ,. For example,
118
118
  # "Rails::Console,UninstrumentedBackgroundJob".
119
- # autostart.denylisted_constants: Rails::Command::ConsoleCommand,Rails::Command::CredentialsCommand,Rails::Command::Db::System::ChangeCommand,Rails::Command::DbConsoleCommand,Rails::Command::DestroyCommand,Rails::Command::DevCommand,Rails::Command::EncryptedCommand,Rails::Command::GenerateCommand,Rails::Command::InitializersCommand,Rails::Command::NotesCommand,Rails::Command::RakeCommand,Rails::Command::RoutesCommand,Rails::Command::RunnerCommand,Rails::Command::SecretsCommand,Rails::Console,Rails::DBConsole
119
+ # autostart.denylisted_constants: Rails::Command::ConsoleCommand,Rails::Command::CredentialsCommand,Rails::Command::Db::System::ChangeCommand,Rails::Command::DbConsoleCommand,Rails::Command::DestroyCommand,Rails::Command::DevCommand,Rails::Command::EncryptedCommand,Rails::Command::GenerateCommand,Rails::Command::InitializersCommand,Rails::Command::NotesCommand,Rails::Command::RoutesCommand,Rails::Command::RunnerCommand,Rails::Command::SecretsCommand,Rails::Console,Rails::DBConsole
120
120
 
121
121
  # Defines a comma-delimited list of executables that the agent should not
122
122
  # instrument. For example, "rake,my_ruby_script.rb".
@@ -188,7 +188,9 @@ common: &default_settings
188
188
  # If true, the agent captures custom events.
189
189
  # custom_insights_events.enabled: true
190
190
 
191
- # Specify a maximum number of custom events to buffer in memory at a time.
191
+ # * Specify a maximum number of custom events to buffer in memory at a time.'
192
+ # * When configuring the agent for AI monitoring, set to max value 100000. This
193
+ # ensures the agent captures the maximum amount of LLM events.
192
194
  # custom_insights_events.max_samples_stored: 3000
193
195
 
194
196
  # If false, the agent will not add database_name parameter to transaction or slow
@@ -354,14 +356,14 @@ common: &default_settings
354
356
  # requests.
355
357
  # exclude_newrelic_header: false
356
358
 
357
- # Forces the exit handler that sends all cached data to collector before shutting
358
- # down to be installed regardless of detecting scenarios where it generally should
359
- # not be. Known use-case for this option is where Sinatra is running as an
360
- # embedded service within another framework and the agent is detecting the Sinatra
361
- # app and skipping the at_exit handler as a result. Sinatra classically runs the
359
+ # The exit handler that sends all cached data to the collector before shutting
360
+ # down is forcibly installed. This is true even when it detects scenarios where it
361
+ # generally should not be. The known use case for this option is when Sinatra runs
362
+ # as an embedded service within another framework. The agent detects the Sinatra
363
+ # app and skips the at_exit handler as a result. Sinatra classically runs the
362
364
  # entire application in an at_exit block and would otherwise misbehave if the
363
- # Agent's at_exit handler was also installed in those circumstances. Note:
364
- # send_data_on_exit should also be set to true in tandem with this setting."
365
+ # agent's at_exit handler was also installed in those circumstances. Note:
366
+ # send_data_on_exit should also be set to true in tandem with this setting.
365
367
  # force_install_exit_handler: false
366
368
 
367
369
  # Ordinarily the agent reports dyno names with a trailing dot and process ID (for
@@ -405,6 +407,10 @@ common: &default_settings
405
407
  # prepend, chain, disabled.
406
408
  # instrumentation.async_http: auto
407
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
+
408
414
  # Controls auto-instrumentation of bunny at start-up. May be one of: auto,
409
415
  # prepend, chain, disabled.
410
416
  # instrumentation.bunny: auto
@@ -699,8 +705,8 @@ common: &default_settings
699
705
 
700
706
  # * Defines the maximum number of span events reported from a single harvest. Any
701
707
  # Integer between 1 and 10000 is valid.'
702
- # * When configuring the agent for AI monitoring, set to max value 10000. This
703
- # ensures that the agent captures the maximum amount of distributed traces.
708
+ # * When configuring the agent for AI monitoring, set to max value 10000.This
709
+ # ensures the agent captures the maximum amount of distributed traces.
704
710
  # span_events.max_samples_stored: 2000
705
711
 
706
712
  # Sets the maximum number of span events to buffer when streaming to the trace
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.1
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-03 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