newrelic_rpm 8.14.0 → 8.15.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: 49ca87c2e7358491ffae831592a15cd16b7941c383ed820c08bef95848755488
4
- data.tar.gz: 6531168cb2c4fcefa32c48efb457013798f7e2ca0bcdd42e3773ea77c91af072
3
+ metadata.gz: f47710c44016e66769de790e72f361e78671a66d676ce1251bb65fe932dfb617
4
+ data.tar.gz: 16886676b0209e4822017475ec470ad11ec20ebb65354a2bd2c022b4d3d3b90e
5
5
  SHA512:
6
- metadata.gz: ff267f3c298e097fd669ed70880f7facb2f85f6402cc117cef50c2449d72795784835076a215f788733abe6a0b28e3541215ce04608be0fc634883ab8931476f
7
- data.tar.gz: 52f6cfd4e327d3c788661d667605d7585015d0ec43ca21fe93fa1fff48251a8721717aa454be7515bed2f0d7751f58f99090504a4cf6d85d391ac3c8d738cd7f
6
+ metadata.gz: f334495833c77703fb5f439617ba4b61c4e07e2138775e510f1c293afa4496ddfe9528582e2cfddcf85e9b04dddfa36dcc58ff110bbd0d05d02aaa2128346633
7
+ data.tar.gz: b1eea25ed1b3881d974af3f179cbafc1caf605ffa2941e6a3a4be046aa7afd99643c6865fb0b88ac9817f3e5e630784842502c0aad02af4fcd79418b37eab5fd
data/.rubocop.yml CHANGED
@@ -14,7 +14,135 @@ AllCops:
14
14
  Exclude:
15
15
  - 'test/multiverse/suites/active_record/db/schema.rb'
16
16
  - 'test/multiverse/suites/active_record_pg/db/schema.rb'
17
- NewCops: enable
17
+
18
+ # New cops
19
+ Layout/LineContinuationLeadingSpace: # new in 1.31
20
+ Enabled: true
21
+ Layout/LineContinuationSpacing: # new in 1.31
22
+ Enabled: true
23
+ Lint/ConstantOverwrittenInRescue: # new in 1.31
24
+ Enabled: true
25
+ Lint/DuplicateMagicComment: # new in 1.37
26
+ Enabled: true
27
+ Lint/NonAtomicFileOperation: # new in 1.31
28
+ Enabled: true
29
+ Lint/RefinementImportMethods: # new in 1.27
30
+ Enabled: true
31
+ Lint/RequireRangeParentheses: # new in 1.32
32
+ Enabled: true
33
+ Lint/UselessRuby2Keywords: # new in 1.23
34
+ Enabled: true
35
+ Naming/BlockForwarding: # new in 1.24
36
+ Enabled: true
37
+ Security/CompoundHash: # new in 1.28
38
+ Enabled: true
39
+ Style/ArrayIntersect: # new in 1.40
40
+ Enabled: true
41
+ Style/EmptyHeredoc: # new in 1.32
42
+ Enabled: true
43
+ Style/FileRead: # new in 1.24
44
+ Enabled: true
45
+ Style/FileWrite: # new in 1.24
46
+ Enabled: true
47
+ Style/MagicCommentFormat: # new in 1.35
48
+ Enabled: true
49
+ Style/MapCompactWithConditionalBlock: # new in 1.30
50
+ Enabled: true
51
+ Style/MapToSet: # new in 1.42
52
+ Enabled: true
53
+ Style/MinMaxComparison: # new in 1.42
54
+ Enabled: true
55
+ Style/NestedFileDirname: # new in 1.26
56
+ Enabled: true
57
+ Style/ObjectThen: # new in 1.28
58
+ Enabled: true
59
+ Style/OperatorMethodCall: # new in 1.37
60
+ Enabled: true
61
+ Style/RedundantConstantBase: # new in 1.40
62
+ Enabled: true
63
+ Style/RedundantDoubleSplatHashBraces: # new in 1.41
64
+ Enabled: true
65
+ Style/RedundantEach: # new in 1.38
66
+ Enabled: true
67
+ Style/RedundantInitialize: # new in 1.27
68
+ Enabled: true
69
+ Style/RedundantStringEscape: # new in 1.37
70
+ Enabled: true
71
+ Style/YodaExpression: # new in 1.42
72
+ Enabled: true
73
+ Minitest/AssertKindOf: # new in 0.10
74
+ Enabled: true
75
+ Minitest/AssertOutput: # new in 0.10
76
+ Enabled: true
77
+ Minitest/AssertPathExists: # new in 0.10
78
+ Enabled: true
79
+ Minitest/AssertPredicate: # new in 0.18
80
+ Enabled: true
81
+ Minitest/AssertRaisesCompoundBody: # new in 0.21
82
+ Enabled: true
83
+ Minitest/AssertRaisesWithRegexpArgument: # new in 0.22
84
+ Enabled: true
85
+ Minitest/AssertSilent: # new in 0.10
86
+ Enabled: true
87
+ Minitest/AssertWithExpectedArgument: # new in 0.11
88
+ Enabled: true
89
+ Minitest/AssertionInLifecycleHook: # new in 0.10
90
+ Enabled: true
91
+ Minitest/DuplicateTestRun: # new in 0.19
92
+ Enabled: true
93
+ Minitest/EmptyLineBeforeAssertionMethods: # new in 0.23
94
+ Enabled: true
95
+ Minitest/LiteralAsActualArgument: # new in 0.10
96
+ Enabled: true
97
+ Minitest/MultipleAssertions: # new in 0.10
98
+ Enabled: true
99
+ Minitest/RefuteInDelta: # new in 0.10
100
+ Enabled: true
101
+ Minitest/RefuteKindOf: # new in 0.10
102
+ Enabled: true
103
+ Minitest/RefutePathExists: # new in 0.10
104
+ Enabled: true
105
+ Minitest/SkipEnsure: # new in 0.20
106
+ Enabled: true
107
+ Minitest/SkipWithoutReason: # new in 0.24
108
+ Enabled: true
109
+ Minitest/UnreachableAssertion: # new in 0.14
110
+ Enabled: true
111
+ Minitest/UnspecifiedException: # new in 0.10
112
+ Enabled: true
113
+ Performance/AncestorsInclude: # new in 1.7
114
+ Enabled: true
115
+ Performance/BigDecimalWithNumericArgument: # new in 1.7
116
+ Enabled: true
117
+ Performance/BlockGivenWithExplicitBlock: # new in 1.9
118
+ Enabled: true
119
+ Performance/CollectionLiteralInLoop: # new in 1.8
120
+ Enabled: true
121
+ Performance/ConcurrentMonotonicTime: # new in 1.12
122
+ Enabled: true
123
+ Performance/ConstantRegexp: # new in 1.9
124
+ Enabled: true
125
+ Performance/RedundantEqualityComparisonBlock: # new in 1.10
126
+ Enabled: true
127
+ Performance/RedundantSortBlock: # new in 1.7
128
+ Enabled: true
129
+ Performance/RedundantSplitRegexpArgument: # new in 1.10
130
+ Enabled: true
131
+ Performance/RedundantStringChars: # new in 1.7
132
+ Enabled: true
133
+ Performance/ReverseFirst: # new in 1.7
134
+ Enabled: true
135
+ Performance/SortReverse: # new in 1.7
136
+ Enabled: true
137
+ Performance/Squeeze: # new in 1.7
138
+ Enabled: true
139
+ Performance/StringIdentifierArgument: # new in 1.13
140
+ Enabled: true
141
+ Performance/StringInclude: # new in 1.7
142
+ Enabled: true
143
+
144
+
145
+ # Old cops
18
146
 
