newrelic_rpm 9.6.0 → 9.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -2
  3. data/CONTRIBUTING.md +0 -7
  4. data/bin/newrelic +2 -9
  5. data/bin/newrelic_rpm +15 -0
  6. data/init.rb +2 -2
  7. data/lib/new_relic/agent/agent.rb +1 -1
  8. data/lib/new_relic/agent/agent_helpers/shutdown.rb +1 -1
  9. data/lib/new_relic/agent/agent_helpers/special_startup.rb +1 -1
  10. data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +2 -2
  11. data/lib/new_relic/agent/agent_helpers/startup.rb +2 -2
  12. data/lib/new_relic/agent/attribute_filter.rb +3 -3
  13. data/lib/new_relic/agent/configuration/default_source.rb +14 -2
  14. data/lib/new_relic/agent/configuration/manager.rb +8 -7
  15. data/lib/new_relic/agent/custom_event_aggregator.rb +27 -1
  16. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +1 -1
  17. data/lib/new_relic/agent/distributed_tracing/distributed_trace_payload.rb +3 -3
  18. data/lib/new_relic/agent/event_loop.rb +1 -1
  19. data/lib/new_relic/agent/http_clients/abstract.rb +4 -0
  20. data/lib/new_relic/agent/http_clients/async_http_wrappers.rb +0 -3
  21. data/lib/new_relic/agent/http_clients/curb_wrappers.rb +1 -3
  22. data/lib/new_relic/agent/http_clients/ethon_wrappers.rb +0 -2
  23. data/lib/new_relic/agent/http_clients/excon_wrappers.rb +0 -3
  24. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +1 -3
  25. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +0 -3
  26. data/lib/new_relic/agent/http_clients/httpx_wrappers.rb +0 -2
  27. data/lib/new_relic/agent/http_clients/net_http_wrappers.rb +1 -4
  28. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +0 -3
  29. data/lib/new_relic/agent/instrumentation/active_merchant.rb +1 -1
  30. data/lib/new_relic/agent/instrumentation/async_http.rb +3 -1
  31. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +1 -1
  32. data/lib/new_relic/agent/instrumentation/fiber/instrumentation.rb +1 -4
  33. data/lib/new_relic/agent/instrumentation/grpc_server.rb +1 -1
  34. data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +1 -1
  35. data/lib/new_relic/agent/instrumentation/sinatra.rb +1 -1
  36. data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +1 -4
  37. data/lib/new_relic/agent/instrumentation/view_component/chain.rb +21 -0
  38. data/lib/new_relic/agent/instrumentation/view_component/instrumentation.rb +39 -0
  39. data/lib/new_relic/agent/instrumentation/view_component/prepend.rb +13 -0
  40. data/lib/new_relic/agent/instrumentation/view_component.rb +26 -0
  41. data/lib/new_relic/agent/javascript_instrumentor.rb +0 -1
  42. data/lib/new_relic/agent/new_relic_service/encoders.rb +2 -2
  43. data/lib/new_relic/agent/new_relic_service.rb +8 -6
  44. data/lib/new_relic/agent/obfuscator.rb +0 -2
  45. data/lib/new_relic/agent/pipe_channel_manager.rb +2 -2
  46. data/lib/new_relic/agent/rules_engine/segment_terms_rule.rb +1 -2
  47. data/lib/new_relic/agent/sql_sampler.rb +0 -1
  48. data/lib/new_relic/agent/tracer.rb +4 -3
  49. data/lib/new_relic/agent/transaction/tracing.rb +11 -1
  50. data/lib/new_relic/agent/vm/{mri_vm.rb → c_ruby_vm.rb} +7 -15
  51. data/lib/new_relic/agent/vm.rb +2 -2
  52. data/lib/new_relic/agent/worker_loop.rb +1 -1
  53. data/lib/new_relic/agent.rb +5 -5
  54. data/lib/new_relic/base64.rb +25 -0
  55. data/lib/new_relic/cli/command.rb +6 -4
  56. data/lib/new_relic/constants.rb +2 -0
  57. data/lib/new_relic/control/frameworks/rails.rb +3 -3
  58. data/lib/new_relic/control/instrumentation.rb +1 -1
  59. data/lib/new_relic/local_environment.rb +22 -13
  60. data/lib/new_relic/supportability_helper.rb +1 -1
  61. data/lib/new_relic/version.rb +2 -2
  62. data/lib/tasks/config.rake +1 -1
  63. data/lib/tasks/helpers/config.html.erb +6 -6
  64. data/lib/tasks/helpers/newrelicyml.rb +1 -1
  65. data/lib/tasks/instrumentation_generator/instrumentation.thor +1 -1
  66. data/lib/tasks/instrumentation_generator/templates/chain.tt +0 -1
  67. data/lib/tasks/instrumentation_generator/templates/chain_method.tt +0 -1
  68. data/newrelic.yml +6 -2
  69. data/newrelic_rpm.gemspec +3 -5
  70. data/test/agent_helper.rb +14 -2
  71. metadata +12 -21
  72. data/bin/newrelic_cmd +0 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e08eba5efd3af57153446155d8c29ea47a55641bbf8c593105be4242325b1613
