newrelic_rpm 8.15.0 → 8.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +65 -38
- data/lib/new_relic/agent/configuration/default_source.rb +56 -17
- data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +6 -19
- data/lib/new_relic/agent/instrumentation/action_controller_other_subscriber.rb +39 -0
- data/lib/new_relic/agent/instrumentation/action_dispatch.rb +31 -0
- data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +64 -0
- data/lib/new_relic/agent/instrumentation/action_mailbox.rb +30 -0
- data/lib/new_relic/agent/instrumentation/action_mailbox_subscriber.rb +33 -0
- data/lib/new_relic/agent/instrumentation/action_mailer.rb +30 -0
- data/lib/new_relic/agent/instrumentation/action_mailer_subscriber.rb +85 -0
- data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +7 -7
- data/lib/new_relic/agent/instrumentation/active_job.rb +14 -1
- data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +41 -0
- data/lib/new_relic/agent/instrumentation/active_storage.rb +4 -0
- data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +2 -30
- data/lib/new_relic/agent/instrumentation/active_support.rb +21 -6
- data/lib/new_relic/agent/instrumentation/active_support_subscriber.rb +41 -0
- data/lib/new_relic/agent/instrumentation/custom_events.rb +12 -0
- data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +41 -0
- data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +4 -4
- data/lib/new_relic/agent/instrumentation/rails_notifications/action_controller.rb +13 -1
- data/lib/new_relic/version.rb +1 -1
- data/newrelic.yml +10 -1
- data/newrelic_rpm.gemspec +1 -0
- data/test/agent_helper.rb +1 -1
- metadata +26 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 36c4100794a9189b995fb7c649be61e3770b1e47ea5c961624c6519bea637770
|
4
|
+
data.tar.gz: bd4cf6f4a56bdad905768d3306ab26649c8ff9564619ec0b4099db63043bc1f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a97a4611de30a1d96ea4afb7b24220dd86f289761fb17cac531acbaeb09ed55be183127a78fbb7c5dac153f68305d6f8e87164be7fe0ab97ef3faf5e42ce2d5
|
7
|
+
data.tar.gz: 8a5e4c91f9c89ba0e3317984865127ad30b9746b469f67246c9da20257ed4a2851d0148f191b19288655aec642d79edbcd71d98f0cd2ebe60c7c7e95e8696336
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# New Relic Ruby Agent Release Notes
|
2
2
|
|
3
|
+
## 8.16.0
|
4
|
+
|
5
|
+
Version 8.16.0 introduces more Ruby on Rails instrumentation (especially for Rails 6 and 7) for various Action\*/Active\* libraries whose actions produce [Active Support notifications events](https://guides.rubyonrails.org/active_support_instrumentation.html).
|
6
|
+
|
7
|
+
- **Add Various Ruby on Rails Library Instrumentations**
|
8
|
+
|
9
|
+
New instrumentation is now automatically provided by several Action\*/Active\* libaries that generate Active Support notifications. With each Ruby on Rails release, new the Rails libraries add new events and sometimes existing events have their payload parameters updated as well. The New Relic Ruby agent will now automatically process more of these events and parameters with New Relic segments created for each event. At a minimum, each segment gives timing information for the event. In several cases, all non-sensitive event payload parameters are also passed along in the segment.
|
10
|
+
|
11
|
+
The agent now newly supports or has updated support for the following libraries:
|
12
|
+
|
13
|
+
- Action Cable (for WebSockets) [PR#1749](https://github.com/newrelic/newrelic-ruby-agent/pull/1749)
|
14
|
+
- Action Controller (for the 'C' in MVC) [PR#1744](https://github.com/newrelic/newrelic-ruby-agent/pull/1744/)
|
15
|
+
- Action Mailbox (for sending mail) [PR#1740](https://github.com/newrelic/newrelic-ruby-agent/pull/1740)
|
16
|
+
- Action Mailer (for routing mail) [PR#1740](https://github.com/newrelic/newrelic-ruby-agent/pull/1740)
|
17
|
+
- Active Job (for background jobs) [PR#1742](https://github.com/newrelic/newrelic-ruby-agent/pull/1761)
|
18
|
+
- Active Support (for caching operations) [PR#1742](https://github.com/newrelic/newrelic-ruby-agent/pull/1742)
|
19
|
+
|
20
|
+
The instrumentations for each of these libaries are all enabled by default, but can be independently disabled via configuration by using the following parameters:
|
21
|
+
|
22
|
+
| Configuration name | Default | Behavior |
|
23
|
+
| --------------------------- | ------- | ------------------------------------------------------ |
|
24
|
+
| `disable_action_cable` | `false` | If `true`, disables Action Cable instrumentation. |
|
25
|
+
| `disable_action_controller` | `false` | If `true`, disables Action Controller instrumentation. |
|
26
|
+
| `disable_action_mailbox` | `false` | If `true`, disables Action Mailbox instrumentation. |
|
27
|
+
| `disable_action_mailer` | `false` | If `true`, disables Action Mailer instrumentation. |
|
28
|
+
| `disable_activejob` | `false` | If `true`, disables Active Job instrumentation. |
|
29
|
+
| `disable_active_support` | `false` | If `true`, disables Active Support instrumentation. |
|
30
|
+
|
3
31
|
## 8.15.0
|
4
32
|
|
5
33
|
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.
|
@@ -12,18 +40,18 @@ Version 8.15.0 of the agent confirms compatibility with Ruby 3.2.0, adds instrum
|
|
12
40
|
|
13
41
|
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
42
|
|
15
|
-
| Configuration name | Default | Behavior
|
16
|
-
| --------------------------------- | ------- |
|
43
|
+
| Configuration name | Default | Behavior |
|
44
|
+
| --------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
17
45
|
| `instrumentation.concurrent_ruby` | auto | Controls auto-instrumentation of the concurrent-ruby library at start up. May be one of `auto`, `prepend`, `chain`, `disabled`. |
|
18
46
|
|
19
47
|
- **Infinite Tracing: Use batching and compression**
|
20
48
|
|
21
49
|
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
50
|
|
23
|
-
| Configuration name
|
24
|
-
|
|
25
|
-
| `infinite_tracing.batching`
|
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. |
|
51
|
+
| Configuration name | Default | Behavior |
|
52
|
+
| ------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------- | --- | ------ | ----------------------------------------------------------------------------- |
|
53
|
+
| `infinite_tracing.batching` | true | If true (the default), data sent to the Trace Observer will be batched instead of each span being sent individually |
|
54
|
+
| `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
55
|
|
28
56
|
- **Add Support for Padrino 0.15.2 and Sinatra 3**
|
29
57
|
|
@@ -294,36 +322,35 @@ Version 8.11.0 of the agent updates the `newrelic deployments` command to work w
|
|
294
322
|
|
295
323
|
- **Deprecate instrumentation versions with low adoption and/or versions over five years old**
|
296
324
|
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
For the gems with deprecated versions, we will no longer test those versions in our multiverse suite. They may, however, still be compatible with the agent. We will no longer fix bug reports for issues related to these gem versions.
|
325
|
+
This release deprecates the following instrumentation:
|
326
|
+
| Deprecated | Replacement |
|
327
|
+
| ----------- | ----------- |
|
328
|
+
| ActiveMerchant < 1.65.0 | ActiveMerchant >= 1.65.0 |
|
329
|
+
| Acts As Solr (all versions) | none |
|
330
|
+
| Authlogic (all versions) | none |
|
331
|
+
| Bunny < 2.7.0 | bunny >= 2.7.0 |
|
332
|
+
| Dalli < 3.2.1 | Dalli >= 3.2.1 |
|
333
|
+
| DataMapper (all versions) | none |
|
334
|
+
| Delayed Job < 4.1.0 | Delayed Job >= 4.1.0 |
|
335
|
+
| Excon < 0.56.0 | Excon >= 0.56.0 |
|
336
|
+
| Grape < 0.19.2 | Grape >= 0.19.2 |
|
337
|
+
| HTTPClient < 2.8.3 | HTTPClient 2.8.3 |
|
338
|
+
| HTTP.rb < 2.2.2 | HTTP.rb >= 2.2.2 |
|
339
|
+
| Mongo < 2.4.1 | Mongo >= 2.4.1 |
|
340
|
+
| Padrino < 0.15.0 | Padrino >= 0.15.0 |
|
341
|
+
| Passenger < 5.1.3 | Passenger >= 5.1.3 |
|
342
|
+
| Puma < 3.9.0 | Puma >= 3.9.0 |
|
343
|
+
| Rack < 1.6.8 | Rack >= 1.6.8 |
|
344
|
+
| Rails 3.2.x | Rails >= 4.x |
|
345
|
+
| Rainbows (all versions) | none |
|
346
|
+
| Sequel < 4.45.0 | Sequel >= 4.45.0 |
|
347
|
+
| Sidekiq < 5.0.0 | Sidekiq >= 5.0.0 |
|
348
|
+
| Sinatra < 2.0.0 | Sinatra >= 2.0.0 |
|
349
|
+
| Sunspot (all versions) | none |
|
350
|
+
| Typhoeus < 1.3.0 | Typhoeus >= 1.3.0 |
|
351
|
+
| Unicorn < 5.3.0 | Unicorn >= 5.3.0 |
|
352
|
+
|
353
|
+
For the gems with deprecated versions, we will no longer test those versions in our multiverse suite. They may, however, still be compatible with the agent. We will no longer fix bug reports for issues related to these gem versions.
|
327
354
|
|
328
355
|
- **Clarify documentation for `rake.tasks` configuration**
|
329
356
|
|
@@ -3157,7 +3184,7 @@ reported to New Relic. The second ignores only the Apdex metric for a single
|
|
3157
3184
|
transaction. The third disables javascript injection for browser monitoring
|
3158
3185
|
for the current transaction.
|
3159
3186
|
|
3160
|
-
These methods differ from the existing newrelic*ignore
|
3187
|
+
These methods differ from the existing newrelic*ignore\*\* method in that they
|
3161
3188
|
may be called *during\* a transaction based on some dynamic runtime criteria,
|
3162
3189
|
as opposed to at the class level on startup.
|
3163
3190
|
|
@@ -3254,7 +3281,7 @@ traces from in the Transaction Trace drill-down.
|
|
3254
3281
|
- High security mode V2
|
3255
3282
|
|
3256
3283
|
The Ruby agent now supports V2 of New Relic's high security mode. To enable
|
3257
|
-
it, you must add '
|
3284
|
+
it, you must add 'high\_security: true' to your newrelic.yml file, _and_ enable
|
3258
3285
|
high security mode through the New Relic web interface. The local agent
|
3259
3286
|
setting must be in agreement with the server-side setting, or the agent will
|
3260
3287
|
shut down and no data will be collected.
|
@@ -364,9 +364,8 @@ module NewRelic
|
|
364
364
|
:type => Array,
|
365
365
|
:allowed_from_server => false,
|
366
366
|
:description => <<-DESCRIPTION
|
367
|
-
An array of ActiveSupport custom
|
368
|
-
|
369
|
-
- my.custom.event
|
367
|
+
An array of ActiveSupport custom event names to subscribe to and instrument. For example,
|
368
|
+
- one.custom.event
|
370
369
|
- another.event
|
371
370
|
- a.third.event
|
372
371
|
DESCRIPTION
|
@@ -466,7 +465,7 @@ When `true`, the agent captures HTTP request parameters and attaches them to tra
|
|
466
465
|
:public => true,
|
467
466
|
:type => String,
|
468
467
|
:allowed_from_server => false,
|
469
|
-
:description => 'A dictionary of [label names](/docs/data-analysis/user-interface-functions/labels-categories-organize-your-apps-servers) and values that will be applied to the data sent from this agent. May also be expressed as a semicolon-delimited `;` string of colon-separated `:` pairs. For example,
|
468
|
+
:description => 'A dictionary of [label names](/docs/data-analysis/user-interface-functions/labels-categories-organize-your-apps-servers) and values that will be applied to the data sent from this agent. May also be expressed as a semicolon-delimited `;` string of colon-separated `:` pairs. For example, `Server:One;Data Center:Primary`.'
|
470
469
|
},
|
471
470
|
:log_file_name => {
|
472
471
|
:default => 'newrelic_agent.log',
|
@@ -1138,25 +1137,65 @@ A map of error classes to a list of messages. When an error of one of the classe
|
|
1138
1137
|
:default => false,
|
1139
1138
|
:public => true,
|
1140
1139
|
:type => Boolean,
|
1141
|
-
:dynamic_name => true,
|
1142
1140
|
:allowed_from_server => false,
|
1143
1141
|
:description => 'If `true`, disables Action Cable instrumentation.'
|
1144
1142
|
},
|
1143
|
+
# TODO: by subscribing to process_middleware.action_dispatch events,
|
1144
|
+
# we duplicate the efforts already performed by non-notifications
|
1145
|
+
# based instrumentation. In future, we ought to determine the
|
1146
|
+
# extent of the overlap and duplication and end up with only this
|
1147
|
+
# notifications based approach existing and the monkey patching
|
1148
|
+
# approach removed entirely. NOTE that we will likely not want to
|
1149
|
+
# do so until we are okay with dropping support for Rails < v6,
|
1150
|
+
# given that these events are available only for v6+.
|
1151
|
+
:disable_action_dispatch => {
|
1152
|
+
:default => true,
|
1153
|
+
:public => false,
|
1154
|
+
:type => Boolean,
|
1155
|
+
:allowed_from_server => false,
|
1156
|
+
:description => 'If `true`, disables Action Dispatch instrumentation.'
|
1157
|
+
},
|
1158
|
+
:disable_action_controller => {
|
1159
|
+
:default => false,
|
1160
|
+
:public => true,
|
1161
|
+
:type => Boolean,
|
1162
|
+
:allowed_from_server => false,
|
1163
|
+
:description => 'If `true`, disables Action Controller instrumentation.'
|
1164
|
+
},
|
1165
|
+
:disable_action_mailbox => {
|
1166
|
+
:default => false,
|
1167
|
+
:public => true,
|
1168
|
+
:type => Boolean,
|
1169
|
+
:allowed_from_server => false,
|
1170
|
+
:description => 'If `true`, disables Action Mailbox instrumentation.'
|
1171
|
+
},
|
1172
|
+
:disable_action_mailer => {
|
1173
|
+
:default => false,
|
1174
|
+
:public => true,
|
1175
|
+
:type => Boolean,
|
1176
|
+
:allowed_from_server => false,
|
1177
|
+
:description => 'If `true`, disables Action Mailer instrumentation.'
|
1178
|
+
},
|
1145
1179
|
:disable_activejob => {
|
1146
1180
|
:default => false,
|
1147
1181
|
:public => true,
|
1148
1182
|
:type => Boolean,
|
1149
|
-
:dynamic_name => true,
|
1150
1183
|
:allowed_from_server => false,
|
1151
|
-
:description => 'If `true`, disables
|
1184
|
+
:description => 'If `true`, disables Active Job instrumentation.'
|
1152
1185
|
},
|
1153
1186
|
:disable_active_storage => {
|
1154
1187
|
:default => false,
|
1155
1188
|
:public => true,
|
1156
1189
|
:type => Boolean,
|
1157
|
-
:dynamic_name => true,
|
1158
1190
|
:allowed_from_server => false,
|
1159
|
-
:description => 'If `true`, disables
|
1191
|
+
:description => 'If `true`, disables Active Storage instrumentation.'
|
1192
|
+
},
|
1193
|
+
:disable_active_support => {
|
1194
|
+
:default => false,
|
1195
|
+
:public => true,
|
1196
|
+
:type => Boolean,
|
1197
|
+
:allowed_from_server => false,
|
1198
|
+
:description => 'If `true`, disables Active Support instrumentation.'
|
1160
1199
|
},
|
1161
1200
|
:disable_activerecord_instrumentation => {
|
1162
1201
|
:default => value_of(:skip_ar_instrumentation),
|
@@ -1164,7 +1203,7 @@ A map of error classes to a list of messages. When an error of one of the classe
|
|
1164
1203
|
:public => true,
|
1165
1204
|
:type => Boolean,
|
1166
1205
|
:allowed_from_server => false,
|
1167
|
-
:description => 'If `true`, disables
|
1206
|
+
:description => 'If `true`, disables Active Record instrumentation.'
|
1168
1207
|
},
|
1169
1208
|
:disable_active_record_notifications => {
|
1170
1209
|
:default => false,
|
@@ -1172,7 +1211,7 @@ A map of error classes to a list of messages. When an error of one of the classe
|
|
1172
1211
|
:type => Boolean,
|
1173
1212
|
:dynamic_name => true,
|
1174
1213
|
:allowed_from_server => false,
|
1175
|
-
:description => 'If `true`, disables instrumentation for
|
1214
|
+
:description => 'If `true`, disables instrumentation for Active Record 4+'
|
1176
1215
|
},
|
1177
1216
|
:disable_bunny => {
|
1178
1217
|
:default => false,
|
@@ -1537,9 +1576,9 @@ If `true`, disables agent middleware for Sinatra. This middleware is responsible
|
|
1537
1576
|
:type => String,
|
1538
1577
|
:allowed_from_server => false,
|
1539
1578
|
:external => :infinite_tracing,
|
1540
|
-
:description => "Configures the hostname for the
|
1579
|
+
:description => "Configures the hostname for the trace observer Host. " \
|
1541
1580
|
"When configured, enables tail-based sampling by sending all recorded spans " \
|
1542
|
-
"to a
|
1581
|
+
"to a trace observer for further sampling decisions, irrespective of any usual " \
|
1543
1582
|
"agent sampling decision."
|
1544
1583
|
},
|
1545
1584
|
:'infinite_tracing.trace_observer.port' => {
|
@@ -1548,7 +1587,7 @@ If `true`, disables agent middleware for Sinatra. This middleware is responsible
|
|
1548
1587
|
:type => Integer,
|
1549
1588
|
:allowed_from_server => false,
|
1550
1589
|
:external => :infinite_tracing,
|
1551
|
-
:description => "Configures the TCP/IP port for the
|
1590
|
+
:description => "Configures the TCP/IP port for the trace observer Host"
|
1552
1591
|
},
|
1553
1592
|
# Instrumentation
|
1554
1593
|
:'instrumentation.active_support_logger' => {
|
@@ -2336,8 +2375,8 @@ If `true`, disables agent middleware for Sinatra. This middleware is responsible
|
|
2336
2375
|
:type => Boolean,
|
2337
2376
|
:allowed_from_server => false,
|
2338
2377
|
:external => :infinite_tracing,
|
2339
|
-
:description => "If true (the default), data sent to the
|
2340
|
-
"span
|
2378
|
+
:description => "If `true` (the default), data sent to the trace observer is batched\ninstead of sending " \
|
2379
|
+
"each span individually."
|
2341
2380
|
},
|
2342
2381
|
:'infinite_tracing.compression_level' => {
|
2343
2382
|
:default => :high,
|
@@ -2345,7 +2384,7 @@ If `true`, disables agent middleware for Sinatra. This middleware is responsible
|
|
2345
2384
|
:type => Symbol,
|
2346
2385
|
:allowed_from_server => false,
|
2347
2386
|
:external => :infinite_tracing,
|
2348
|
-
:description => "Configure the compression level for data sent to the
|
2387
|
+
:description => "Configure the compression level for data sent to the trace observer\nMay be one of " \
|
2349
2388
|
"[none|low|medium|high]\n'high' is the default. Set the level to 'none' to disable compression"
|
2350
2389
|
},
|
2351
2390
|
:js_agent_file => {
|
@@ -10,9 +10,7 @@ module NewRelic
|
|
10
10
|
class ActionCableSubscriber < NotificationsSubscriber
|
11
11
|
PERFORM_ACTION = 'perform_action.action_cable'.freeze
|
12
12
|
|
13
|
-
def
|
14
|
-
return unless state.is_execution_traced?
|
15
|
-
|
13
|
+
def start_segment(name, id, payload) # THREAD_LOCAL_ACCESS
|
16
14
|
finishable = if name == PERFORM_ACTION
|
17
15
|
Tracer.start_transaction_or_segment(
|
18
16
|
name: transaction_name_from_payload(payload),
|
@@ -22,21 +20,6 @@ module NewRelic
|
|
22
20
|
Tracer.start_segment(name: metric_name_from_payload(name, payload))
|
23
21
|
end
|
24
22
|
push_segment(id, finishable)
|
25
|
-
rescue => e
|
26
|
-
log_notification_error(e, name, 'start')
|
27
|
-
end
|
28
|
-
|
29
|
-
def finish(name, id, payload) # THREAD_LOCAL_ACCESS
|
30
|
-
return unless state.is_execution_traced?
|
31
|
-
|
32
|
-
if exception = exception_object(payload)
|
33
|
-
NewRelic::Agent.notice_error(exception)
|
34
|
-
end
|
35
|
-
|
36
|
-
finishable = pop_segment(id)
|
37
|
-
finishable.finish if finishable
|
38
|
-
rescue => e
|
39
|
-
log_notification_error(e, name, 'finish')
|
40
23
|
end
|
41
24
|
|
42
25
|
private
|
@@ -46,7 +29,11 @@ module NewRelic
|
|
46
29
|
end
|
47
30
|
|
48
31
|
def metric_name_from_payload(name, payload)
|
49
|
-
"Ruby/ActionCable/#{payload
|
32
|
+
"Ruby/ActionCable/#{metric_name(payload)}/#{action_name(name)}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def metric_name(payload)
|
36
|
+
payload[:broadcasting] || payload[:channel_class]
|
50
37
|
end
|
51
38
|
|
52
39
|
DOT_ACTION_CABLE = '.action_cable'.freeze
|
@@ -0,0 +1,39 @@
|
|
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 'new_relic/agent/instrumentation/notifications_subscriber'
|
6
|
+
require 'new_relic/agent/instrumentation/ignore_actions'
|
7
|
+
require 'new_relic/agent/parameter_filtering'
|
8
|
+
|
9
|
+
module NewRelic
|
10
|
+
module Agent
|
11
|
+
module Instrumentation
|
12
|
+
class ActionControllerOtherSubscriber < NotificationsSubscriber
|
13
|
+
def add_segment_params(segment, payload)
|
14
|
+
segment.params[:filter] = payload[:filter] if payload[:filter]
|
15
|
+
segment.params[:keys] = payload[:keys] if payload[:keys]
|
16
|
+
segment.params[:original_path] = payload[:request].original_fullpath if payload[:request]
|
17
|
+
|
18
|
+
if payload[:context]
|
19
|
+
segment.params[:action] = payload[:context][:action]
|
20
|
+
segment.params[:controller] = payload[:context][:controller]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def metric_name(name, payload)
|
25
|
+
controller_name = controller_name_for_metric(payload)
|
26
|
+
"Ruby/ActionController#{"/#{controller_name}" if controller_name}/#{name.gsub(/\.action_controller/, '')}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def controller_name_for_metric(payload)
|
30
|
+
# redirect_to
|
31
|
+
return payload[:request].controller_class.controller_path if payload[:request] && payload[:request].controller_class
|
32
|
+
|
33
|
+
# unpermitted_parameters
|
34
|
+
::NewRelic::LanguageSupport.constantize(payload[:context][:controller]).controller_path if payload[:context] && payload[:context][:controller]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
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 'new_relic/agent/instrumentation/action_dispatch_subscriber'
|
6
|
+
|
7
|
+
DependencyDetection.defer do
|
8
|
+
named :action_dispatch
|
9
|
+
|
10
|
+
depends_on do
|
11
|
+
!NewRelic::Agent.config[:disable_action_dispatch]
|
12
|
+
end
|
13
|
+
|
14
|
+
depends_on do
|
15
|
+
defined?(ActiveSupport) &&
|
16
|
+
defined?(ActionDispatch) &&
|
17
|
+
defined?(ActionPack) &&
|
18
|
+
ActionPack.respond_to?(:gem_version) &&
|
19
|
+
ActionPack.gem_version >= Gem::Version.new('6.0.0') && # notifications for dispatch added in Rails 6
|
20
|
+
!NewRelic::Agent::Instrumentation::ActionDispatchSubscriber.subscribed?
|
21
|
+
end
|
22
|
+
|
23
|
+
executes do
|
24
|
+
NewRelic::Agent.logger.info('Installing ActionDispatch instrumentation')
|
25
|
+
end
|
26
|
+
|
27
|
+
executes do
|
28
|
+
ActiveSupport::Notifications.subscribe(/\A[^\.]+\.action_dispatch\z/,
|
29
|
+
NewRelic::Agent::Instrumentation::ActionDispatchSubscriber.new)
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,64 @@
|
|
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 'new_relic/agent/instrumentation/notifications_subscriber'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
module Instrumentation
|
10
|
+
class ActionDispatchSubscriber < NotificationsSubscriber
|
11
|
+
def start(name, id, payload)
|
12
|
+
return unless state.is_execution_traced?
|
13
|
+
|
14
|
+
start_segment(name, id, payload)
|
15
|
+
rescue => e
|
16
|
+
log_notification_error(e, name, 'start')
|
17
|
+
end
|
18
|
+
|
19
|
+
def finish(name, id, payload)
|
20
|
+
return unless state.is_execution_traced?
|
21
|
+
|
22
|
+
finish_segment(id, payload)
|
23
|
+
rescue => e
|
24
|
+
log_notification_error(e, name, 'finish')
|
25
|
+
end
|
26
|
+
|
27
|
+
def start_segment(name, id, payload)
|
28
|
+
segment = Tracer.start_segment(name: metric_name(name, payload))
|
29
|
+
push_segment(id, segment)
|
30
|
+
end
|
31
|
+
|
32
|
+
def finish_segment(id, payload)
|
33
|
+
if segment = pop_segment(id)
|
34
|
+
if exception = exception_object(payload)
|
35
|
+
segment.notice_error(exception)
|
36
|
+
end
|
37
|
+
segment.finish
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def metric_name(name, payload)
|
42
|
+
middleware = payload[:middleware]
|
43
|
+
method = method_from_name(name)
|
44
|
+
"Ruby/ActionDispatch/#{middleware}/#{method}"
|
45
|
+
end
|
46
|
+
|
47
|
+
PATTERN = /\A([^\.]+)\.action_dispatch\z/
|
48
|
+
UNKNOWN = 'unknown'.freeze
|
49
|
+
|
50
|
+
METHOD_NAME_MAPPING = Hash.new do |h, k|
|
51
|
+
if PATTERN =~ k
|
52
|
+
h[k] = $1
|
53
|
+
else
|
54
|
+
h[k] = UNKNOWN
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def method_from_name(name)
|
59
|
+
METHOD_NAME_MAPPING[name]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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 'new_relic/agent/instrumentation/action_mailbox_subscriber'
|
6
|
+
|
7
|
+
DependencyDetection.defer do
|
8
|
+
named :action_mailbox
|
9
|
+
|
10
|
+
depends_on do
|
11
|
+
!NewRelic::Agent.config[:disable_action_mailbox]
|
12
|
+
end
|
13
|
+
|
14
|
+
depends_on do
|
15
|
+
defined?(ActiveSupport) &&
|
16
|
+
defined?(ActionMailbox) &&
|
17
|
+
ActionMailbox.respond_to?(:gem_version) && # 'require "action_mailbox"' doesn't require version...
|
18
|
+
ActionMailbox.gem_version >= Gem::Version.new('7.1.0.alpha') && # notifications added in Rails 7.1
|
19
|
+
!NewRelic::Agent::Instrumentation::ActionMailboxSubscriber.subscribed?
|
20
|
+
end
|
21
|
+
|
22
|
+
executes do
|
23
|
+
NewRelic::Agent.logger.info('Installing ActionMailbox instrumentation')
|
24
|
+
end
|
25
|
+
|
26
|
+
executes do
|
27
|
+
ActiveSupport::Notifications.subscribe(/\A[^\.]+\.action_mailbox\z/,
|
28
|
+
NewRelic::Agent::Instrumentation::ActionMailboxSubscriber.new)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
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 'new_relic/agent/instrumentation/notifications_subscriber'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
module Instrumentation
|
10
|
+
class ActionMailboxSubscriber < NotificationsSubscriber
|
11
|
+
def metric_name(name, payload)
|
12
|
+
mailbox = payload[:mailbox].class.name
|
13
|
+
method = method_from_name(name)
|
14
|
+
"Ruby/ActionMailbox/#{mailbox}/#{method}"
|
15
|
+
end
|
16
|
+
|
17
|
+
PATTERN = /\A([^\.]*)\.action_mailbox\z/
|
18
|
+
|
19
|
+
METHOD_NAME_MAPPING = Hash.new do |h, k|
|
20
|
+
if PATTERN =~ k
|
21
|
+
h[k] = $1
|
22
|
+
else
|
23
|
+
h[k] = NewRelic::UNKNOWN
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def method_from_name(name)
|
28
|
+
METHOD_NAME_MAPPING[name]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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 'new_relic/agent/instrumentation/action_mailer_subscriber'
|
6
|
+
|
7
|
+
DependencyDetection.defer do
|
8
|
+
named :action_mailer
|
9
|
+
|
10
|
+
depends_on do
|
11
|
+
!NewRelic::Agent.config[:disable_action_mailer]
|
12
|
+
end
|
13
|
+
|
14
|
+
depends_on do
|
15
|
+
defined?(ActiveSupport) &&
|
16
|
+
defined?(ActionMailer) &&
|
17
|
+
ActionMailer.respond_to?(:gem_version) &&
|
18
|
+
ActionMailer.gem_version >= Gem::Version.new('5.0') &&
|
19
|
+
!NewRelic::Agent::Instrumentation::ActionMailerSubscriber.subscribed?
|
20
|
+
end
|
21
|
+
|
22
|
+
executes do
|
23
|
+
NewRelic::Agent.logger.info('Installing ActionMailer instrumentation')
|
24
|
+
end
|
25
|
+
|
26
|
+
executes do
|
27
|
+
ActiveSupport::Notifications.subscribe(/\A(?:[^\.]+)\.action_mailer\z/,
|
28
|
+
NewRelic::Agent::Instrumentation::ActionMailerSubscriber.new)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,85 @@
|
|
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 'new_relic/agent/instrumentation/notifications_subscriber'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
module Instrumentation
|
10
|
+
# NOTE: as of v7.1.0.0.alpha, deliver.action_mailer will provide
|
11
|
+
# an empty payload hash ({}) to #start, so in this subscriber class
|
12
|
+
# we defer params population until #finish and start the segment with
|
13
|
+
# a temporary name that is later replaced
|
14
|
+
class ActionMailerSubscriber < NotificationsSubscriber
|
15
|
+
BASE_NAME = 'Ruby/ActionMailer'
|
16
|
+
PAYLOAD_KEYS = %i[action data key mailer message_id perform_deliveries subject]
|
17
|
+
PATTERN = /\A([^\.]+)\.action_mailer\z/
|
18
|
+
UNKNOWN_MAILER = %r{^#{BASE_NAME}/#{UNKNOWN}/}
|
19
|
+
|
20
|
+
METHOD_NAME_MAPPING = Hash.new do |h, k|
|
21
|
+
if PATTERN =~ k
|
22
|
+
h[k] = $1
|
23
|
+
else
|
24
|
+
h[k] = NewRelic::UNKNOWN
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def start(name, id, payload)
|
29
|
+
return unless state.is_execution_traced?
|
30
|
+
|
31
|
+
start_segment(name, id, payload)
|
32
|
+
rescue => e
|
33
|
+
log_notification_error(e, name, 'start')
|
34
|
+
end
|
35
|
+
|
36
|
+
def finish(name, id, payload)
|
37
|
+
return unless state.is_execution_traced?
|
38
|
+
|
39
|
+
finish_segment(id, payload)
|
40
|
+
rescue => e
|
41
|
+
log_notification_error(e, name, 'finish')
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def start_segment(name, id, payload)
|
47
|
+
segment = Tracer.start_segment(name: metric_name(name, payload))
|
48
|
+
push_segment(id, segment)
|
49
|
+
end
|
50
|
+
|
51
|
+
def finish_segment(id, payload)
|
52
|
+
segment = pop_segment(id)
|
53
|
+
return unless segment
|
54
|
+
|
55
|
+
if segment.name.match?(UNKNOWN_MAILER) && payload.key?(:mailer)
|
56
|
+
segment.name = segment.name.sub(UNKNOWN_MAILER, "#{BASE_NAME}/#{payload[:mailer]}/")
|
57
|
+
end
|
58
|
+
|
59
|
+
PAYLOAD_KEYS.each do |key|
|
60
|
+
segment.params[key] = payload[key] if payload.key?(key)
|
61
|
+
end
|
62
|
+
|
63
|
+
notice_exception(segment, payload)
|
64
|
+
segment.finish
|
65
|
+
end
|
66
|
+
|
67
|
+
def notice_exception(segment, payload)
|
68
|
+
if exception = exception_object(payload)
|
69
|
+
segment.notice_error(exception)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def metric_name(name, payload)
|
74
|
+
mailer = payload[:mailer] || UNKNOWN
|
75
|
+
method = method_from_name(name)
|
76
|
+
"#{BASE_NAME}/#{mailer}/#{method}"
|
77
|
+
end
|
78
|
+
|
79
|
+
def method_from_name(name)
|
80
|
+
METHOD_NAME_MAPPING[name]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -10,28 +10,25 @@ module NewRelic
|
|
10
10
|
module Agent
|
11
11
|
module Instrumentation
|
12
12
|
class ActionViewSubscriber < NotificationsSubscriber
|
13
|
-
def
|
13
|
+
def start_segment(name, id, payload)
|
14
14
|
parent = segment_stack[id].last
|
15
15
|
metric_name = format_metric_name(name, payload, parent)
|
16
16
|
|
17
17
|
event = ActionViewEvent.new(metric_name, payload[:identifier])
|
18
|
-
|
18
|
+
|
19
|
+
if recordable?(name, metric_name)
|
19
20
|
event.finishable = Tracer.start_segment(name: metric_name)
|
20
21
|
end
|
21
22
|
push_segment(id, event)
|
22
|
-
rescue => e
|
23
|
-
log_notification_error(e, name, 'start')
|
24
23
|
end
|
25
24
|
|
26
|
-
def
|
25
|
+
def finish_segment(id, payload)
|
27
26
|
if segment = pop_segment(id)
|
28
27
|
if exception = exception_object(payload)
|
29
28
|
segment.notice_error(exception)
|
30
29
|
end
|
31
30
|
segment.finish
|
32
31
|
end
|
33
|
-
rescue => e
|
34
|
-
log_notification_error(e, name, 'finish')
|
35
32
|
end
|
36
33
|
|
37
34
|
def format_metric_name(event_name, payload, parent)
|
@@ -61,12 +58,15 @@ module NewRelic
|
|
61
58
|
RENDER_TEMPLATE_EVENT_NAME = 'render_template.action_view'.freeze
|
62
59
|
RENDER_PARTIAL_EVENT_NAME = 'render_partial.action_view'.freeze
|
63
60
|
RENDER_COLLECTION_EVENT_NAME = 'render_collection.action_view'.freeze
|
61
|
+
RENDER_LAYOUT_EVENT_NAME = 'render_layout.action_view'.freeze
|
64
62
|
|
65
63
|
def metric_action(name)
|
66
64
|
case name
|
67
65
|
when /#{RENDER_TEMPLATE_EVENT_NAME}$/o then 'Rendering'
|
68
66
|
when RENDER_PARTIAL_EVENT_NAME then 'Partial'
|
69
67
|
when RENDER_COLLECTION_EVENT_NAME then 'Partial'
|
68
|
+
when RENDER_LAYOUT_EVENT_NAME then 'Layout'
|
69
|
+
else NewRelic::UNKNOWN
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -12,7 +12,7 @@ DependencyDetection.defer do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
executes do
|
15
|
-
NewRelic::Agent.logger.info('Installing ActiveJob instrumentation')
|
15
|
+
NewRelic::Agent.logger.info('Installing base ActiveJob instrumentation')
|
16
16
|
|
17
17
|
ActiveSupport.on_load(:active_job) do
|
18
18
|
ActiveJob::Base.around_enqueue do |job, block|
|
@@ -26,6 +26,19 @@ DependencyDetection.defer do
|
|
26
26
|
NewRelic::Agent::PrependSupportability.record_metrics_for(ActiveJob::Base)
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
executes do
|
31
|
+
if defined?(ActiveSupport) &&
|
32
|
+
ActiveJob.respond_to?(:gem_version) &&
|
33
|
+
ActiveJob.gem_version >= Gem::Version.new('6.0.0') &&
|
34
|
+
!NewRelic::Agent.config[:disable_activejob] &&
|
35
|
+
!NewRelic::Agent::Instrumentation::ActiveJobSubscriber.subscribed?
|
36
|
+
NewRelic::Agent.logger.info('Installing notifications based ActiveJob instrumentation')
|
37
|
+
|
38
|
+
ActiveSupport::Notifications.subscribe(/\A[^\.]+\.active_job\z/,
|
39
|
+
NewRelic::Agent::Instrumentation::ActiveJobSubscriber.new)
|
40
|
+
end
|
41
|
+
end
|
29
42
|
end
|
30
43
|
|
31
44
|
module NewRelic
|
@@ -0,0 +1,41 @@
|
|
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 'new_relic/agent/instrumentation/notifications_subscriber'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
module Instrumentation
|
10
|
+
class ActiveJobSubscriber < NotificationsSubscriber
|
11
|
+
PAYLOAD_KEYS = %i[adapter db_runtime error job wait]
|
12
|
+
|
13
|
+
def add_segment_params(segment, payload)
|
14
|
+
PAYLOAD_KEYS.each do |key|
|
15
|
+
segment.params[key] = payload[key] if payload.key?(key)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def metric_name(name, payload)
|
20
|
+
queue = payload[:job].queue_name
|
21
|
+
method = method_from_name(name)
|
22
|
+
"Ruby/ActiveJob/#{queue}/#{method}"
|
23
|
+
end
|
24
|
+
|
25
|
+
PATTERN = /\A([^\.]+)\.active_job\z/
|
26
|
+
|
27
|
+
METHOD_NAME_MAPPING = Hash.new do |h, k|
|
28
|
+
if PATTERN =~ k
|
29
|
+
h[k] = $1
|
30
|
+
else
|
31
|
+
h[k] = NewRelic::UNKNOWN
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_from_name(name)
|
36
|
+
METHOD_NAME_MAPPING[name]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -7,6 +7,10 @@ require 'new_relic/agent/instrumentation/active_storage_subscriber'
|
|
7
7
|
DependencyDetection.defer do
|
8
8
|
named :active_storage
|
9
9
|
|
10
|
+
depends_on do
|
11
|
+
!NewRelic::Agent.config[:disable_active_storage]
|
12
|
+
end
|
13
|
+
|
10
14
|
depends_on do
|
11
15
|
defined?(ActiveStorage) &&
|
12
16
|
!NewRelic::Agent::Instrumentation::ActiveStorageSubscriber.subscribed?
|
@@ -8,36 +8,9 @@ module NewRelic
|
|
8
8
|
module Agent
|
9
9
|
module Instrumentation
|
10
10
|
class ActiveStorageSubscriber < NotificationsSubscriber
|
11
|
-
def
|
12
|
-
return unless state.is_execution_traced?
|
13
|
-
|
14
|
-
start_segment(name, id, payload)
|
15
|
-
rescue => e
|
16
|
-
log_notification_error(e, name, 'start')
|
17
|
-
end
|
18
|
-
|
19
|
-
def finish(name, id, payload)
|
20
|
-
return unless state.is_execution_traced?
|
21
|
-
|
22
|
-
finish_segment(id, payload)
|
23
|
-
rescue => e
|
24
|
-
log_notification_error(e, name, 'finish')
|
25
|
-
end
|
26
|
-
|
27
|
-
def start_segment(name, id, payload)
|
28
|
-
segment = Tracer.start_segment(name: metric_name(name, payload))
|
11
|
+
def add_segment_params(segment, payload)
|
29
12
|
segment.params[:key] = payload[:key]
|
30
13
|
segment.params[:exist] = payload[:exist] if payload.key?(:exist)
|
31
|
-
push_segment(id, segment)
|
32
|
-
end
|
33
|
-
|
34
|
-
def finish_segment(id, payload)
|
35
|
-
if segment = pop_segment(id)
|
36
|
-
if exception = exception_object(payload)
|
37
|
-
segment.notice_error(exception)
|
38
|
-
end
|
39
|
-
segment.finish
|
40
|
-
end
|
41
14
|
end
|
42
15
|
|
43
16
|
def metric_name(name, payload)
|
@@ -47,13 +20,12 @@ module NewRelic
|
|
47
20
|
end
|
48
21
|
|
49
22
|
PATTERN = /\Aservice_([^\.]*)\.active_storage\z/
|
50
|
-
UNKNOWN = "unknown".freeze
|
51
23
|
|
52
24
|
METHOD_NAME_MAPPING = Hash.new do |h, k|
|
53
25
|
if PATTERN =~ k
|
54
26
|
h[k] = $1
|
55
27
|
else
|
56
|
-
h[k] = UNKNOWN
|
28
|
+
h[k] = NewRelic::UNKNOWN
|
57
29
|
end
|
58
30
|
end
|
59
31
|
|
@@ -2,11 +2,26 @@
|
|
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
|
-
|
6
|
-
# to still leverage all ActiveSupport based instrumentation functionality
|
7
|
-
# offered by the agent that would otherwise be gated by the detection of Rails.
|
5
|
+
require 'new_relic/agent/instrumentation/active_support_subscriber'
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
DependencyDetection.defer do
|
8
|
+
named :active_support
|
9
|
+
|
10
|
+
depends_on do
|
11
|
+
!NewRelic::Agent.config[:disable_active_support]
|
12
|
+
end
|
13
|
+
|
14
|
+
depends_on do
|
15
|
+
defined?(ActiveSupport) &&
|
16
|
+
!NewRelic::Agent::Instrumentation::ActiveSupportSubscriber.subscribed?
|
17
|
+
end
|
18
|
+
|
19
|
+
executes do
|
20
|
+
NewRelic::Agent.logger.info('Installing ActiveSupport instrumentation')
|
21
|
+
end
|
22
|
+
|
23
|
+
executes do
|
24
|
+
ActiveSupport::Notifications.subscribe(/\.active_support$/,
|
25
|
+
NewRelic::Agent::Instrumentation::ActiveSupportSubscriber.new)
|
26
|
+
end
|
12
27
|
end
|
@@ -0,0 +1,41 @@
|
|
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 'new_relic/agent/instrumentation/notifications_subscriber'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
module Instrumentation
|
10
|
+
class ActiveSupportSubscriber < NotificationsSubscriber
|
11
|
+
def add_segment_params(segment, payload)
|
12
|
+
segment.params[:key] = payload[:key]
|
13
|
+
segment.params[:store] = payload[:store]
|
14
|
+
segment.params[:hit] = payload[:hit] if payload.key?(:hit)
|
15
|
+
segment.params[:super_operation] = payload[:super_operation] if payload.key?(:super_operation)
|
16
|
+
segment
|
17
|
+
end
|
18
|
+
|
19
|
+
def metric_name(name, payload)
|
20
|
+
store = payload[:store]
|
21
|
+
method = method_from_name(name)
|
22
|
+
"Ruby/ActiveSupport#{"/#{store}" if store}/#{method}"
|
23
|
+
end
|
24
|
+
|
25
|
+
PATTERN = /\Acache_([^\.]*)\.active_support\z/
|
26
|
+
|
27
|
+
METHOD_NAME_MAPPING = Hash.new do |h, k|
|
28
|
+
if PATTERN =~ k
|
29
|
+
h[k] = $1
|
30
|
+
else
|
31
|
+
h[k] = NewRelic::UNKNOWN
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def method_from_name(name)
|
36
|
+
METHOD_NAME_MAPPING[name]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,12 @@
|
|
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
|
+
# This is a helper file that will allow apps using ActiveSupport without Rails
|
6
|
+
# to still leverage all ActiveSupport based instrumentation functionality
|
7
|
+
# offered by the agent that would otherwise be gated by the detection of Rails.
|
8
|
+
|
9
|
+
# ActiveSupport notifications custom events
|
10
|
+
if !defined?(Rails) && defined?(ActiveSupport::Notifications) && defined?(ActiveSupport::IsolatedExecutionState)
|
11
|
+
require_relative 'rails_notifications/custom_events'
|
12
|
+
end
|
@@ -47,6 +47,47 @@ module NewRelic
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
def start(name, id, payload)
|
51
|
+
return unless state.is_execution_traced?
|
52
|
+
|
53
|
+
start_segment(name, id, payload)
|
54
|
+
rescue => e
|
55
|
+
log_notification_error(e, name, 'start')
|
56
|
+
end
|
57
|
+
|
58
|
+
def finish(name, id, payload)
|
59
|
+
return unless state.is_execution_traced?
|
60
|
+
|
61
|
+
finish_segment(id, payload)
|
62
|
+
rescue => e
|
63
|
+
log_notification_error(e, name, 'finish')
|
64
|
+
end
|
65
|
+
|
66
|
+
def start_segment(name, id, payload)
|
67
|
+
segment = Tracer.start_segment(name: metric_name(name, payload))
|
68
|
+
add_segment_params(segment, payload)
|
69
|
+
push_segment(id, segment)
|
70
|
+
end
|
71
|
+
|
72
|
+
def finish_segment(id, payload)
|
73
|
+
if segment = pop_segment(id)
|
74
|
+
if exception = exception_object(payload)
|
75
|
+
segment.notice_error(exception)
|
76
|
+
end
|
77
|
+
segment.finish
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# for subclasses
|
82
|
+
def add_segment_params(segment, payload)
|
83
|
+
# no op
|
84
|
+
end
|
85
|
+
|
86
|
+
# for subclasses
|
87
|
+
def metric_name(name, payload)
|
88
|
+
"Ruby/#{name}"
|
89
|
+
end
|
90
|
+
|
50
91
|
def log_notification_error(error, name, event_type)
|
51
92
|
# These are important enough failures that we want the backtraces
|
52
93
|
# logged at error level, hence the explicit log_exception call.
|
@@ -9,9 +9,9 @@ DependencyDetection.defer do
|
|
9
9
|
@name = :action_cable_notifications
|
10
10
|
|
11
11
|
depends_on do
|
12
|
-
defined?(
|
13
|
-
|
14
|
-
defined?(
|
12
|
+
defined?(ActionCable::VERSION::MAJOR) &&
|
13
|
+
ActionCable::VERSION::MAJOR.to_i >= 5 &&
|
14
|
+
defined?(ActiveSupport)
|
15
15
|
end
|
16
16
|
|
17
17
|
depends_on do
|
@@ -25,7 +25,7 @@ DependencyDetection.defer do
|
|
25
25
|
|
26
26
|
executes do
|
27
27
|
# enumerate the specific events we want so that we do not get unexpected additions in the future
|
28
|
-
ActiveSupport::Notifications.subscribe(
|
28
|
+
ActiveSupport::Notifications.subscribe(/\A(?:perform_action|transmit|broadcast)\.action_cable\z/,
|
29
29
|
NewRelic::Agent::Instrumentation::ActionCableSubscriber.new)
|
30
30
|
|
31
31
|
ActiveSupport.on_load(:action_cable) do
|
@@ -3,6 +3,7 @@
|
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
5
|
require 'new_relic/agent/instrumentation/action_controller_subscriber'
|
6
|
+
require 'new_relic/agent/instrumentation/action_controller_other_subscriber'
|
6
7
|
require 'new_relic/agent/prepend_supportability'
|
7
8
|
|
8
9
|
DependencyDetection.defer do
|
@@ -13,7 +14,8 @@ DependencyDetection.defer do
|
|
13
14
|
end
|
14
15
|
|
15
16
|
depends_on do
|
16
|
-
|
17
|
+
!NewRelic::Agent.config[:disable_action_controller] &&
|
18
|
+
defined?(ActionController) && (defined?(ActionController::Base) || defined?(ActionController::API))
|
17
19
|
end
|
18
20
|
|
19
21
|
executes do
|
@@ -29,5 +31,15 @@ DependencyDetection.defer do
|
|
29
31
|
|
30
32
|
NewRelic::Agent::Instrumentation::ActionControllerSubscriber \
|
31
33
|
.subscribe(/^process_action.action_controller$/)
|
34
|
+
|
35
|
+
subs = %w[send_file
|
36
|
+
send_data
|
37
|
+
redirect_to
|
38
|
+
halted_callback
|
39
|
+
unpermitted_parameters]
|
40
|
+
|
41
|
+
# have to double escape period because its going from string -> regex
|
42
|
+
NewRelic::Agent::Instrumentation::ActionControllerOtherSubscriber \
|
43
|
+
.subscribe(Regexp.new("^(#{subs.join('|')})\\.action_controller$"))
|
32
44
|
end
|
33
45
|
end
|
data/lib/new_relic/version.rb
CHANGED
data/newrelic.yml
CHANGED
@@ -169,12 +169,21 @@ common: &default_settings
|
|
169
169
|
# If true, disables Action Cable instrumentation.
|
170
170
|
# disable_action_cable_instrumentation: false
|
171
171
|
|
172
|
-
# If true, disables
|
172
|
+
# If true, disables Action Mailbox instrumentation.
|
173
|
+
# disable_action_mailbox: false
|
174
|
+
|
175
|
+
# If true, disables Action Mailer instrumentation.
|
176
|
+
# disable_action_mailer: false
|
177
|
+
|
178
|
+
# If true, disables instrumentation for Active Record 4+
|
173
179
|
# disable_active_record_notifications: false
|
174
180
|
|
175
181
|
# If true, disables Active Storage instrumentation.
|
176
182
|
# disable_active_storage: false
|
177
183
|
|
184
|
+
# If true, disables Active Support instrumentation.
|
185
|
+
# disable_active_support: false
|
186
|
+
|
178
187
|
# If true, disables Active Job instrumentation.
|
179
188
|
# disable_activejob: false
|
180
189
|
|
data/newrelic_rpm.gemspec
CHANGED
@@ -60,5 +60,6 @@ https://github.com/newrelic/newrelic-ruby-agent/
|
|
60
60
|
s.add_development_dependency 'rubocop-rake' unless ENV['CI'] && RUBY_VERSION < '3.0.0'
|
61
61
|
s.add_development_dependency 'simplecov' if RUBY_VERSION >= '2.7.0'
|
62
62
|
s.add_development_dependency 'thor' unless ENV['CI']
|
63
|
+
s.add_development_dependency 'warning' if RUBY_VERSION >= '2.4.0'
|
63
64
|
s.add_development_dependency 'yard', "#{RUBY_VERSION < '2.3.0' ? '0.9.26' : '> 0.9.26'}"
|
64
65
|
end
|
data/test/agent_helper.rb
CHANGED
@@ -1021,6 +1021,6 @@ def defer_testing_to_min_supported_rails(test_file, min_rails_version, supports_
|
|
1021
1021
|
|
1022
1022
|
yield
|
1023
1023
|
else
|
1024
|
-
puts "Skipping tests in #{test_file} because Rails >= #{min_rails_version} is unavailable"
|
1024
|
+
puts "Skipping tests in #{File.basename(test_file)} because Rails >= #{min_rails_version} is unavailable" if ENV["VERBOSE_TEST_OUTPUT"]
|
1025
1025
|
end
|
1026
1026
|
end
|
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.
|
4
|
+
version: 8.16.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: 2023-
|
14
|
+
date: 2023-02-06 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -97,6 +97,20 @@ dependencies:
|
|
97
97
|
- - ">="
|
98
98
|
- !ruby/object:Gem::Version
|
99
99
|
version: '0'
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
name: warning
|
102
|
+
requirement: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
type: :development
|
108
|
+
prerelease: false
|
109
|
+
version_requirements: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
100
114
|
- !ruby/object:Gem::Dependency
|
101
115
|
name: yard
|
102
116
|
requirement: !ruby/object:Gem::Requirement
|
@@ -241,9 +255,17 @@ files:
|
|
241
255
|
- lib/new_relic/agent/http_clients/uri_util.rb
|
242
256
|
- lib/new_relic/agent/instrumentation.rb
|
243
257
|
- lib/new_relic/agent/instrumentation/action_cable_subscriber.rb
|
258
|
+
- lib/new_relic/agent/instrumentation/action_controller_other_subscriber.rb
|
244
259
|
- lib/new_relic/agent/instrumentation/action_controller_subscriber.rb
|
260
|
+
- lib/new_relic/agent/instrumentation/action_dispatch.rb
|
261
|
+
- lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb
|
262
|
+
- lib/new_relic/agent/instrumentation/action_mailbox.rb
|
263
|
+
- lib/new_relic/agent/instrumentation/action_mailbox_subscriber.rb
|
264
|
+
- lib/new_relic/agent/instrumentation/action_mailer.rb
|
265
|
+
- lib/new_relic/agent/instrumentation/action_mailer_subscriber.rb
|
245
266
|
- lib/new_relic/agent/instrumentation/action_view_subscriber.rb
|
246
267
|
- lib/new_relic/agent/instrumentation/active_job.rb
|
268
|
+
- lib/new_relic/agent/instrumentation/active_job_subscriber.rb
|
247
269
|
- lib/new_relic/agent/instrumentation/active_merchant.rb
|
248
270
|
- lib/new_relic/agent/instrumentation/active_record.rb
|
249
271
|
- lib/new_relic/agent/instrumentation/active_record_helper.rb
|
@@ -257,6 +279,7 @@ files:
|
|
257
279
|
- lib/new_relic/agent/instrumentation/active_support_logger/chain.rb
|
258
280
|
- lib/new_relic/agent/instrumentation/active_support_logger/instrumentation.rb
|
259
281
|
- lib/new_relic/agent/instrumentation/active_support_logger/prepend.rb
|
282
|
+
- lib/new_relic/agent/instrumentation/active_support_subscriber.rb
|
260
283
|
- lib/new_relic/agent/instrumentation/acts_as_solr.rb
|
261
284
|
- lib/new_relic/agent/instrumentation/authlogic.rb
|
262
285
|
- lib/new_relic/agent/instrumentation/bunny.rb
|
@@ -272,6 +295,7 @@ files:
|
|
272
295
|
- lib/new_relic/agent/instrumentation/curb/chain.rb
|
273
296
|
- lib/new_relic/agent/instrumentation/curb/instrumentation.rb
|
274
297
|
- lib/new_relic/agent/instrumentation/curb/prepend.rb
|
298
|
+
- lib/new_relic/agent/instrumentation/custom_events.rb
|
275
299
|
- lib/new_relic/agent/instrumentation/custom_events_subscriber.rb
|
276
300
|
- lib/new_relic/agent/instrumentation/data_mapper.rb
|
277
301
|
- lib/new_relic/agent/instrumentation/delayed_job/chain.rb
|