19
147
  Bundler/DuplicatedGem:
20
148
  Enabled: true
data/.rubocop_todo.yml CHANGED
@@ -45,6 +45,9 @@ Minitest/RefutePredicate:
45
45
  Minitest/TestMethodName:
46
46
  Enabled: false
47
47
 
48
+ Style/ConcatArrayLiterals:
49
+ Enabled: false
50
+
48
51
  Minitest/RefuteRespondTo:
49
52
  Exclude:
50
53
  - 'test/new_relic/cli/commands/deployments_test.rb'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # New Relic Ruby Agent Release Notes
2
2
 
3
+ ## 8.15.0
4
+
5
+ Version 8.15.0 of the agent confirms compatibility with Ruby 3.2.0, adds instrumentation for concurrent-ruby, and confirms Sinatra 3 compatibility with Padrino 0.15.2. It also enables batching and compression for Infinite Tracing.
6
+
7
+ - **Add Support for Ruby 3.2.0**
8
+
9
+ Following the 3.2.0 release of Ruby, the New Relic Ruby Agent has confirmed compatibility with and now supports the official release of Ruby 3.2.0. [PR#1715](https://github.com/newrelic/newrelic-ruby-agent/pull/1715)
10
+
11
+ - **Add instrumentation for concurrent-ruby**
12
+
13
+ Instrumentation for the [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby) gem has been added to the agent for versions 1.1.5 and above. When a transaction is already in progress and a call to a `Concurrent::` method that routes through `Concurrent::ThreadPoolExecutor#post` is made, a segment will be added to the transaction. Any content within the block passed to the `Concurrent::` method that is instrumented by the agent, such as a call to `Net::HTTP.get`, will have a nested segment created. [PR#1682](https://github.com/newrelic/newrelic-ruby-agent/pull/1682)
14
+
15
+ | Configuration name | Default | Behavior |
16
+ | --------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------- |
17
+ | `instrumentation.concurrent_ruby` | auto | Controls auto-instrumentation of the concurrent-ruby library at start up. May be one of `auto`, `prepend`, `chain`, `disabled`. |
18
+
19
+ - **Infinite Tracing: Use batching and compression**
20
+
21
+ For [Infinite Tracing](https://docs.newrelic.com/docs/distributed-tracing/infinite-tracing/introduction-infinite-tracing/), which Ruby applications can leverage with the `newrelic-infinite_tracing` gem, payloads will now be batched and compressed to signficantly decrease the amount of outbound network traffic. [PR#1723](https://github.com/newrelic/newrelic-ruby-agent/pull/1723)
22
+
23
+ | Configuration name | Default | Behavior |
24
+ | --------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------- |
25
+ | `infinite_tracing.batching` | true | If true (the default), data sent to the Trace Observer will be batched instead of each span being sent individually |
26
+ | `infinite_tracing.compression_level` | high | Configure the compression level for data sent to the Trace Observer. May be one of [none|low|medium|high]. 'high' is the default. Set the level to 'none' to disable compression. |
27
+
28
+ - **Add Support for Padrino 0.15.2 and Sinatra 3**
29
+
30
+ We've added testing to confirm Padrino 0.15.2 and Sinatra 3 are compatible with the Ruby agent. Thank you [@nesquena](https://github.com/nesquena) for letting us know 0.15.2 was ready! [PR#1712](https://github.com/newrelic/newrelic-ruby-agent/pull/1712)
31
+
3
32
  ## v8.14.0
4
33
 
5
34
  Version 8.14.0 of the agent restores desired Capistrano-based changelog lookup functionality when a deployment is performed, speeds up GUID generation, delivers support for instrumenting Rails custom event notifications, fixes potential compatibility issues with the RedisClient gem, and fixes bugs related to initialization in Rails.
@@ -10,7 +39,7 @@ Version 8.14.0 of the agent restores desired Capistrano-based changelog lookup f
10
39
 
11
40
  - **Speed up GUID generation**
12
41
 
13
- The agent leverages random numbers in its GUID (globally unique identifier) generation and would previously always freshly calculate the result of 16^16 or 32^32 before generating a random number. Given that those 16^16 and 32^32 operations are expected, it makes sense to calculate their results up front and store them in constants to be referred to later. Doing so has resulted in a performance gain for the generation of GUIDs. Many thanks to [@tungmq](https://github.com/tungmq) for contributing this optimisation and the benchmarks to support it! [PR#1693[(https://github.com/newrelic/newrelic-ruby-agent/pull/1693)
42
+ The agent leverages random numbers in its GUID (globally unique identifier) generation and would previously always freshly calculate the result of 16^16 or 32^32 before generating a random number. Given that those 16^16 and 32^32 operations are expected, it makes sense to calculate their results up front and store them in constants to be referred to later. Doing so has resulted in a performance gain for the generation of GUIDs. Many thanks to [@tungmq](https://github.com/tungmq) for contributing this optimisation and the benchmarks to support it! [PR#1693](https://github.com/newrelic/newrelic-ruby-agent/pull/1693)
14
43
 
15
44
  - **Support for Rails ActiveSupport::Notifications for custom events**
16
45
 
@@ -20,15 +49,17 @@ Version 8.14.0 of the agent restores desired Capistrano-based changelog lookup f
20
49
 
21
50
  With version 8.13.0 of the agent, support was added for the [redis-rb](https://github.com/redis/redis-rb) gem v5+ and the new [RedisClient](https://rubygems.org/gems/redis-client) gem. With versions of RedisClient older than v0.11, the agent could cause the monitored application to crash when attempting to determine the Redis database index. Version 8.14.0 adds two related improvements. Firstly, support for RedisClient versions older than v0.11 has been added to get at the database index value. Secondly, the agent will no longer crash or impact the monitored application in the event that the database index cannot be obtained. Thank you very much to our community members [@mbsmartee](https://github.com/mbsmartee) and [@patatepartie](https://github.com/patatepartie) for bringing this issue to our attention, for helping us determine how to best reproduce it, and for testing out the update. We appreciate your help! [Issue#1650](https://github.com/newrelic/newrelic-ruby-agent/issues/1650) [PR#1673](https://github.com/newrelic/newrelic-ruby-agent/pull/1673)
22
51
 
23
- - **Bugfix: Defer agent startup in Rails until after application-defined initializers have run**
52
+ - ~~**Bugfix: Defer agent startup in Rails until after application-defined initializers have run**~~
53
+
54
+ ~~In Rails, the agent previously loaded before any application-defined initializers. This allowed initializers to reference the `add_method_tracer` API. However, this had the side-effect of forcing some framework libraries to load before initializers ran, preventing any configuration values related to these libraries from being applied. This fix provides an option to split initialization into two parts: load `add_method_tracer` before application-defined initializers and start the agent after application-defined initializers. This may cause other initializers to behave differently.~~
24
55
 
25
- In Rails, the agent previously loaded before any application-defined initializers. This allowed initializers to reference the `add_method_tracer` API. However, this had the side-effect of forcing some framework libraries to load before initializers ran, preventing any configuration values related to these libraries from being applied. This fix provides an option to split initialization into two parts: load `add_method_tracer` before application-defined initializers and start the agent after application-defined initializers. This may cause other initializers to behave differently.
56
+ ~~If you'd like to use this feature, set `defer_rails_initialization` to `true`. It is `false` by default, but may become `true` by default in a future release.~~
26
57
 
27
- If you'd like to use this feature, set `defer_rails_initialization` to `true`. It is `false` by default, but may become `true` by default in a future release.
58
+ ~~Furthermore, our Action View instrumentation was missing an `ActiveSupport.on_load` block around the code that loads our instrumentation.~~
28
59
 
29
- Furthermore, our Action View instrumentation was missing an `ActiveSupport.on_load` block around the code that loads our instrumentation.
60
+ ~~Thank you [@jdelStrother](https://github.com/jdelStrother) for bringing this to our attention and collaborating with us on a fix. [PR#1658](https://github.com/newrelic/newrelic-ruby-agent/pull/1658)~~
30
61
 
31
- Thank you [@jdelStrother](https://github.com/jdelStrother) for bringing this to our attention and collaborating with us on a fix. [PR#1658](https://github.com/newrelic/newrelic-ruby-agent/pull/1658)
62
+ Unfortunately, this bugfix is unreachable as written because the configuration value used to access the bugfix won't be applied until after initialization. Follow along for updates at [Issue#662](https://github.com/newrelic/newrelic-ruby-agent/issues/662).
32
63
 
33
64
  ## v8.13.1
34
65
 
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
- [![Blue banner - Community Plus: This code is currently maintained by New Relic engineering teams and delivered here in GitHub. See the README for troubleshooting and defect reporting instructions.](https://github.com/newrelic/opensource-website/raw/main/src/images/categories/Community_Plus.png)](https://opensource.newrelic.com/oss-category/#community-plus)
1
+ [![Open Source, New Relic Community Plus: This code is currently maintained by New Relic engineering teams and delivered here in GitHub. See the README for troubleshooting and defect reporting instructions.](https://github.com/newrelic/open-source-office/raw/master/examples/categories/images/Community_Plus.png)](https://opensource.newrelic.com/oss-category/#community-plus)
2
+
2
3
 
3
4
  # New Relic Ruby Agent
4
5
 
@@ -128,7 +128,7 @@ module NewRelic
128
128
 
129
129
  # apdex_f is always 4 times the apdex_t
130
130
  def apdex_f
131
- (4 * Agent.config[:apdex_t]).to_f
131
+ (Agent.config[:apdex_t] * 4).to_f
132
132
  end
133
133
 
134
134
  class WaitOnConnectTimeout < StandardError
@@ -384,7 +384,7 @@ instrumentation for. For example,
384
384
  :public => true,
385
385
  :type => String,
386
386
  :allowed_from_server => false,
387
- :description => 'Your New Relic API key. Required when using the New Relic REST API v2 to record deployments using the `newrelic deployments` command.'
387
+ :description => 'Your New Relic [user key](/docs/apis/intro-apis/new-relic-api-keys/#overview-keys). Required when using the New Relic REST API v2 to record deployments using the `newrelic deployments` command.'
388
388
  },
389
389
  :backport_fast_active_record_connection_lookup => {
390
390
  :default => false,
@@ -1452,7 +1452,7 @@ A map of error classes to a list of messages. When an error of one of the classe
1452
1452
  If `true`, disables agent middleware for Sinatra. This middleware is responsible for advanced feature support such as [cross application tracing](/docs/apm/transactions/cross-application-traces/cross-application-tracing), [page load timing](/docs/browser/new-relic-browser/getting-started/new-relic-browser), and [error collection](/docs/apm/applications-menu/events/view-apm-error-analytics).
1453
1453
 
1454
1454
  <Callout variant="important">
1455
- Cross application tracing is deprecated in favor of [distributed tracing](https://docs.newrelic.com/docs/apm/distributed-tracing/getting-started/introduction-distributed-tracing). Distributed tracing is on by default for Ruby agent versions 8.0.0 and above. Middlewares are not required to support distributed tracing.
1455
+ Cross application tracing is deprecated in favor of [distributed tracing](/docs/apm/distributed-tracing/getting-started/introduction-distributed-tracing). Distributed tracing is on by default for Ruby agent versions 8.0.0 and above. Middlewares are not required to support distributed tracing.
1456
1456
 
1457
1457
  To continue using cross application tracing, update the following options in your `newrelic.yml` configuration file:
1458
1458
 
@@ -1569,6 +1569,14 @@ If `true`, disables agent middleware for Sinatra. This middleware is responsible
1569
1569
  :allowed_from_server => false,
1570
1570
  :description => 'Controls auto-instrumentation of bunny at start up. May be one of [auto|prepend|chain|disabled].'
1571
1571
  },
1572
+ :'instrumentation.concurrent_ruby' => {
1573
+ :default => 'auto',
1574
+ :public => true,
1575
+ :type => String,
1576
+ :dynamic_name => true,
1577
+ :allowed_from_server => false,
1578
+ :description => 'Controls auto-instrumentation of the concurrent-ruby library at start up. May be one of [auto|prepend|chain|disabled].'
1579
+ },
1572
1580
  :'instrumentation.curb' => {
1573
1581
  :default => instrumentation_value_of(:disable_curb),
1574
1582
  :documentation_default => 'auto',
@@ -1802,6 +1810,13 @@ If `true`, disables agent middleware for Sinatra. This middleware is responsible
1802
1810
  :allowed_from_server => false,
1803
1811
  :description => "Controls auto-instrumentation of the Thread class at start up to automatically add tracing to all Threads created in the application."
1804
1812
  },
1813
+ :'thread_ids_enabled' => {
1814
+ :default => false,
1815
+ :public => false,
1816
+ :type => Boolean,
1817
+ :allowed_from_server => false,
1818
+ :description => "If enabled, will append the current Thread and Fiber object ids onto the segment names of segments created in Threads and concurrent-ruby"
1819
+ },
1805
1820
  :'instrumentation.tilt' => {
1806
1821
  :default => "auto",
1807
1822
  :public => true,
@@ -1853,11 +1868,12 @@ If `true`, disables agent middleware for Sinatra. This middleware is responsible
1853
1868
  # Rails
1854
1869
  :'defer_rails_initialization' => {
1855
1870
  :default => false,
1856
- :public => true,
1871
+ :public => false,
1857
1872
  :type => Boolean,
1858
1873
  :allowed_from_server => false,
1859
- :description => 'If `true`, when the agent is in an application using Ruby on Rails, it will start after ' \
1860
- 'config/initializers are run.'
1874
+ :description => 'This configuration option is currently unreachable. Please do not use. ' \
1875
+ 'If `true`, when the agent is in an application using Ruby on Rails, it will start after ' \
1876
+ 'config/initializers have run.'
1861
1877
  },
1862
1878
  # Rake
1863
1879
  :'rake.tasks' => {
@@ -1896,7 +1912,7 @@ If `true`, disables agent middleware for Sinatra. This middleware is responsible
1896
1912
  :type => Array,
1897
1913
  :allowed_from_server => true,
1898
1914
  :transform => DefaultSource.method(:convert_to_regexp_list),
1899
- :description => 'Define transactions you want the agent to ignore, by specifying a list of patterns matching the URI you want to ignore. See documentation on (ignoring specific transactions)[https://docs.newrelic.com/docs/agents/ruby-agent/api-guides/ignoring-specific-transactions/#config-ignoring] for more details.'
1915
+ :description => 'Define transactions you want the agent to ignore, by specifying a list of patterns matching the URI you want to ignore. For more detail, see [the docs on ignoring specific transactions](/docs/agents/ruby-agent/api-guides/ignoring-specific-transactions/#config-ignoring).'
1900
1916
  },
1901
1917
  # Sidekiq
1902
1918
  :'sidekiq.capture_params' => {
@@ -2315,22 +2331,22 @@ If `true`, disables agent middleware for Sinatra. This middleware is responsible
2315
2331
  :description => "URI for the New Relic data collection service."
2316
2332
  },
2317
2333
  :'infinite_tracing.batching' => {
2318
- :default => false,
2319
- :public => false,
2334
+ :default => true,
2335
+ :public => true,
2320
2336
  :type => Boolean,
2321
2337
  :allowed_from_server => false,
2322
2338
  :external => :infinite_tracing,
2323
- :description => "If true, data sent to the Trace Observer will be batched instead of the default of each " \
2339
+ :description => "If true (the default), data sent to the Trace Observer will be batched\ninstead of each " \
2324
2340
  "span being sent individually"
2325
2341
  },
2326
2342
  :'infinite_tracing.compression_level' => {
2327
- :default => :none,
2328
- :public => false,
2343
+ :default => :high,
2344
+ :public => true,
2329
2345
  :type => Symbol,
2330
2346
  :allowed_from_server => false,
2331
2347
  :external => :infinite_tracing,
2332
2348
  :description => "Configure the compression level for data sent to the Trace Observer\nMay be one of " \
2333
- "[none|low|medium|high]\nBy default, compression is not used (level = none)"
2349
+ "[none|low|medium|high]\n'high' is the default. Set the level to 'none' to disable compression"
2334
2350
  },
2335
2351
  :js_agent_file => {
2336
2352
  :default => '',
@@ -83,7 +83,7 @@ module NewRelic
83
83
  return nil if @timers.empty?
84
84
 
85
85
  timeout = @timers.values.map(&:next_fire_time).min - Process.clock_gettime(Process::CLOCK_REALTIME)
86
- timeout < 0 ? 0 : timeout
86
+ [timeout, 0].max
87
87
  end
88
88
 
89
89
  def stopped?
@@ -94,7 +94,7 @@ module NewRelic
94
94
  end
95
95
 
96
96
  def left_child_index_for(parent_index)
97
- 2 * parent_index + 1
97
+ parent_index * 2 + 1
98
98
  end
99
99
 
100
100
  def right_sibling_smaller?(lchild_index)
@@ -0,0 +1,36 @@
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 ConcurrentRuby::Chain
7
+ def self.instrument!
8
+ ::Concurrent::ThreadPoolExecutor.class_eval do
9
+ include NewRelic::Agent::Instrumentation::ConcurrentRuby
10
+
11
+ alias_method(:post_without_new_relic, :post)
12
+
13
+ def post(*args, &task)
14
+ return post_without_new_relic(*args, &task) unless NewRelic::Agent::Tracer.tracing_enabled?
15
+
16
+ traced_task = add_task_tracing(*args, &task)
17
+ post_without_new_relic(*args, &traced_task)
18
+ end
19
+ end
20
+
21
+ [::Concurrent::Promises.const_get(:'InternalStates')::Rejected,
22
+ ::Concurrent::Promises.const_get(:'InternalStates')::PartiallyRejected].each do |klass|
23
+ klass.class_eval do
24
+ alias_method(:initialize_without_new_relic, :initialize)
25
+
26
+ # Uses args.last to record the error becuase the methods that this will monkey patch
27
+ # look like: initialize(reason) & initialize(value, reason)
28
+ def initialize(*args)
29
+ NewRelic::Agent.notice_error(args.last) if args.last.is_a?(Exception)
30
+ initialize_without_new_relic(*args)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ 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 ConcurrentRuby
7
+ SEGMENT_NAME = 'Concurrent/Task'
8
+ SUPPORTABILITY_METRIC = 'Supportability/ConcurrentRuby/Invoked'
9
+
10
+ def add_task_tracing(*args, &task)
11
+ NewRelic::Agent.record_metric_once(SUPPORTABILITY_METRIC)
12
+
13
+ NewRelic::Agent::Tracer.thread_block_with_current_transaction(
14
+ *args,
15
+ segment_name: SEGMENT_NAME,
16
+ parent: NewRelic::Agent::Tracer.current_segment,
17
+ &task
18
+ )
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
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 ConcurrentRuby
7
+ module Prepend
8
+ include NewRelic::Agent::Instrumentation::ConcurrentRuby
9
+
10
+ def post(*args, &task)
11
+ return super(*args, &task) unless NewRelic::Agent::Tracer.tracing_enabled?
12
+
13
+ traced_task = add_task_tracing(*args, &task)
14
+ super(*args, &traced_task)
15
+ end
16
+ end
17
+
18
+ module ErrorPrepend
19
+ # Uses args.last to record the error because the methods that this will be prepended to
20
+ # look like: initialize(reason) & initialize(value, reason)
21
+ def initialize(*args)
22
+ NewRelic::Agent.notice_error(args.last) if args.last.is_a?(Exception)
23
+ super
24
+ end
25
+ end
26
+ end
27
+ 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_relative 'concurrent_ruby/instrumentation'
6
+ require_relative 'concurrent_ruby/chain'
7
+ require_relative 'concurrent_ruby/prepend'
8
+
9
+ DependencyDetection.defer do
10
+ named :'concurrent_ruby'
11
+
12
+ depends_on do
13
+ defined?(Concurrent) &&
14
+ Gem::Version.new(Concurrent::VERSION) >= Gem::Version.new('1.1.5')
15
+ end
16
+
17
+ executes do
18
+ NewRelic::Agent.logger.info('Installing concurrent-ruby instrumentation')
19
+
20
+ if use_prepend?
21
+ prepend_instrument(Concurrent::ThreadPoolExecutor, NewRelic::Agent::Instrumentation::ConcurrentRuby::Prepend)
22
+
23
+ [Concurrent::Promises.const_get(:'InternalStates')::Rejected,
24
+ Concurrent::Promises.const_get(:'InternalStates')::PartiallyRejected].each do |klass|
25
+ klass.prepend(NewRelic::Agent::Instrumentation::ConcurrentRuby::ErrorPrepend)
26
+ end
27
+ else
28
+ chain_instrument NewRelic::Agent::Instrumentation::ConcurrentRuby::Chain
29
+ end
30
+ end
31
+ end
@@ -340,7 +340,7 @@ module NewRelic
340
340
  #
341
341
  # Seldomly used options:
342
342
  #
343
- # * <tt>:class_name => aClass.name</tt> is used to override the name
343
+ # * <tt>:class_name => Class.name</tt> is used to override the name
344
344
  # of the class when used inside the metric name. Default is the
345
345
  # current class.
346
346
  # * <tt>:path => metric_path</tt> is *deprecated* in the public API. It
@@ -16,7 +16,11 @@ module NewRelic
16
16
  def add_thread_tracing(*args, &block)
17
17
  return block if skip_tracing?
18
18
 
19
- NewRelic::Agent::Tracer.thread_block_with_current_transaction(*args, &block)
19
+ NewRelic::Agent::Tracer.thread_block_with_current_transaction(
20
+ *args,
21
+ segment_name: 'Ruby/Thread',
22
+ &block
23
+ )
20
24
  end
21
25
 
22
26
  def skip_tracing?
@@ -141,8 +141,8 @@ module NewRelic
141
141
  start_time_in_seconds = [transaction.start_time, 0.0].max
142
142
  app_time_in_seconds = Process.clock_gettime(Process::CLOCK_REALTIME) - start_time_in_seconds
143
143
 
144
- queue_time_in_millis = (1000.0 * queue_time_in_seconds).round
145
- app_time_in_millis = (1000.0 * app_time_in_seconds).round
144
+ queue_time_in_millis = (queue_time_in_seconds * 1000.0).round
145
+ app_time_in_millis = (app_time_in_seconds * 1000.0).round
146
146
 
147
147
  transaction_name = transaction.best_name || ::NewRelic::Agent::UNKNOWN_METRIC
148
148
 
@@ -18,8 +18,8 @@ module NewRelic
18
18
  ranges.inject(0) do |memo, other|
19
19
  next memo unless intersects?(range, other)
20
20
 
21
- memo += (range.end < other.end ? range.end : other.end) -
22
- (range.begin > other.begin ? range.begin : other.begin)
21
+ memo += ([range.end, other.end].min) -
22
+ ([range.begin, other.begin].max)
23
23
  end
24
24
  end
25
25
  end
@@ -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 'fiber'
5
6
  require 'new_relic/agent/transaction'
6
7
  require 'new_relic/agent/transaction/segment'
7
8
  require 'new_relic/agent/transaction/datastore_segment'
@@ -409,15 +410,18 @@ module NewRelic
409
410
 
410
411
  alias_method :tl_clear, :clear_state
411
412
 
412
- def thread_block_with_current_transaction(*args, &block)
413
+ def thread_block_with_current_transaction(*args, segment_name:, parent: nil, &block)
413
414
  current_txn = ::Thread.current[:newrelic_tracer_state].current_transaction if ::Thread.current[:newrelic_tracer_state] && ::Thread.current[:newrelic_tracer_state].is_execution_traced?
414
415
  proc do
415
416
  begin
416
417
  if current_txn
417
418
  NewRelic::Agent::Tracer.state.current_transaction = current_txn
418
- segment = NewRelic::Agent::Tracer.start_segment(name: "Ruby/Thread/#{::Thread.current.object_id}")
419
+ segment_name += "/Thread#{::Thread.current.object_id}/Fiber#{::Fiber.current.object_id}" if NewRelic::Agent.config[:'thread_ids_enabled']
420
+ segment = NewRelic::Agent::Tracer.start_segment(name: segment_name, parent: parent)
421
+ end
422
+ NewRelic::Agent::Tracer.capture_segment_error(segment) do
423
+ yield(*args)
419
424
  end
420
- yield(*args) if block.respond_to?(:call)
421
425
  ensure
422
426
  ::NewRelic::Agent::Transaction::Segment.finish(segment)
423
427
  end
@@ -111,8 +111,8 @@ module NewRelic
111
111
  end
112
112
 
113
113
  def merge_timings(timing1, timing2)
114
- [(timing1.first < timing2.first ? timing1.first : timing2.first),
115
- (timing1.last > timing2.last ? timing1.last : timing2.last)]
114
+ [([timing1.first, timing2.first].min),
115
+ ([timing1.last, timing2.last].max)]
116
116
  end
117
117
 
118
118
  # @children_timings is an array of array, with each inner array
@@ -72,7 +72,7 @@ module NewRelic
72
72
  # A typical buffer should NOT override this method (although we do for
73
73
  # odd things like dev-mode)
74
74
  def max_capacity
75
- capacity > SINGLE_BUFFER_MAX ? SINGLE_BUFFER_MAX : capacity
75
+ [capacity, SINGLE_BUFFER_MAX].min
76
76
  end
77
77
 
78
78
  # Our default truncation strategy is to keep max_capacity
@@ -168,7 +168,7 @@ module NewRelic
168
168
  :apdex_f
169
169
  when duration <= apdex_t
170
170
  :apdex_s
171
- when duration <= 4 * apdex_t
171
+ when duration <= apdex_t * 4
172
172
  :apdex_t
173
173
  else
174
174
  :apdex_f
@@ -302,7 +302,7 @@ module NewRelic
302
302
  end
303
303
 
304
304
  def priority
305
- @priority ||= (sampled? ? 1.0 + rand : rand).round(NewRelic::PRIORITY_PRECISION)
305
+ @priority ||= (sampled? ? rand + 1.0 : rand).round(NewRelic::PRIORITY_PRECISION)
306
306
  end
307
307
 
308
308
  def referer
@@ -635,7 +635,7 @@ module NewRelic
635
635
  return unless distributed_trace_payload
636
636
 
637
637
  duration = start_time - (distributed_trace_payload.timestamp / 1000.0)
638
- duration < 0 ? 0 : duration
638
+ [duration, 0].max
639
639
  end
640
640
 
641
641
  # The summary metrics recorded by this method all end up with a duration
@@ -109,6 +109,7 @@ module NewRelic
109
109
  @logger = nil
110
110
  @tracer_lock = Mutex.new
111
111
  @tracer_queue = []
112
+ @metrics_already_recorded = Set.new
112
113
 
113
114
  # The singleton Agent instance. Used internally.
114
115
  def agent # :nodoc:
@@ -203,6 +204,12 @@ module NewRelic
203
204
  agent.stats_engine.tl_record_unscoped_metrics(metric_name, value)
204
205
  end
205
206
 
207
+ def record_metric_once(metric_name, value = 0.0)
208
+ return unless @metrics_already_recorded.add?(metric_name)
209
+
210
+ record_metric(metric_name, value)
211
+ end
212
+
206
213
  # Increment a simple counter metric.
207
214
  #
208
215
  # +metric_name+ should follow a slash separated path convention. Application
@@ -63,7 +63,7 @@ module NewRelic
63
63
  raise NewRelic::CommandRunFailedError.new("Failed to run command '#{command}': #{message}")
64
64
  end
65
65
 
66
- output.chomp
66
+ output.chomp if output
67
67
  end
68
68
 
69
69
  # TODO: Open3 defers the actual execution of a binary to Process.spawn,
@@ -29,7 +29,11 @@ module NewRelic
29
29
  def create_traced_block(*args, &block)
30
30
  return block if NewRelic::Agent.config[:'instrumentation.thread.tracing'] # if this is on, don't double trace
31
31
 
32
- NewRelic::Agent::Tracer.thread_block_with_current_transaction(*args, &block)
32
+ NewRelic::Agent::Tracer.thread_block_with_current_transaction(
33
+ *args,
34
+ segment_name: 'Ruby/TracedThread',
35
+ &block
36
+ )
33
37
  end
34
38
  end
35
39
  end
@@ -6,7 +6,7 @@
6
6
  module NewRelic
7
7
  module VERSION # :nodoc:
8
8
  MAJOR = 8
9
- MINOR = 14
9
+ MINOR = 15
10
10
  TINY = 0
11
11
 
12
12
  STRING = "#{MAJOR}.#{MINOR}.#{TINY}"
data/newrelic.yml CHANGED
@@ -162,6 +162,10 @@ common: &default_settings
162
162
  # or port_path_or_id parameters to transaction or slow SQL traces.
163
163
  # datastore_tracer.instance_reporting.enabled: true
164
164
 
165
+ # If true, when the agent is in an application using Ruby on Rails, it will start after
166
+ # config/initializers have run.
167
+ # defer_rails_initialization: false
168
+
165
169
  # If true, disables Action Cable instrumentation.
166
170
  # disable_action_cable_instrumentation: false
167
171
 
@@ -313,17 +317,21 @@ common: &default_settings
313
317
 
314
318
  # Configure the compression level for data sent to the Trace Observer
315
319
  # May be one of [none|low|medium|high]
316
- # By default, compression is not used (level = none)
317
- # infinite_tracing.compression_level: none
320
+ # 'high' is the default. Set the level to 'none' to disable compression
321
+ # infinite_tracing.compression_level: high
318
322
 
319
- # If true, data sent to the Trace Observer will be batched instead of
320
- # the default of each span being sent individually
321
- # infinite_tracing.batching: false
323
+ # If true (the default), data sent to the Trace Observer will be batched
324
+ # instead of each span being sent individually
325
+ # infinite_tracing.batching: true
322
326
 
323
327
  # Controls auto-instrumentation of bunny at start up.
324
328
  # May be one of [auto|prepend|chain|disabled].
325
329
  # instrumentation.bunny: auto
326
330
 
331
+ # Controls auto-instrumentation of concurrent_ruby at start up.
332
+ # May be one of [auto|prepend|chain|disabled]
333
+ # instrumentation.concurrent_ruby: auto
334
+
327
335
  # Controls auto-instrumentation of Curb at start up.
328
336
  # May be one of [auto|prepend|chain|disabled].
329
337
  # instrumentation.curb: auto
data/test/agent_helper.rb CHANGED
@@ -31,7 +31,7 @@ def fake_guid(length = 16)
31
31
  end
32
32
 
33
33
  def assert_between(floor, ceiling, value, message = "expected #{floor} <= #{value} <= #{ceiling}")
34
- assert((floor <= value && value <= ceiling), message) # rubocop:disable Minitest/AssertWithExpectedArgument
34
+ assert((floor <= value && value <= ceiling), message)
35
35
  end
36
36
 
37
37
  def assert_in_delta(expected, actual, delta)
@@ -236,7 +236,7 @@ def assert_metrics_recorded(expected)
236
236
  msg += "\nDid find specs: [\n#{matches.join(",\n")}\n]" unless matches.empty?
237
237
  msg += "\nAll specs in there were: #{format_metric_spec_list(all_specs)}"
238
238
 
239
- assert(actual_stats, msg) # rubocop:disable Minitest/AssertWithExpectedArgument
239
+ assert(actual_stats, msg)
240
240
  end
241
241
 
242
242
  assert_stats_has_values(actual_stats, expected_spec, expected_attrs)
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: 8.14.0
4
+ version: 8.15.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: 2022-12-14 00:00:00.000000000 Z
14
+ date: 2023-01-09 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -263,6 +263,10 @@ files:
263
263
  - lib/new_relic/agent/instrumentation/bunny/chain.rb
264
264
  - lib/new_relic/agent/instrumentation/bunny/instrumentation.rb
265
265
  - lib/new_relic/agent/instrumentation/bunny/prepend.rb
266
+ - lib/new_relic/agent/instrumentation/concurrent_ruby.rb
267
+ - lib/new_relic/agent/instrumentation/concurrent_ruby/chain.rb
268
+ - lib/new_relic/agent/instrumentation/concurrent_ruby/instrumentation.rb
269
+ - lib/new_relic/agent/instrumentation/concurrent_ruby/prepend.rb
266
270
  - lib/new_relic/agent/instrumentation/controller_instrumentation.rb
267
271
  - lib/new_relic/agent/instrumentation/curb.rb
268
272
  - lib/new_relic/agent/instrumentation/curb/chain.rb