4
- data.tar.gz: 571ec550538228168b2cafdf64f3cb55360aaac3ab33938d1200bf63ee840506
3
+ metadata.gz: 6bdcea3ab1fea41b672c672c931a6005966bef1500709deb9d85681912cf7d33
4
+ data.tar.gz: 7d2bcd8db6e959d909e26dd4c3d8e8a99c7cec6572204a1c0283ce65521a5d6a
5
5
  SHA512:
6
- metadata.gz: 13fae847437ac99e08ac4bc25545074e4bf300c91abdabc2d3afcb0b3e7fb87987c1c811bdb7b7eb4a4470d3d58bc11266ee75d6d21672cdab3437418d42814c
7
- data.tar.gz: 4eb79daba4531d41b736099e904126af44421a3ca9457fed3a0b9d89ea90973674b204d1f96d2fbe28f449b452d8b12c01b73f991bf3ceb26cfafe0bf7cf794d
6
+ metadata.gz: '053846613ea0a66e691e15cd2159c3ada613f3f66dcfc9232f723569a54d3659f84b8b16ed178e7eb46691a36dc182addaf187370b15862e3f05d3e9335f50b3'
7
+ data.tar.gz: 588be3aa5b6e29b2cb1c79e89d4b3bd4af5fc5e41e819f1916c52107aca1ba41f8ca9d573ccf7d8def38d9fb166a2cd73ae2bf9733de2bc03472cd517cdf1801
data/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # New Relic Ruby Agent Release Notes
2
2
 
