newrelic_rpm 9.10.2 → 9.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +91 -1
  3. data/README.md +1 -1
  4. data/lib/new_relic/agent/agent_logger.rb +1 -0
  5. data/lib/new_relic/agent/configuration/default_source.rb +114 -3
  6. data/lib/new_relic/agent/database/obfuscator.rb +1 -0
  7. data/lib/new_relic/agent/error_collector.rb +14 -10
  8. data/lib/new_relic/agent/instrumentation/aws_sqs/chain.rb +37 -0
  9. data/lib/new_relic/agent/instrumentation/aws_sqs/instrumentation.rb +67 -0
  10. data/lib/new_relic/agent/instrumentation/aws_sqs/prepend.rb +21 -0
  11. data/lib/new_relic/agent/instrumentation/aws_sqs.rb +25 -0
  12. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +14 -0
  13. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +1 -1
  14. data/lib/new_relic/agent/instrumentation/logstasher/chain.rb +21 -0
  15. data/lib/new_relic/agent/instrumentation/logstasher/instrumentation.rb +24 -0
  16. data/lib/new_relic/agent/instrumentation/logstasher/prepend.rb +13 -0
  17. data/lib/new_relic/agent/instrumentation/logstasher.rb +27 -0
  18. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +3 -0
  19. data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +9 -5
  20. data/lib/new_relic/agent/instrumentation/redis/cluster_middleware.rb +26 -0
  21. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +14 -11
  22. data/lib/new_relic/agent/instrumentation/redis/middleware.rb +3 -0
  23. data/lib/new_relic/agent/instrumentation/redis.rb +5 -0
  24. data/lib/new_relic/agent/instrumentation/stripe_subscriber.rb +22 -1
  25. data/lib/new_relic/agent/local_log_decorator.rb +8 -1
  26. data/lib/new_relic/agent/log_event_aggregator.rb +91 -26
  27. data/lib/new_relic/control/instance_methods.rb +1 -0
  28. data/lib/new_relic/control/private_instance_methods.rb +4 -0
  29. data/lib/new_relic/control/security_interface.rb +57 -0
  30. data/lib/new_relic/control.rb +1 -1
  31. data/lib/new_relic/rack/browser_monitoring.rb +11 -7
  32. data/lib/new_relic/version.rb +2 -2
  33. data/lib/tasks/config.rake +5 -2
  34. data/lib/tasks/gha.rake +31 -0
  35. data/lib/tasks/helpers/config.html.erb +1 -1
  36. data/lib/tasks/helpers/format.rb +1 -1
  37. data/lib/tasks/helpers/newrelicyml.rb +3 -2
  38. data/lib/tasks/instrumentation_generator/instrumentation.thor +1 -0
  39. data/newrelic.yml +202 -135
  40. data/newrelic_rpm.gemspec +2 -0
  41. data/test/agent_helper.rb +9 -0
  42. metadata +42 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cef71bbfaac5e07f6d5b0862fccb3bf35e4c99251ce5fec00143036c89c964f8
4
- data.tar.gz: e5521d0958408d97494625b155f2dcb97736d02994f7b7dfdc58143dabc73dee
3
+ metadata.gz: 3c551a88ec42cceb53ade85126fe41272598c367b11d70e5167d374556b6fe8d
4
+ data.tar.gz: 912ff4f8d33e2ba318b4ec74fa8a3e0680c21fda3521a2382658855219ec81d6
5
5
  SHA512:
6
- metadata.gz: 28a45e748a241b3bfb2c93bb19500cda6bc433c9c428e56f4cbcc92ff5c12d8f6d0198ab87d3a910f11539695fc8d0a4935c65ea5869d6bf36b66ae2b012c3a7
7
- data.tar.gz: 35426f77a90e9f10b2be825538482a5bda1d074cc4d3c22acd1df007774f21a190b10696ad962fe34e30db0dd57d0a5bcadb3db6d5bc97edad0dcfba88db9a19
6
+ metadata.gz: 61472afe9cf52eea1a86e4394b613666372c6a0086ea1173c28d8341ff417cf980feb6fd7a25f23ec2e78bb02cc4a32efeb5102f1f42175300d0a0f8ba7eea1b
7
+ data.tar.gz: e3de1701d6f580a18ceb05c1607d3eada9081012e6bc8edec503b2e945d7128312224c63604dd40debb8554fcc13621a731251f4e349dbcdef909cf09c60c867
data/CHANGELOG.md CHANGED
@@ -1,12 +1,102 @@
1
1
  # New Relic Ruby Agent Release Notes