3
+
4
+ ## v9.7.1
5
+
6
+ Version 9.7.1 fixes a ViewComponent instrumentation bug and enforces maximum size limits for custom event attributes.
7
+
8
+ - **Bugfix: Stop suppressing ViewComponent errors**
9
+
10
+ Previously, the agent suppressed ViewComponent render errors. The agent now reports these errors and allows them to raise. Thank you [@mjacobus](https://github.com/mjacobus) for reporting this bug and providing a fix! [PR#2410](https://github.com/newrelic/newrelic-ruby-agent/pull/2410)
11
+
12
+ - **Bugfix: Enforce maximum size limits for custom event attributes**
13
+
14
+ Previously, the agent would allow custom event attributes to be any size. This would lead to the New Relic backend dropping attributes larger than the maximum size. Now, the agent will truncate custom event attribute values to 4095 characters, attribute names to 255 characters, and the total count of attributes to 64. [PR#2401](https://github.com/newrelic/newrelic-ruby-agent/pull/2401)
15
+
16
+ ## v9.7.0
17
+
18
+ Version 9.7.0 introduces ViewComponent instrumentation, changes the endpoint used to access the cluster name for Elasticsearch instrumentation, removes the creation of the Ruby/Thread and Ruby/Fiber spans, and adds support for Falcon.
19
+
20
+ - **Feature: ViewComponent instrumentation**
21
+
22
+ [ViewComponent](https://viewcomponent.org/) is a now an instrumented library. [PR#2367](https://github.com/newrelic/newrelic-ruby-agent/pull/2367)
23
+
24
+ - **Feature: Use root path to access Elasticsearch cluster name**
25
+
26
+ Previously, the agent used the cluster health endpoint (`/_cluster/health`) to access the cluster name. However, this has been found to make startup unstable for large clusters. Now, the agent uses the more performant root endpoint (`/`).
27
+
28
+ Our thanks go to [@erikkessler1](https://github.com/erikkessler1), [@gremerritt](https://github.com/gremerritt), and [@joshbranham](https://github.com/joshbranham) for reporting the issue, suggesting solutions, and testing them. [Issue#2360](https://github.com/newrelic/newrelic-ruby-agent/issues/2360) [PR#2377](https://github.com/newrelic/newrelic-ruby-agent/pull/2377)
29
+
30
+ - **Feature: Remove base64 dependency, use direct calls to String methods**
31
+
32
+ In version 9.6.0, the agent required the Ruby `base64` gem as a depdendency to prepare for deprecation warnings in Ruby 3.3 and the gem's removal from the Ruby standard libraries in 3.4. Including `base64` as a dependency has caused problems with version resolution in some environments.
33
+
34
+ To resolve this, the agent now directly calls the `String` methods used in the `base64` library in the new `NewRelic::Base64` module.
35
+
36
+ Thank you, [@Earlopain](https://github.com/Earlopain), for submitting this change. [PR#2378](https://github.com/newrelic/newrelic-ruby-agent/pull/2378)
37
+
38
+ - **Feature: Add Falcon support**
39
+
40
+ The agent now supports the web server [Falcon](https://socketry.github.io/falcon/). [PR#2383](https://github.com/newrelic/newrelic-ruby-agent/pull/2383)
41
+
42
+ - **Feature: Remove spans with name Ruby/Thread and Ruby/Fiber**
43
+
44
+ Due to the lack of helpful information and the confusion commonly caused by the spans named Ruby/Thread and Ruby/Fiber, these spans have been removed. However, the agents ability to monitor instrumented code running in a thread or fiber will remain unchanged. [PR#2389](https://github.com/newrelic/newrelic-ruby-agent/pull/2389)
45
+
3
46
  ## v9.6.0
4
47
 
5
48
  Version 9.6.0 adds instrumentation for Async::HTTP, Ethon, and HTTPX, adds the ability to ignore specific routes with Roda, gleans Docker container IDs from cgroups v2-based containers, records additional synthetics attributes, fixes an issue with Rails 7.1 that could cause duplicate log records to be sent to New Relic, fixes a deprecation warning for the Sidekiq error handler, adds additional attributes for OpenTelemetry compatibility, and resolves some technical debt, thanks to the community.
@@ -69,7 +112,7 @@ Version 9.6.0 adds instrumentation for Async::HTTP, Ethon, and HTTPX, adds the a
69
112
 
70
113
  We also received some great contributions from community members to resolve some outstanding technical debt issues. Thank you for your contributions!
71
114
  * Add and Replace SLASH and ROOT constants: [PR#2256](https://github.com/newrelic/newrelic-ruby-agent/pull/2256) [chahmedejaz](https://github.com/chahmedejaz)
72
- * Remove pry as a dev dependency: [PR#2665](https://github.com/newrelic/newrelic-ruby-agent/pull/2265), [PR#2273](https://github.com/newrelic/newrelic-ruby-agent/pull/2273) [AlajeBash](https://github.com/AlajeBash)
115
+ * Remove pry as a dev dependency: PR#2665, PR#2273, AlajeBash (profile no longer active)
73
116
  * Replace "start up" with "start-up": [PR#2249](https://github.com/newrelic/newrelic-ruby-agent/pull/2249) [chahmedejaz](https://github.com/chahmedejaz)
74
117
  * Remove unused variables in test suites: [PR#2250](https://github.com/newrelic/newrelic-ruby-agent/pull/2250)
75
118
 
@@ -1465,7 +1508,7 @@ The multiverse collection of test suites requires a variety of data handling sof
1465
1508
 
1466
1509
  - **Additional Transaction Information applied to Span Events**
1467
1510
 
1468
- When Distributed Tracing and/or Infinite Tracing are enabled, the Agent will now incorporate additional information from the Transaction Event on to the root Span Event of the transaction.
1511
+ When Distributed Tracing and/or Infinite Tracing are enabled, the agent will now incorporate additional information from the Transaction Event on to the root Span Event of the transaction.
1469
1512
 
1470
1513
  The following items are affected:
1471
1514
 
data/CONTRIBUTING.md CHANGED
@@ -178,13 +178,6 @@ opensource@newrelic.com.
178
178
  For more information about CLAs, please check out Alex Russell’s excellent post,
179
179
  [“Why Do I Need to Sign This?”](https://infrequently.org/2008/06/why-do-i-need-to-sign-this/).
180
180
 
181
- ## Slack
182
-
183
- We host a public Slack with a dedicated channel for contributors and maintainers
184
- of open source projects hosted by New Relic. If you are contributing to this
185
- project, you're welcome to request access to the #oss-contributors channel in
186
- the newrelicusers.slack.com workspace. To request access, please use this [link](https://join.slack.com/t/newrelicusers/shared_invite/zt-1ayj69rzm-~go~Eo1whIQGYnu3qi15ng).
187
-
188
181
  ## Explorer's Hub
189
182
 
190
183
  New Relic hosts and moderates an online forum where customers can interact with
data/bin/newrelic CHANGED
@@ -1,15 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
+ # This command has been renamed "newrelic_rpm"
4
5
  # executes one of the commands in the new_relic/commands directory
5
6
  # pass the name of the command as an argument
6
7
 
7
- $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
8
- require 'new_relic/cli/command'
9
- begin
10
- NewRelic::Cli::Command.run
11
- rescue NewRelic::Cli::Command::CommandFailure => failure
12
- STDERR.puts failure.message
13
- STDERR.puts failure.options if failure.options
14
- exit(1)
15
- end
8
+ load File.dirname(__FILE__) + '/newrelic_rpm'
data/bin/newrelic_rpm ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # executes one of the commands in the new_relic/commands directory
5
+ # pass the name of the command as an argument
6
+
7
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
8
+ require 'new_relic/cli/command'
9
+ begin
10
+ NewRelic::Cli::Command.run
11
+ rescue NewRelic::Cli::Command::CommandFailure => failure
12
+ STDERR.puts failure.message
13
+ STDERR.puts failure.options if failure.options
14
+ exit(1)
15
+ end
data/init.rb CHANGED
@@ -2,7 +2,7 @@
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
- # This is the initialization for the New Relic Ruby Agent when used as
5
+ # This is the initialization for the New Relic Ruby agent when used as
6
6
  # a plugin
7
7
  require 'new_relic/control'
8
8
 
@@ -12,7 +12,7 @@ require 'new_relic/control'
12
12
  # If you can't find any log files and you don't see anything in your
13
13
  # application log files please visit support.newrelic.com.
14
14
 
15
- # Initializer for the NewRelic Ruby Agent
15
+ # Initializer for the New Relic Ruby agent
16
16
 
17
17
  # After version 2.0 of Rails we can access the configuration directly.
18
18
  # We need it to add dev mode routes after initialization finished.
@@ -47,7 +47,7 @@ require 'new_relic/agent/agent_helpers/transmit'
47
47
 
48
48
  module NewRelic
49
49
  module Agent
50
- # The Agent is a singleton that is instantiated when the plugin is
50
+ # The agent is a singleton that is instantiated when the plugin is
51
51
  # activated. It collects performance data from ruby applications
52
52
  # in realtime as the application runs, and periodically sends that
53
53
  # data to the NewRelic server.
@@ -11,7 +11,7 @@ module NewRelic
11
11
  def shutdown
12
12
  return unless started?
13
13
 
14
- ::NewRelic::Agent.logger.info('Starting Agent shutdown')
14
+ ::NewRelic::Agent.logger.info('Starting agent shutdown')
15
15
 
16
16
  stop_event_loop
17
17
  trap_signals_for_litespeed
@@ -10,7 +10,7 @@ module NewRelic
10
10
  # requests, we need to wait until the children are forked
11
11
  # before connecting, otherwise the parent process sends useless data
12
12
  def using_forking_dispatcher?
13
- if [:puma, :passenger, :unicorn].include?(Agent.config[:dispatcher])
13
+ if [:puma, :passenger, :unicorn, :falcon].include?(Agent.config[:dispatcher])
14
14
  ::NewRelic::Agent.logger.info('Deferring startup of agent reporting thread because ' \
15
15
  "#{Agent.config[:dispatcher]} may fork.")
16
16
  true
@@ -19,12 +19,12 @@ module NewRelic
19
19
  # See #connect for a description of connection_options.
20
20
  def start_worker_thread(connection_options = {})
21
21
  if disable = NewRelic::Agent.config[:disable_harvest_thread]
22
- NewRelic::Agent.logger.info('Not starting Ruby Agent worker thread because :disable_harvest_thread is ' \
22
+ NewRelic::Agent.logger.info('Not starting Ruby agent worker thread because :disable_harvest_thread is ' \
23
23
  "#{disable}")
24
24
  return
25
25
  end
26
26
 
27
- ::NewRelic::Agent.logger.debug('Creating Ruby Agent worker thread.')
27
+ ::NewRelic::Agent.logger.debug('Creating Ruby agent worker thread.')
28
28
  @worker_thread = Threading::AgentThread.create('Worker Loop') do
29
29
  deferred_work!(connection_options)
30
30
  end
@@ -103,7 +103,7 @@ module NewRelic
103
103
  # so we can disambiguate processes in the log file and make
104
104
  # sure they're running a reasonable version
105
105
  def log_version_and_pid
106
- ::NewRelic::Agent.logger.debug("New Relic Ruby Agent #{NewRelic::VERSION::STRING} Initialized: pid = #{$$}")
106
+ ::NewRelic::Agent.logger.debug("New Relic Ruby agent #{NewRelic::VERSION::STRING} initialized: pid = #{$$}")
107
107
  end
108
108
 
109
109
  # Logs the configured application names
@@ -180,7 +180,7 @@ module NewRelic
180
180
 
181
181
  unless app_name_configured?
182
182
  NewRelic::Agent.logger.error('No application name configured.',
183
- 'The Agent cannot start without at least one. Please check your ',
183
+ 'The agent cannot start without at least one. Please check your ',
184
184
  'newrelic.yml and ensure that it is valid and has at least one ',
185
185
  "value set for app_name in the #{NewRelic::Control.instance.env} ",
186
186
  'environment.')
@@ -2,7 +2,7 @@
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
- # This class applies filtering rules as specified in the Agent Attributes
5
+ # This class applies filtering rules as specified in the agent attributes
6
6
  # cross-agent spec.
7
7
  #
8
8
  # Instances of it are constructed by deriving a set of rules from the agent
@@ -44,7 +44,7 @@
44
44
  # 1. First, the names are compared lexicographically. This has the impact of
45
45
  # forcing shorter (more general) rules towards the top of the list and longer
46
46
  # (more specific) rules towards the bottom. This is important, because the
47
- # Agent Attributes spec stipulates that the most specific rule for a given
47
+ # agent Attributes spec stipulates that the most specific rule for a given
48
48
  # destination should take precedence. Since rules are applied top-to-bottom,
49
49
  # this sorting guarantees that the most specific rule will be applied last.
50
50
  # 2. If the names are identical, we next examine the wildcard flag. Rules ending
@@ -274,7 +274,7 @@ module NewRelic
274
274
 
275
275
  def initialize(attribute_name, destinations, is_include)
276
276
  @attribute_name = attribute_name.sub(/\*$/, '')
277
- @wildcard = attribute_name.end_with?('*')
277
+ @wildcard = attribute_name.end_with?(ASTERISK)
278
278
  @is_include = is_include
279
279
  @destinations = is_include ? destinations : ~destinations
280
280
  end
@@ -313,6 +313,7 @@ module NewRelic
313
313
  'webpacker:compile'
314
314
  ].join(',').freeze
315
315
 
316
+ # rubocop:disable Metrics/CollectionLiteralLength
316
317
  DEFAULTS = {
317
318
  # Critical
318
319
  :agent_enabled => {
@@ -336,6 +337,7 @@ module NewRelic
336
337
  :public => true,
337
338
  :type => String,
338
339
  :allowed_from_server => false,
340
+ :exclude_from_reported_settings => true,
339
341
  :description => 'Your New Relic <InlinePopover type="licenseKey" />.'
340
342
  },
341
343
  :log_level => {
@@ -444,7 +446,7 @@ module NewRelic
444
446
  'before shutting down to be installed regardless of detecting scenarios where it generally should not be. ' \
445
447
  'Known use-case for this option is where Sinatra is running as an embedded service within another framework ' \
446
448
  'and the agent is detecting the Sinatra app and skipping the `at_exit` handler as a result. Sinatra classically ' \
447
- 'runs the entire application in an `at_exit` block and would otherwise misbehave if the Agent\'s `at_exit` handler ' \
449
+ 'runs the entire application in an `at_exit` block and would otherwise misbehave if the agent\'s `at_exit` handler ' \
448
450
  'was also installed in those circumstances. Note: `send_data_on_exit` should also be set to `true` in tandem with this setting.'
449
451
  },
450
452
  :high_security => {
@@ -1656,6 +1658,14 @@ module NewRelic
1656
1658
  :allowed_from_server => false,
1657
1659
  :description => 'Controls auto-instrumentation of Stripe at startup. May be one of: `enabled`, `disabled`.'
1658
1660
  },
1661
+ :'instrumentation.view_component' => {
1662
+ :default => 'auto',
1663
+ :public => true,
1664
+ :type => String,
1665
+ :dynamic_name => true,
1666
+ :allowed_from_server => false,
1667
+ :description => 'Controls auto-instrumentation of ViewComponent at startup. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
1668
+ },
1659
1669
  :'stripe.user_data.include' => {
1660
1670
  default: NewRelic::EMPTY_ARRAY,
1661
1671
  public: true,
@@ -2227,7 +2237,8 @@ module NewRelic
2227
2237
  :public => false,
2228
2238
  :type => String,
2229
2239
  :allowed_from_server => true,
2230
- :description => 'JavaScript agent loader content.'
2240
+ :description => 'JavaScript agent loader content.',
2241
+ :exclude_from_reported_settings => true
2231
2242
  },
2232
2243
  :keep_alive_timeout => {
2233
2244
  :default => 60,
@@ -2403,6 +2414,7 @@ module NewRelic
2403
2414
  :description => 'This value represents the total amount of memory available to the host (not the process), in mebibytes (1024 squared or 1,048,576 bytes).'
2404
2415
  }
2405
2416
  }.freeze
2417
+ # rubocop:enable Metrics/CollectionLiteralLength
2406
2418
  end
2407
2419
  end
2408
2420
  end
@@ -230,7 +230,7 @@ module NewRelic
230
230
  end
231
231
 
232
232
  def to_collector_hash
233
- DottedHash.new(apply_mask(flattened)).to_hash.delete_if do |k, v|
233
+ DottedHash.new(apply_mask(flattened)).to_hash.delete_if do |k, _v|
234
234
  default = DEFAULTS[k]
235
235
  if default
236
236
  default[:exclude_from_reported_settings]
@@ -364,7 +364,7 @@ module NewRelic
364
364
  def reset_cache
365
365
  return new_cache unless defined?(@cache) && @cache
366
366
 
367
- preserved = @cache.select { |_k, v| DEPENDENCY_DETECTION_VALUES.include?(v) }
367
+ preserved = @cache.dup.select { |_k, v| DEPENDENCY_DETECTION_VALUES.include?(v) }
368
368
  new_cache
369
369
  preserved.each { |k, v| @cache[k] = v }
370
370
 
@@ -376,12 +376,13 @@ module NewRelic
376
376
  end
377
377
 
378
378
  def log_config(direction, source)
379
- # Just generating this log message (specifically calling
380
- # flattened.inspect) is expensive enough that we don't want to do it
381
- # unless we're actually going to be logging the message based on our
382
- # current log level.
379
+ # Just generating this log message (specifically calling `flattened`)
380
+ # is expensive enough that we don't want to do it unless we're
381
+ # actually going to be logging the message based on our current log
382
+ # level, so use a `do` block.
383
383
  ::NewRelic::Agent.logger.debug do
384
- "Updating config (#{direction}) from #{source.class}. Results: #{flattened.inspect}"
384
+ hash = flattened.delete_if { |k, _h| DEFAULTS.fetch(k, {}).fetch(:exclude_from_reported_settings, false) }
385
+ "Updating config (#{direction}) from #{source.class}. Results: #{hash.inspect}"
385
386
  end
386
387
  end
387
388
 
@@ -14,6 +14,9 @@ module NewRelic
14
14
  TIMESTAMP = 'timestamp'.freeze
15
15
  PRIORITY = 'priority'.freeze
16
16
  EVENT_TYPE_REGEX = /^[a-zA-Z0-9:_ ]+$/.freeze
17
+ MAX_ATTRIBUTE_COUNT = 64
18
+ MAX_ATTRIBUTE_SIZE = 4095
19
+ MAX_NAME_SIZE = 255
17
20
 
18
21
  named :CustomEventAggregator
19
22
  capacity_key :'custom_insights_events.max_samples_stored'
@@ -49,10 +52,33 @@ module NewRelic
49
52
  {TYPE => type,
50
53
  TIMESTAMP => Process.clock_gettime(Process::CLOCK_REALTIME).to_i,
51
54
  PRIORITY => priority},
52
- AttributeProcessing.flatten_and_coerce(attributes)
55
+ create_custom_event_attributes(attributes)
53
56
  ]
54
57
  end
55
58
 
59
+ def create_custom_event_attributes(attributes)
60
+ result = AttributeProcessing.flatten_and_coerce(attributes)
61
+
62
+ if result.size > MAX_ATTRIBUTE_COUNT
63
+ NewRelic::Agent.logger.warn("Custom event attributes are limited to #{MAX_ATTRIBUTE_COUNT}. Discarding #{result.size - MAX_ATTRIBUTE_COUNT} attributes")
64
+ result = result.first(MAX_ATTRIBUTE_COUNT)
65
+ end
66
+
67
+ result.each_with_object({}) do |(key, val), new_result|
68
+ # name is limited to 255
69
+ if key.is_a?(String) && key.length > MAX_NAME_SIZE
70
+ key = key[0, MAX_NAME_SIZE]
71
+ end
72
+
73
+ # value is limited to 4095
74
+ if val.is_a?(String) && val.length > MAX_ATTRIBUTE_SIZE
75
+ val = val[0, MAX_ATTRIBUTE_SIZE]
76
+ end
77
+
78
+ new_result[key] = val
79
+ end
80
+ end
81
+
56
82
  def after_initialize
57
83
  @type_strings = Hash.new { |hash, key| hash[key] = key.to_s.freeze }
58
84
  end
@@ -128,7 +128,7 @@ module NewRelic
128
128
  end
129
129
 
130
130
  def self.drop_indexes?(name, payload)
131
- name == :deleteIndexes && payload[:selector] && payload[:selector][:index] == '*'
131
+ name == :deleteIndexes && payload[:selector] && payload[:selector][:index] == ASTERISK
132
132
  end
133
133
 
134
134
  def self.drop_index?(name, payload)
@@ -3,7 +3,7 @@
3
3
  # frozen_string_literal: true
4
4
 
5
5
  require 'json'
6
- require 'base64'
6
+ require 'new_relic/base64'
7
7
 
8
8
  module NewRelic
9
9
  module Agent
@@ -78,7 +78,7 @@ module NewRelic
78
78
  end
79
79
 
80
80
  def from_http_safe(http_safe_payload)
81
- decoded_payload = Base64.strict_decode64(http_safe_payload)
81
+ decoded_payload = NewRelic::Base64.strict_decode64(http_safe_payload)
82
82
  from_json(decoded_payload)
83
83
  end
84
84
 
@@ -156,7 +156,7 @@ module NewRelic
156
156
  #
157
157
  # @api public
158
158
  def http_safe
159
- Base64.strict_encode64(text)
159
+ NewRelic::Base64.strict_encode64(text)
160
160
  end
161
161
  end
162
162
  end
@@ -156,7 +156,7 @@ module NewRelic
156
156
  end
157
157
 
158
158
  if !errors.empty?
159
- ::NewRelic::Agent.logger.error("#{errors.size} error(s) running task for event '#{event}' in Agent Event Loop:", *errors)
159
+ ::NewRelic::Agent.logger.error("#{errors.size} error(s) running task for event '#{event}' in agent event loop:", *errors)
160
160
  end
161
161
  end
162
162
 
@@ -14,6 +14,10 @@ module NewRelic
14
14
  #
15
15
  # @api public
16
16
  class AbstractRequest
17
+ LHOST = 'host'
18
+ UHOST = 'Host'
19
+ COLON = ':'
20
+
17
21
  %i[[] []= type host_from_header host method headers uri].each do |name|
18
22
  define_method(name) do
19
23
  not_implemented(name)
@@ -31,9 +31,6 @@ module NewRelic
31
31
  end
32
32
 
33
33
  ASYNC_HTTP = 'Async::HTTP'
34
- LHOST = 'host'
35
- UHOST = 'Host'
36
- COLON = ':'
37
34
 
38
35
  def type
39
36
  ASYNC_HTTP
@@ -7,10 +7,8 @@ require_relative 'abstract'
7
7
  module NewRelic
8
8
  module Agent
9
9
  module HTTPClients
10
- class CurbRequest
10
+ class CurbRequest < AbstractRequest
11
11
  CURB = 'Curb'
12
- LHOST = 'host'
13
- UHOST = 'Host'
14
12
 
15
13
  def initialize(curlobj)
16
14
  @curlobj = curlobj
@@ -42,8 +42,6 @@ module NewRelic
42
42
  DEFAULT_ACTION = 'GET'
43
43
  DEFAULT_HOST = 'UNKNOWN_HOST'
44
44
  ETHON = 'Ethon'
45
- LHOST = 'host'.freeze
46
- UHOST = 'Host'.freeze
47
45
 
48
46
  def initialize(easy)
49
47
  @easy = easy
@@ -47,9 +47,6 @@ module NewRelic
47
47
  attr_reader :method
48
48
 
49
49
  EXCON = 'Excon'
50
- LHOST = 'host'
51
- UHOST = 'Host'
52
- COLON = ':'
53
50
 
54
51
  def initialize(datum)
55
52
  @datum = datum
@@ -20,8 +20,6 @@ module NewRelic
20
20
 
21
21
  class HTTPRequest < AbstractRequest
22
22
  HTTP_RB = 'http.rb'
23
- HOST = 'host'
24
- COLON = ':'
25
23
 
26
24
  def initialize(wrapped_request)
27
25
  @wrapped_request = wrapped_request
@@ -36,7 +34,7 @@ module NewRelic
36
34
  end
37
35
 
38
36
  def host_from_header
39
- if hostname = self[HOST]
37
+ if hostname = self[LHOST]
40
38
  hostname.split(COLON).first
41
39
  end
42
40
  end
@@ -26,9 +26,6 @@ module NewRelic
26
26
  attr_reader :request
27
27
 
28
28
  HTTP_CLIENT = 'HTTPClient'.freeze
29
- LHOST = 'host'.freeze
30
- UHOST = 'Host'.freeze
31
- COLON = ':'.freeze
32
29
 
33
30
  def initialize(request)
34
31
  @request = request
@@ -52,8 +52,6 @@ module NewRelic
52
52
 
53
53
  DEFAULT_HOST = 'UNKNOWN_HOST'
54
54
  TYPE = 'HTTPX'
55
- LHOST = 'host'.freeze
56
- UHOST = 'Host'.freeze
57
55
 
58
56
  def initialize(request)
59
57
  @request = request
@@ -30,11 +30,8 @@ module NewRelic
30
30
  NET_HTTP
31
31
  end
32
32
 
33
- HOST = 'host'
34
- COLON = ':'
35
-
36
33
  def host_from_header
37
- if hostname = self[HOST]
34
+ if hostname = self[LHOST]
38
35
  hostname.split(COLON).first
39
36
  end
40
37
  end
@@ -48,9 +48,6 @@ module NewRelic
48
48
  TYPHOEUS
49
49
  end
50
50
 
51
- LHOST = 'host'.freeze
52
- UHOST = 'Host'.freeze
53
-
54
51
  def host_from_header
55
52
  self[LHOST] || self[UHOST]
56
53
  end
@@ -39,7 +39,7 @@ DependencyDetection.defer do
39
39
  executes do
40
40
  next unless Gem::Version.new(ActiveMerchant::VERSION) < Gem::Version.new('1.65.0')
41
41
 
42
- deprecation_msg = 'The Ruby Agent is dropping support for ActiveMerchant versions below 1.65.0 ' \
42
+ deprecation_msg = 'The Ruby agent is dropping support for ActiveMerchant versions below 1.65.0 ' \
43
43
  'in version 9.0.0. Please upgrade your ActiveMerchant version to continue receiving full support. ' \
44
44
 
45
45
  NewRelic::Agent.logger.log_once(
@@ -10,7 +10,9 @@ DependencyDetection.defer do
10
10
  named :async_http
11
11
 
12
12
  depends_on do
13
- defined?(Async::HTTP) && Gem::Version.new(Async::HTTP::VERSION) >= Gem::Version.new('0.59.0')
13
+ defined?(Async::HTTP) &&
14
+ Gem::Version.new(Async::HTTP::VERSION) >= Gem::Version.new('0.59.0') &&
15
+ !defined?(Traces::Backend::NewRelic) # defined in the traces-backend-newrelic gem
14
16
  end
15
17
 
16
18
  executes do
@@ -56,7 +56,7 @@ module NewRelic::Agent::Instrumentation
56
56
  return if nr_hosts.empty?
57
57
 
58
58
  NewRelic::Agent.disable_all_tracing do
59
- @nr_cluster_name ||= perform_request('GET', '_cluster/health').body['cluster_name']
59
+ @nr_cluster_name ||= perform_request('GET', '/').body['cluster_name']
60
60
  end
61
61
  rescue StandardError => e
62
62
  NewRelic::Agent.logger.error('Failed to get cluster name for elasticsearch', e)
@@ -14,10 +14,7 @@ module NewRelic::Agent::Instrumentation
14
14
  def add_thread_tracing(&block)
15
15
  return block if !NewRelic::Agent::Tracer.thread_tracing_enabled?
16
16
 
17
- NewRelic::Agent::Tracer.thread_block_with_current_transaction(
18
- segment_name: 'Ruby/Fiber',
19
- &block
20
- )
17
+ NewRelic::Agent::Tracer.thread_block_with_current_transaction(&block)
21
18
  end
22
19
  end
23
20
  end
@@ -14,7 +14,7 @@ DependencyDetection.defer do
14
14
  end
15
15
 
16
16
  executes do
17
- supportability_name = NewRelic::Agent::Instrumentation::GRPC::Client::INSTRUMENTATION_NAME
17
+ supportability_name = NewRelic::Agent::Instrumentation::GRPC::Server::INSTRUMENTATION_NAME
18
18
  if use_prepend?
19
19
  prepend_instrument GRPC::RpcServer, NewRelic::Agent::Instrumentation::GRPC::Server::RpcServerPrepend, supportability_name
20
20
  prepend_instrument GRPC::RpcDesc, NewRelic::Agent::Instrumentation::GRPC::Server::RpcDescPrepend, supportability_name
@@ -33,7 +33,7 @@ module NewRelic::Agent::Instrumentation
33
33
  set(:newrelic_ignores, Hash.new([])) if !respond_to?(:newrelic_ignores)
34
34
 
35
35
  # If we call an ignore without a route, it applies to the whole app
36
- routes = ['*'] if routes.empty?
36
+ routes = [::NewRelic::ASTERISK] if routes.empty?
37
37
 
38
38
  settings.newrelic_ignores[type] += routes.map do |r|
39
39
  # Ugly sending to private Base#compile, but we want to mimic
@@ -46,7 +46,7 @@ DependencyDetection.defer do
46
46
  executes do
47
47
  next unless Gem::Version.new(Sinatra::VERSION) < Gem::Version.new('2.0.0')
48
48
 
49
- deprecation_msg = 'The Ruby Agent is dropping support for Sinatra versions below 2.0.0 ' \
49
+ deprecation_msg = 'The Ruby agent is dropping support for Sinatra versions below 2.0.0 ' \
50
50
  'in version 9.0.0. Please upgrade your Sinatra version to continue receiving full compatibility. ' \
51
51
 
52
52
  NewRelic::Agent.logger.log_once(
@@ -16,10 +16,7 @@ module NewRelic
16
16
  def add_thread_tracing(*args, &block)
17
17
  return block if !NewRelic::Agent::Tracer.thread_tracing_enabled?
18
18
 
19
- NewRelic::Agent::Tracer.thread_block_with_current_transaction(
20
- segment_name: 'Ruby/Thread',
21
- &block
22
- )
19
+ NewRelic::Agent::Tracer.thread_block_with_current_transaction(&block)
23
20
  end
24
21
  end
25
22
  end