2
2
 
3
+ ## v9.12.0
4
+
5
+ Version 9.12.0 adds support for the `newrelic_security` agent, introduces instrumentation for the LogStasher gem, improves instrumentation for the `redis-clustering` gem, and updates the Elasticsearch instrumentation to only attempt to get the cluster name once per client, even if it fails.
6
+
7
+ - **Feature: Add support for the newrelic_security agent**
8
+
9
+ [New Relic Interactive Application Security Testing (IAST)](https://docs.newrelic.com/docs/iast/introduction/) can help you prevent cyberattacks and breaches on your applications by probing your running code for exploitable vulnerabilities.
10
+
11
+ The `newrelic_security` gem provides this feature for Ruby. It depends on `newrelic_rpm`. This is the first version of `newrelic_rpm` compatible with `newrelic_security`.
12
+
13
+ At this time, the security agent is intended for use only within a dedicated security testing environment with data that can tolerate modification or deletion. The security agent is available as a separate Ruby gem, `newrelic_security`. It is recommended that this separate gem only be introduced to a security testing environment by leveraging Bundler grouping like so:
14
+
15
+ ```ruby
16
+ # Gemfile
17
+ gem 'newrelic_rpm' # New Relic APM observability agent
18
+ gem 'newrelic-infinite_tracing' # New Relic Infinite Tracing
19
+
20
+ group :security do
21
+ gem 'newrelic_security', require: false # New Relic security agent
22
+ end
23
+ ```
24
+
25
+ In order to run the security agent, you need to update your configuration. At a minimum, `security.agent.enabled` and `security.enabled` must be set to `true`. They are `false` by default. Similar to the gem installation, we recommend you set these configurations for a special security testing environment only.
26
+
27
+ Here's an example using `newrelic.yml`:
28
+
29
+ ```yaml
30
+ common: &default_settings
31
+ license_key: <%= ENV['NEW_RELIC_LICENSE_KEY'] %>
32
+ app_name: "Example app"
33
+
34
+ development:
35
+ <<: *default_settings
36
+ app_name: <%= app_name %> (Development)
37
+
38
+ security:
39
+ <<: *default_settings
40
+ security.enabled: true
41
+ security.agent.enabled: true
42
+
43
+ production:
44
+ <<: *default_settings
45
+ ```
46
+
47
+ The following configuration relate to the `newrelic_security` gem:
48
+
49
+ | Configuration name | Default | Behavior |
50
+ | ------------------ | ------- |----------|
51
+ | security.agent.enabled | `false` | If `true`, the security agent is loaded (a Ruby 'require' is performed) |
52
+ | security.enabled | `false` | If `true`, the security agent is started (the agent runs in its event loop) |
53
+ | security.mode | `'IAST'` | Defines the mode for the security agent to operate in. Currently only 'IAST' is supported |
54
+ | security.validator_service_url | `'wss://csec.nr-data.net'` | Defines the endpoint URL for posting security related data |
55
+ | security.detection.rci.enabled | `true` | If `true`, enables RCI (remote code injection) detection |
56
+ | security.detection.rxss.enabled | `true` | If `true`, enables RXSS (reflected cross-site scripting) detection |
57
+ | security.detection.deserialization.enabled | `true` | If `true`, enables deserialization detection |
58
+ | security.application_info.port | `nil` | An Integer representing the port the application is listening on. This setting is mandatory for Passenger servers. Other servers should be detected by default. |
59
+
60
+ - **Feature: Add instrumentation for LogStasher**
61
+
62
+ The agent will now record logs generated by [LogStasher](https://github.com/shadabahmed/logstasher). Versions 1.0.0 and above of the LogStasher gem are supported. [PR#2559](https://github.com/newrelic/newrelic-ruby-agent/pull/2559)
63
+
64
+ - **Feature: Add instrumentation for redis-clustering**
65
+
66
+ Version 5.x of the `redis` gem moved cluster behavior into a different gem, `redis-clustering`. This gem can access instrumentation registered through `RedisClient::Middleware`. Previously, the agent only instrumented the `call_pipelined` method through this approach, but now users of the `redis-clustering` gem will also have instrumentation registered for `connect` and `call` methods. In addition, the way the `database_name` attribute is set for Redis datastore spans is now compatible with all versions of Redis supported by the New Relic Ruby agent. Thank you, [@praveen-ks](https://github.com/praveen-ks) for bringing this to our attention. [Issue#2444](https://github.com/newrelic/newrelic-ruby-agent/issues/2444) [PR#2720](https://github.com/newrelic/newrelic-ruby-agent/pull/2720)
67
+
68
+ - **Bugfix: Update Elasticsearch instrumentation to only attempt to get the cluster name once per client**
69
+
70
+ Previously, the agent would attempt to get the cluster name every time a call was made if it was not already captured. This could lead to a large number of failures if the cluster name could not be retrieved. Now, the agent will only attempt to get the cluster name once per client, even if it fails. Thank you, [@ascoppa](https://github.com/ascoppa) for bringing this to our attention. [Issue#2730](https://github.com/newrelic/newrelic-ruby-agent/issues/2730) [PR#2743](https://github.com/newrelic/newrelic-ruby-agent/pull/2743)
71
+
72
+ - **Feature: Produce metrics for 4 additional Action Controller Rails notifications**
73
+
74
+ Four additional Action Controller related Rails notifications are now subscribed to by the agent to produce telemetry. These 4 are `exist_fragment?`, `expire_fragment`, `read_fragment`, and `write_fragment`. As with instrumentation for Action Controller itself, these notifications are enabled by default and can be disabled by setting `:disable_action_controller` to `true` in the agent's `newrelic.yml` configuration file. [PR#2745](https://github.com/newrelic/newrelic-ruby-agent/pull/2745)
75
+
76
+
77
+ ## v9.11.0
78
+
79
+ 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.
80
+
81
+ - **Feature: Add instrumentation for SQS**
82
+
83
+ 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)
84
+
85
+ - **Bugfix: HTTP status code based expected errors will now have an "expected" value of "true"**
86
+
87
+ 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)
88
+
89
+ - **Bugfix: Stripe metric names will no longer include full request paths to limit the unique name count**
90
+
91
+ 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)
92
+
3
93
  ## v9.10.2
4
94
 
5
95
  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
96
 
7
97
  - **Bugfix: DynamoDB instrumentation logging errors when trying to get account_id**
8
98
 
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)
99
+ 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
100
 
11
101
  - **Bugfix: Remove Rails::Command::RakeCommand from the default list of autostart.denylisted_constants**
12
102
 
data/README.md CHANGED
@@ -24,7 +24,7 @@ You can also monitor non-web applications. Refer to the "Other
24
24
  Environments" section below.
25
25
 
26
26
  We offer an AWS Lambda layer for instrumenting your serverless Ruby functions.
27
- Details can be found on our [getting started guide](https://docs.newrelic.com/docs/serverless-function-monitoring/aws-lambda-monitoring/get-started/monitoring-aws-lambda-serverless-monitoring/).
27
+ Details can be found on our [getting started guide](https://docs.newrelic.com/docs/serverless-function-monitoring/aws-lambda-monitoring/instrument-lambda-function/instrument-your-own/).
28
28
 
29
29
  ## Installing and Using
30
30
 
@@ -4,6 +4,7 @@
4
4
 
5
5
  require 'thread'
6
6
  require 'logger'
7
+ require 'singleton'
7
8
  require 'new_relic/agent/hostname'
8
9
  require 'new_relic/agent/log_once'
9
10
  require 'new_relic/agent/instrumentation/logger/instrumentation'
@@ -72,7 +72,7 @@ module NewRelic
72
72
  value_from_defaults(key, :transform)
73
73
  end
74
74
 
75
- def self.config_search_paths # rubocop:disable Metrics/AbcSize
75
+ def self.config_search_paths
76
76
  proc {
77
77
  yaml = 'newrelic.yml'
78
78
  config_yaml = File.join('config', yaml)
@@ -1112,7 +1112,7 @@ module NewRelic
1112
1112
  :public => true,
1113
1113
  :type => Boolean,
1114
1114
  :allowed_from_server => true,
1115
- :description => "If `true`, the agent will report source code level metrics for traced methods.\nsee: " \
1115
+ :description => "If `true`, the agent will report source code level metrics for traced methods.\nSee: " \
1116
1116
  'https://docs.newrelic.com/docs/apm/agents/ruby-agent/features/ruby-codestream-integration/'
1117
1117
  },
1118
1118
  # Cross application tracer
@@ -1150,7 +1150,7 @@ module NewRelic
1150
1150
  :allowed_from_server => true,
1151
1151
  :dynamic_name => true,
1152
1152
  :description => <<~DESC
1153
- * Specify a maximum number of custom events to buffer in memory at a time.'
1153
+ * Specify a maximum number of custom events to buffer in memory at a time.
1154
1154
  * When configuring the agent for [AI monitoring](/docs/ai-monitoring/intro-to-ai-monitoring), \
1155
1155
  set to max value `100000`. This ensures the agent captures the maximum amount of LLM events.
1156
1156
  DESC
@@ -1444,6 +1444,7 @@ module NewRelic
1444
1444
  },
1445
1445
  :'instrumentation.async_http' => {
1446
1446
  :default => 'auto',
1447
+ :documentation_default => 'auto',
1447
1448
  :public => true,
1448
1449
  :type => String,
1449
1450
  :dynamic_name => true,
@@ -1452,14 +1453,24 @@ module NewRelic
1452
1453
  },
1453
1454
  :'instrumentation.bunny' => {
1454
1455
  :default => 'auto',
1456
+ :documentation_default => 'auto',
1455
1457
  :public => true,
1456
1458
  :type => String,
1457
1459
  :dynamic_name => true,
1458
1460
  :allowed_from_server => false,
1459
1461
  :description => 'Controls auto-instrumentation of bunny at start-up. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
1460
1462
  },
1463
+ :'instrumentation.aws_sqs' => {
1464
+ :default => 'auto',
1465
+ :public => true,
1466
+ :type => String,
1467
+ :dynamic_name => true,
1468
+ :allowed_from_server => false,
1469
+ :description => 'Controls auto-instrumentation of the aws-sdk-sqs library at start-up. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
1470
+ },
1461
1471
  :'instrumentation.dynamodb' => {
1462
1472
  :default => 'auto',
1473
+ :documentation_default => 'auto',
1463
1474
  :public => true,
1464
1475
  :type => String,
1465
1476
  :dynamic_name => true,
@@ -1468,6 +1479,7 @@ module NewRelic
1468
1479
  },
1469
1480
  :'instrumentation.fiber' => {
1470
1481
  :default => 'auto',
1482
+ :documentation_default => 'auto',
1471
1483
  :public => true,
1472
1484
  :type => String,
1473
1485
  :dynamic_name => true,
@@ -1476,6 +1488,7 @@ module NewRelic
1476
1488
  },
1477
1489
  :'instrumentation.concurrent_ruby' => {
1478
1490
  :default => 'auto',
1491
+ :documentation_default => 'auto',
1479
1492
  :public => true,
1480
1493
  :type => String,
1481
1494
  :dynamic_name => true,
@@ -1502,6 +1515,7 @@ module NewRelic
1502
1515
  },
1503
1516
  :'instrumentation.elasticsearch' => {
1504
1517
  :default => 'auto',
1518
+ :documentation_default => 'auto',
1505
1519
  :public => true,
1506
1520
  :type => String,
1507
1521
  :dynamic_name => true,
@@ -1510,6 +1524,7 @@ module NewRelic
1510
1524
  },
1511
1525
  :'instrumentation.ethon' => {
1512
1526
  :default => 'auto',
1527
+ :documentation_default => 'auto',
1513
1528
  :public => true,
1514
1529
  :type => String,
1515
1530
  :dynamic_name => true,
@@ -1527,6 +1542,7 @@ module NewRelic
1527
1542
  },
1528
1543
  :'instrumentation.grape' => {
1529
1544
  :default => 'auto',
1545
+ :documentation_default => 'auto',
1530
1546
  :public => true,
1531
1547
  :type => String,
1532
1548
  :dynamic_name => true,
@@ -1595,8 +1611,18 @@ module NewRelic
1595
1611
  :allowed_from_server => false,
1596
1612
  :description => 'Controls auto-instrumentation of Ruby standard library Logger at start-up. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
1597
1613
  },
1614
+ :'instrumentation.logstasher' => {
1615
+ :default => instrumentation_value_from_boolean(:'application_logging.enabled'),
1616
+ :documentation_default => 'auto',
1617
+ :public => true,
1618
+ :type => String,
1619
+ :dynamic_name => true,
1620
+ :allowed_from_server => false,
1621
+ :description => 'Controls auto-instrumentation of the LogStasher library at start-up. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
1622
+ },
1598
1623
  :'instrumentation.memcache' => {
1599
1624
  :default => 'auto',
1625
+ :documentation_default => 'auto',
1600
1626
  :public => true,
1601
1627
  :type => String,
1602
1628
  :dynamic_name => true,
@@ -1690,6 +1716,7 @@ module NewRelic
1690
1716
  },
1691
1717
  :'instrumentation.rake' => {
1692
1718
  :default => 'auto',
1719
+ :documentation_default => 'auto',
1693
1720
  :public => true,
1694
1721
  :type => String,
1695
1722
  :dynamic_name => true,
@@ -1698,6 +1725,7 @@ module NewRelic
1698
1725
  },
1699
1726
  :'instrumentation.redis' => {
1700
1727
  :default => 'auto',
1728
+ :documentation_default => 'auto',
1701
1729
  :public => true,
1702
1730
  :type => String,
1703
1731
  :dynamic_name => true,
@@ -1715,6 +1743,7 @@ module NewRelic
1715
1743
  },
1716
1744
  :'instrumentation.roda' => {
1717
1745
  :default => 'auto',
1746
+ :documentation_default => 'auto',
1718
1747
  :public => true,
1719
1748
  :type => String,
1720
1749
  :dynamic_name => true,
@@ -1723,6 +1752,7 @@ module NewRelic
1723
1752
  },
1724
1753
  :'instrumentation.sinatra' => {
1725
1754
  :default => 'auto',
1755
+ :documentation_default => 'auto',
1726
1756
  :public => true,
1727
1757
  :type => String,
1728
1758
  :dynamic_name => true,
@@ -1738,6 +1768,7 @@ module NewRelic
1738
1768
  },
1739
1769
  :'instrumentation.view_component' => {
1740
1770
  :default => 'auto',
1771
+ :documentation_default => 'auto',
1741
1772
  :public => true,
1742
1773
  :type => String,
1743
1774
  :dynamic_name => true,
@@ -1774,6 +1805,7 @@ module NewRelic
1774
1805
  },
1775
1806
  :'instrumentation.thread' => {
1776
1807
  :default => 'auto',
1808
+ :documentation_default => 'auto',
1777
1809
  :public => true,
1778
1810
  :type => String,
1779
1811
  :dynamic_name => true,
@@ -1796,6 +1828,7 @@ module NewRelic
1796
1828
  },
1797
1829
  :'instrumentation.tilt' => {
1798
1830
  :default => 'auto',
1831
+ :documentation_default => 'auto',
1799
1832
  :public => true,
1800
1833
  :type => String,
1801
1834
  :dynamic_name => true,
@@ -2506,6 +2539,84 @@ module NewRelic
2506
2539
  :type => Integer,
2507
2540
  :allowed_from_server => false,
2508
2541
  :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).'
2542
+ },
2543
+ # security agent
2544
+ :'security.agent.enabled' => {
2545
+ :default => false,
2546
+ :external => true,
2547
+ :public => true,
2548
+ :type => Boolean,
2549
+ :allowed_from_server => false,
2550
+ :description => "If `true`, the security agent is loaded (a Ruby 'require' is performed)"
2551
+ },
2552
+ :'security.enabled' => {
2553
+ :default => false,
2554
+ :external => true,
2555
+ :public => true,
2556
+ :type => Boolean,
2557
+ :allowed_from_server => false,
2558
+ :description => 'If `true`, the security agent is started (the agent runs in its event loop)'
2559
+ },
2560
+ :'security.mode' => {
2561
+ :default => 'IAST',
2562
+ :external => true,
2563
+ :public => true,
2564
+ :type => String,
2565
+ :allowed_from_server => true,
2566
+ :allowlist => %w[IAST RASP],
2567
+ :description => 'Defines the mode for the security agent to operate in. Currently only `IAST` is supported',
2568
+ :dynamic_name => true
2569
+ },
2570
+ :'security.validator_service_url' => {
2571
+ :default => 'wss://csec.nr-data.net',
2572
+ :external => true,
2573
+ :public => true,
2574
+ :type => String,
2575
+ :allowed_from_server => true,
2576
+ :description => 'Defines the endpoint URL for posting security-related data',
2577
+ :dynamic_name => true
2578
+ },
2579
+ :'security.detection.rci.enabled' => {
2580
+ :default => true,
2581
+ :external => true,
2582
+ :public => true,
2583
+ :type => Boolean,
2584
+ :allowed_from_server => false,
2585
+ :description => 'If `true`, enables RCI (remote code injection) detection'
2586
+ },
2587
+ :'security.detection.rxss.enabled' => {
2588
+ :default => true,
2589
+ :external => true,
2590
+ :public => true,
2591
+ :type => Boolean,
2592
+ :allowed_from_server => false,
2593
+ :description => 'If `true`, enables RXSS (reflected cross-site scripting) detection'
2594
+ },
2595
+ :'security.detection.deserialization.enabled' => {
2596
+ :default => true,
2597
+ :external => true,
2598
+ :public => true,
2599
+ :type => Boolean,
2600
+ :allowed_from_server => false,
2601
+ :description => 'If `true`, enables deserialization detection'
2602
+ },
2603
+ :'security.application_info.port' => {
2604
+ :default => nil,
2605
+ :allow_nil => true,
2606
+ :public => true,
2607
+ :type => Integer,
2608
+ :external => true,
2609
+ :allowed_from_server => false,
2610
+ :description => 'The port the application is listening on. This setting is mandatory for Passenger servers. Other servers should be detected by default.'
2611
+ },
2612
+ :'security.request.body_limit' => {
2613
+ :default => 300,
2614
+ :allow_nil => true,
2615
+ :public => true,
2616
+ :type => Integer,
2617
+ :external => true,
2618
+ :allowed_from_server => false,
2619
+ :description => 'Defines the request body limit to process in security events (in KB). The default value is 300, for 300KB.'
2509
2620
  }
2510
2621
  }.freeze
2511
2622
  # rubocop:enable Metrics/CollectionLiteralLength
@@ -2,6 +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
+ require 'singleton'
5
6
  require 'new_relic/agent/database/obfuscation_helpers'
6
7
 
7
8
  module NewRelic
@@ -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
@@ -48,6 +48,12 @@ module NewRelic
48
48
  correlation_id: opts[:correlation_id],
49
49
  exchange_type: type
50
50
  )
51
+ if segment
52
+ segment.add_agent_attribute('server.address', channel&.connection&.hostname)
53
+ segment.add_agent_attribute('server.port', channel&.connection&.port)
54
+ segment.add_agent_attribute('messaging.destination.name', destination) # for produce, this is exchange name
55
+ segment.add_agent_attribute('messaging.rabbitmq.destination.routing_key', opts[:routing_key])
56
+ end
51
57
  rescue => e
52
58
  NewRelic::Agent.logger.error('Error starting message broker segment in Bunny::Exchange#publish', e)
53
59
  yield
@@ -94,6 +100,14 @@ module NewRelic
94
100
  queue_name: name,
95
101
  start_time: t0
96
102
  )
103
+ if segment
104
+ segment.add_agent_attribute('server.address', channel&.connection&.hostname)
105
+ segment.add_agent_attribute('server.port', channel&.connection&.port)
106
+ segment.add_agent_attribute('messaging.destination.name', name) # for consume, this is queue name
107
+ segment.add_agent_attribute('messaging.destination_publish.name', exch_name)
108
+ segment.add_agent_attribute('message.queueName', name)
109
+ segment.add_agent_attribute('messaging.rabbitmq.destination.routing_key', delivery_info&.routing_key)
110
+ end
97
111
  rescue => e
98
112
  NewRelic::Agent.logger.error('Error starting message broker segment in Bunny::Queue#pop', e)
99
113
  else
@@ -102,7 +102,7 @@ module NewRelic::Agent::Instrumentation
102
102
  end
103
103
 
104
104
  def nr_cluster_name
105
- return @nr_cluster_name if @nr_cluster_name
105
+ return @nr_cluster_name if defined?(@nr_cluster_name)
106
106
  return if nr_hosts.empty?
107
107
 
108
108
  NewRelic::Agent.disable_all_tracing do