newrelic_rpm 9.4.1 → 9.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -4
- data/lib/new_relic/agent/attribute_pre_filtering.rb +109 -0
- data/lib/new_relic/agent/configuration/default_source.rb +74 -1
- data/lib/new_relic/agent/instrumentation/active_support_logger/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +9 -0
- data/lib/new_relic/agent/instrumentation/concurrent_ruby/instrumentation.rb +2 -2
- data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +3 -0
- data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +4 -1
- data/lib/new_relic/agent/instrumentation/excon/middleware.rb +3 -0
- data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/grpc/client/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/grpc/server/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/grpc_client.rb +1 -1
- data/lib/new_relic/agent/instrumentation/grpc_server.rb +1 -1
- data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/logger/instrumentation.rb +3 -0
- data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +9 -0
- data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +4 -0
- data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +6 -0
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +4 -0
- data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/roda/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/roda/roda_transaction_namer.rb +1 -1
- data/lib/new_relic/agent/instrumentation/roda.rb +1 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/client.rb +4 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/server.rb +26 -3
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +2 -2
- data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/stripe.rb +28 -0
- data/lib/new_relic/agent/instrumentation/stripe_subscriber.rb +77 -0
- data/lib/new_relic/agent/instrumentation/tilt/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +5 -1
- data/lib/new_relic/agent/transaction/abstract_segment.rb +52 -0
- data/lib/new_relic/agent.rb +12 -0
- data/lib/new_relic/rack/agent_hooks.rb +1 -1
- data/lib/new_relic/rack/agent_middleware.rb +0 -16
- data/lib/new_relic/supportability_helper.rb +1 -0
- data/lib/new_relic/version.rb +2 -2
- data/newrelic.yml +45 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5e1f4605a4afe166aa2035486a2433f91f4d0432666b787e6d9c5af9e5ee717
|
4
|
+
data.tar.gz: 16e7707b8c81774ea0c2bea54825d023c2849d0a03ab553e25800c131d9c2972
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8180f7caa158ce2ea794914376f441f5f912f46fbce8caca074b8c2c9a06fb84ca5e290eab2aa63dfa68f5385e6f7f9f3ede8ee00ee97fbc30d692b93721ec8e
|
7
|
+
data.tar.gz: 21062253bf9236563dcd226ccc4e5e2f8d1fceaed24f6047fb6ed23f485f8b0e4607bbe9b7985c4a63809767c2f4b5785e4ec52c25ff6d2ac186ff7fb8a149f7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,67 @@
|
|
1
1
|
# New Relic Ruby Agent Release Notes
|
2
2
|
|
3
|
+
## v9.5.0
|
4
|
+
|
5
|
+
Version 9.5.0 introduces Stripe instrumentation, allows the agent to record additional response information on a transaction when middleware instrumentation is disabled, introduces new `:'sidekiq.args.include'` and `:'sidekiq.args.exclude:` configuration options to permit capturing only certain Sidekiq job arguments, updates Elasticsearch datastore instance metrics, and fixes a bug in `NewRelic::Rack::AgentHooks.needed?`.
|
6
|
+
|
7
|
+
- **Feature: Add Stripe instrumentation**
|
8
|
+
|
9
|
+
[Stripe](https://stripe.com/) calls are now automatically instrumented. Additionally, new `:'stripe.user_data.include'` and `:'stripe.user_data.exclude'` configuration options permit capturing custom `user_data` key-value pairs that can be stored in [Stripe events](https://github.com/stripe/stripe-ruby#instrumentation). No `user_data` key-value pairs are captured by default. The agent currently supports Stripe versions 5.38.0+. [PR#2180](https://github.com/newrelic/newrelic-ruby-agent/pull/2180)
|
10
|
+
|
11
|
+
- **Feature: Report transaction HTTP status codes when middleware instrumentation is disabled**
|
12
|
+
|
13
|
+
Previously, when `disable_middleware_instrumentation` was set to `true`, the agent would not record the value of the response code or content type on the transaction. This was due to the possibility that a middleware could alter the response, which would not be captured by the agent when the middleware instrumentation was disabled. However, based on customer feedback, the agent will now report the HTTP status code and content type on a transaction when middleware instrumentation is disabled. [PR#2175](https://github.com/newrelic/newrelic-ruby-agent/pull/2175)
|
14
|
+
|
15
|
+
- **Feature: Permit capturing only certain Sidekiq job arguments**
|
16
|
+
|
17
|
+
New `:'sidekiq.args.include'` and `:'sidekiq.args.exclude'` configuration options have been introduced to permit fine grained control over which Sidekiq job arguments (args) are reported to New Relic. By default, no Sidekiq args are reported. To report any Sidekiq options, the `:'attributes.include'` array must include the string `'jobs.sidekiq.args.*'`. With that string in place, all arguments will be reported unless one or more of the new include/exclude options are used. The `:'sidekiq.args.include'` option can be set to an array of strings. Each of those strings will be passed to `Regexp.new` and collectively serve as an allowlist for desired args. For job arguments that are hashes, if a hash's key matches one of the include patterns, then both the key and its corresponding value will be included. For scalar arguments, the string representation of the scalar will need to match one of the include patterns to be captured. The `:'sidekiq.args.exclude'` option works similarly. It can be set to an array of strings that will each be passed to `Regexp.new` to create patterns. These patterns will collectively serve as a denylist for unwanted job args. Any hash key, hash value, or scalar that matches an exclude pattern will be excluded (not sent to New Relic). [PR#2177](https://github.com/newrelic/newrelic-ruby-agent/pull/2177)
|
18
|
+
|
19
|
+
`newrelic.yml` examples:
|
20
|
+
|
21
|
+
Any string in the `:'sidekiq.args.include'` or `:'sidekiq.args.exclude'` arrays will be turned into a regular expression. Knowledge of [Ruby regular expression support](https://ruby-doc.org/3.2.2/Regexp.html) can be leveraged but is not required. If regular expression syntax is not used, inexact matches will be performed and the string "Fortune" will match both "Fortune 500" and "Fortune and Glory". For exact matches, use [regular expression anchors](https://ruby-doc.org/3.2.2/Regexp.html#class-Regexp-label-Anchors).
|
22
|
+
|
23
|
+
```yaml
|
24
|
+
# Include any argument whose string representation matches either "apple" or "banana"
|
25
|
+
# The "apple" pattern will match both "green apple" and "red apple"
|
26
|
+
sidekiq.args.include:
|
27
|
+
- apple
|
28
|
+
- banana
|
29
|
+
|
30
|
+
# Exclude any arguments that match either "grape", "orange", or "pear"
|
31
|
+
sidekiq.args.exclude:
|
32
|
+
- grape
|
33
|
+
- orange
|
34
|
+
- pear
|
35
|
+
|
36
|
+
# Exclude any argument that is a 9 digit number
|
37
|
+
sidekiq.args.exclude:
|
38
|
+
- '\d{9}'
|
39
|
+
|
40
|
+
# Include anything that starts with "blue" but exclude anything that ends in "green"
|
41
|
+
sidekiq.args.include
|
42
|
+
- '^blue'
|
43
|
+
|
44
|
+
sidekiq.args.exclude
|
45
|
+
- 'green$'
|
46
|
+
```
|
47
|
+
|
48
|
+
- **Bugfix: Update Elasticsearch datastore instance metric to use port instead of path**
|
49
|
+
|
50
|
+
Previously, the Elasticsearch datastore instance metric (`Datastore/instance/Elasticsearch/<host>/*`) used the path as the final value. This caused a [metrics grouping issue](https://docs.newrelic.com/docs/new-relic-solutions/solve-common-issues/troubleshooting/metric-grouping-issues) for some users, as every document ID created a unique metric. Now, the datastore instance metric has been updated to use the port as the final value. This also has the benefit of being more accurate for datastore instance metrics, as this port is directly associated with the already listed host.
|
51
|
+
|
52
|
+
- **Bugfix: Resolve inverted logic of NewRelic::Rack::AgentHooks.needed?**
|
53
|
+
|
54
|
+
Previously, `NewRelic::Rack::AgentHooks.needed?` incorrectly used inverted logic. This has now been resolved, allowing AgentHooks to be installed when `disable_middleware_instrumentation` is set to true. [PR#2175](https://github.com/newrelic/newrelic-ruby-agent/pull/2175)
|
55
|
+
|
56
|
+
|
57
|
+
## v9.4.2
|
58
|
+
|
59
|
+
Version 9.4.2 of the agent re-addresses the 9.4.0 issue of `NoMethodError` seen when using the `uppy-s3_multipart` gem.
|
60
|
+
|
61
|
+
- **Bugfix: Resolve NoMethodError**
|
62
|
+
|
63
|
+
Ruby agent 9.4.1 attempted to fix a `NoMethodError` introduced in 9.4.0. A missing `require` prevented a method from scoping appropriately and has now been added. Thanks to [@spickermann](https://github.com/spickermann) and [@ColinOrr](https://github.com/ColinOrr) for working with us to get this resolved. [PR#2167](https://github.com/newrelic/newrelic-ruby-agent/pull/2167)
|
64
|
+
|
3
65
|
## v9.4.1
|
4
66
|
|
5
67
|
Version 9.4.1 of the agent resolves a `NoMethodError` introduced in 9.4.0.
|
@@ -19,19 +81,19 @@ Version 9.4.0 of the agent adds [Roda](https://roda.jeremyevans.net/) instrument
|
|
19
81
|
- **Feature: New allow_all_headers configuration option**
|
20
82
|
|
21
83
|
A new `allow_all_headers` configuration option brings parity with the [Node.js agent](https://docs.newrelic.com/docs/release-notes/agent-release-notes/nodejs-release-notes/node-agent-270/) to capture all HTTP request headers.
|
22
|
-
|
84
|
+
|
23
85
|
This configuration option:
|
24
86
|
* Defaults to `false`
|
25
87
|
* Is not compatible with high security mode
|
26
|
-
* Requires Rack version 2 or higher (as does Ruby on Rails version 5 and above)
|
88
|
+
* Requires Rack version 2 or higher (as does Ruby on Rails version 5 and above)
|
27
89
|
* Respects all existing behavior for the `attributes.include` and `attributes.exclude` [configuration options](https://docs.newrelic.com/docs/apm/agents/ruby-agent/configuration/ruby-agent-configuration/#attributes)
|
28
90
|
* Captures the additional headers as attributes prefixed with `request.headers.`
|
29
|
-
|
91
|
+
|
30
92
|
This work was done in response to a feature request submitted by community member [@jamesarosen](https://github.com/jamesarosen). Thank you very much, @jamesarosen! [Issue#1029](https://github.com/newrelic/newrelic-ruby-agent/issues/1029)
|
31
93
|
|
32
94
|
- **Feature: Improved error tracking transaction linking**
|
33
95
|
|
34
|
-
Errors tracked and sent to the New Relic errors inbox will now be associated with a transaction id to enable improved UI/UX associations between transactions and errors. [PR#2035](https://github.com/newrelic/newrelic-ruby-agent/pull/2035)
|
96
|
+
Errors tracked and sent to the New Relic errors inbox will now be associated with a transaction id to enable improved UI/UX associations between transactions and errors. [PR#2035](https://github.com/newrelic/newrelic-ruby-agent/pull/2035)
|
35
97
|
|
36
98
|
- **Feature: Use Net::HTTP native timeout logic**
|
37
99
|
|
@@ -0,0 +1,109 @@
|
|
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
|
6
|
+
module Agent
|
7
|
+
module AttributePreFiltering
|
8
|
+
module_function
|
9
|
+
|
10
|
+
PRE_FILTER_KEYS = %i[include exclude].freeze
|
11
|
+
DISCARDED = :nr_discarded
|
12
|
+
|
13
|
+
def formulate_regexp_union(option)
|
14
|
+
return if NewRelic::Agent.config[option].empty?
|
15
|
+
|
16
|
+
Regexp.union(NewRelic::Agent.config[option].map { |p| string_to_regexp(p) }.uniq.compact).freeze
|
17
|
+
rescue StandardError => e
|
18
|
+
NewRelic::Agent.logger.warn("Failed to formulate a Regexp union from the '#{option}' configuration option " +
|
19
|
+
"- #{e.class}: #{e.message}")
|
20
|
+
end
|
21
|
+
|
22
|
+
def string_to_regexp(str)
|
23
|
+
Regexp.new(str)
|
24
|
+
rescue StandardError => e
|
25
|
+
NewRelic::Agent.logger.warn("Failed to initialize Regexp from string '#{str}' - #{e.class}: #{e.message}")
|
26
|
+
end
|
27
|
+
|
28
|
+
# attribute filtering suppresses data that has already been flattened
|
29
|
+
# and coerced (serialized as text) via #flatten_and_coerce, and is
|
30
|
+
# restricted to basic text matching with a single optional wildcard.
|
31
|
+
# pre filtering operates on raw Ruby objects beforehand and uses full
|
32
|
+
# Ruby regex syntax
|
33
|
+
def pre_filter(values = [], options = {})
|
34
|
+
return values unless !options.empty? && PRE_FILTER_KEYS.any? { |k| options.key?(k) }
|
35
|
+
|
36
|
+
# if there's a prefix in play for (non-pre) attribute filtration and
|
37
|
+
# attribute filtration won't allow that prefix, then don't even bother
|
38
|
+
# with pre filtration that could only result in values that would be
|
39
|
+
# blocked
|
40
|
+
if options.key?(:attribute_namespace) &&
|
41
|
+
!NewRelic::Agent.instance.attribute_filter.might_allow_prefix?(options[:attribute_namespace])
|
42
|
+
return values
|
43
|
+
end
|
44
|
+
|
45
|
+
values.each_with_object([]) do |element, filtered|
|
46
|
+
object = pre_filter_object(element, options)
|
47
|
+
filtered << object unless discarded?(object)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def pre_filter_object(object, options)
|
52
|
+
if object.is_a?(Hash)
|
53
|
+
pre_filter_hash(object, options)
|
54
|
+
elsif object.is_a?(Array)
|
55
|
+
pre_filter_array(object, options)
|
56
|
+
else
|
57
|
+
pre_filter_scalar(object, options)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def pre_filter_hash(hash, options)
|
62
|
+
filtered_hash = hash.each_with_object({}) do |(key, value), filtered|
|
63
|
+
filtered_key = pre_filter_object(key, options)
|
64
|
+
next if discarded?(filtered_key)
|
65
|
+
|
66
|
+
# If the key is permitted, skip include filtration for the value
|
67
|
+
# but still apply exclude filtration
|
68
|
+
if options.key?(:exclude)
|
69
|
+
exclude_only = options.dup
|
70
|
+
exclude_only.delete(:include)
|
71
|
+
filtered_value = pre_filter_object(value, exclude_only)
|
72
|
+
next if discarded?(filtered_value)
|
73
|
+
else
|
74
|
+
filtered_value = value
|
75
|
+
end
|
76
|
+
|
77
|
+
filtered[filtered_key] = filtered_value
|
78
|
+
end
|
79
|
+
|
80
|
+
filtered_hash.empty? && !hash.empty? ? DISCARDED : filtered_hash
|
81
|
+
end
|
82
|
+
|
83
|
+
def pre_filter_array(array, options)
|
84
|
+
filtered_array = array.each_with_object([]) do |element, filtered|
|
85
|
+
filtered_element = pre_filter_object(element, options)
|
86
|
+
next if discarded?(filtered_element)
|
87
|
+
|
88
|
+
filtered.push(filtered_element)
|
89
|
+
end
|
90
|
+
|
91
|
+
filtered_array.empty? && !array.empty? ? DISCARDED : filtered_array
|
92
|
+
end
|
93
|
+
|
94
|
+
def pre_filter_scalar(scalar, options)
|
95
|
+
return DISCARDED if options.key?(:include) && !scalar.to_s.match?(options[:include])
|
96
|
+
return DISCARDED if options.key?(:exclude) && scalar.to_s.match?(options[:exclude])
|
97
|
+
|
98
|
+
scalar
|
99
|
+
end
|
100
|
+
|
101
|
+
# `nil`, empty enumerable objects, and `false` are all valid in their
|
102
|
+
# own right as application data, so pre-filtering uses a special value
|
103
|
+
# to indicate that filtered out data has been discarded
|
104
|
+
def discarded?(object)
|
105
|
+
object == DISCARDED
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
5
|
require 'forwardable'
|
6
|
+
require_relative '../../constants'
|
6
7
|
|
7
8
|
module NewRelic
|
8
9
|
module Agent
|
@@ -1212,7 +1213,13 @@ module NewRelic
|
|
1212
1213
|
:public => true,
|
1213
1214
|
:type => Boolean,
|
1214
1215
|
:allowed_from_server => false,
|
1215
|
-
:description =>
|
1216
|
+
:description => <<~DESCRIPTION
|
1217
|
+
If `true`, the agent won't wrap third-party middlewares in instrumentation (regardless of whether they are installed via `Rack::Builder` or Rails).
|
1218
|
+
|
1219
|
+
<Callout variant="important">
|
1220
|
+
When middleware instrumentation is disabled, if an application is using middleware that could alter the response code, the HTTP status code reported on the transaction may not reflect the altered value.
|
1221
|
+
</Callout>
|
1222
|
+
DESCRIPTION
|
1216
1223
|
},
|
1217
1224
|
:disable_samplers => {
|
1218
1225
|
:default => false,
|
@@ -1595,6 +1602,41 @@ module NewRelic
|
|
1595
1602
|
:allowed_from_server => false,
|
1596
1603
|
:description => 'Controls auto-instrumentation of Sinatra at start up. May be one of: `auto`, `prepend`, `chain`, `disabled`.'
|
1597
1604
|
},
|
1605
|
+
:'instrumentation.stripe' => {
|
1606
|
+
:default => 'enabled',
|
1607
|
+
:public => true,
|
1608
|
+
:type => String,
|
1609
|
+
:allowed_from_server => false,
|
1610
|
+
:description => 'Controls auto-instrumentation of Stripe at startup. May be one of: `enabled`, `disabled`.'
|
1611
|
+
},
|
1612
|
+
:'stripe.user_data.include' => {
|
1613
|
+
default: NewRelic::EMPTY_ARRAY,
|
1614
|
+
public: true,
|
1615
|
+
type: Array,
|
1616
|
+
dynamic_name: true,
|
1617
|
+
allowed_from_server: false,
|
1618
|
+
:transform => DefaultSource.method(:convert_to_list),
|
1619
|
+
:description => <<~DESCRIPTION
|
1620
|
+
An array of strings to specify which keys inside a Stripe event's `user_data` hash should be reported
|
1621
|
+
to New Relic. Each string in this array will be turned into a regular expression via `Regexp.new` to
|
1622
|
+
permit advanced matching. Setting the value to `["."]` will report all `user_data`.
|
1623
|
+
DESCRIPTION
|
1624
|
+
},
|
1625
|
+
:'stripe.user_data.exclude' => {
|
1626
|
+
default: NewRelic::EMPTY_ARRAY,
|
1627
|
+
public: true,
|
1628
|
+
type: Array,
|
1629
|
+
dynamic_name: true,
|
1630
|
+
allowed_from_server: false,
|
1631
|
+
:transform => DefaultSource.method(:convert_to_list),
|
1632
|
+
:description => <<~DESCRIPTION
|
1633
|
+
An array of strings to specify which keys and/or values inside a Stripe event's `user_data` hash should
|
1634
|
+
not be reported to New Relic. Each string in this array will be turned into a regular expression via
|
1635
|
+
`Regexp.new` to permit advanced matching. For each hash pair, if either the key or value is matched the
|
1636
|
+
pair will not be reported. By default, no `user_data` is reported, so this option should only be used if
|
1637
|
+
the `stripe.user_data.include` option is being used.
|
1638
|
+
DESCRIPTION
|
1639
|
+
},
|
1598
1640
|
:'instrumentation.thread' => {
|
1599
1641
|
:default => 'auto',
|
1600
1642
|
:public => true,
|
@@ -1709,6 +1751,37 @@ module NewRelic
|
|
1709
1751
|
:transform => DefaultSource.method(:convert_to_regexp_list),
|
1710
1752
|
: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).'
|
1711
1753
|
},
|
1754
|
+
# Sidekiq
|
1755
|
+
:'sidekiq.args.include' => {
|
1756
|
+
default: NewRelic::EMPTY_ARRAY,
|
1757
|
+
public: true,
|
1758
|
+
type: Array,
|
1759
|
+
dynamic_name: true,
|
1760
|
+
allowed_from_server: false,
|
1761
|
+
description: <<~SIDEKIQ_ARGS_INCLUDE.chomp.tr("\n", ' ')
|
1762
|
+
An array of strings that will collectively serve as an allowlist for filtering which Sidekiq
|
1763
|
+
job arguments get reported to New Relic. To capture any Sidekiq arguments,
|
1764
|
+
'job.sidekiq.args.*' must be added to the separate `:'attributes.include'` configuration option. Each
|
1765
|
+
string in this array will be turned into a regular expression via `Regexp.new` to permit advanced
|
1766
|
+
matching. For job argument hashes, if either a key or value matches the pair will be included. All
|
1767
|
+
matching job argument array elements and job argument scalars will be included.
|
1768
|
+
SIDEKIQ_ARGS_INCLUDE
|
1769
|
+
},
|
1770
|
+
:'sidekiq.args.exclude' => {
|
1771
|
+
default: NewRelic::EMPTY_ARRAY,
|
1772
|
+
public: true,
|
1773
|
+
type: Array,
|
1774
|
+
dynamic_name: true,
|
1775
|
+
allowed_from_server: false,
|
1776
|
+
description: <<~SIDEKIQ_ARGS_EXCLUDE.chomp.tr("\n", ' ')
|
1777
|
+
An array of strings that will collectively serve as a denylist for filtering which Sidekiq
|
1778
|
+
job arguments get reported to New Relic. To capture any Sidekiq arguments,
|
1779
|
+
'job.sidekiq.args.*' must be added to the separate `:'attributes.include'` configuration option. Each string
|
1780
|
+
in this array will be turned into a regular expression via `Regexp.new` to permit advanced matching.
|
1781
|
+
For job argument hashes, if either a key or value matches the pair will be excluded. All matching job
|
1782
|
+
argument array elements and job argument scalars will be excluded.
|
1783
|
+
SIDEKIQ_ARGS_EXCLUDE
|
1784
|
+
},
|
1712
1785
|
# Slow SQL
|
1713
1786
|
:'slow_sql.enabled' => {
|
1714
1787
|
:default => value_of(:'transaction_tracer.enabled'),
|
@@ -6,8 +6,12 @@ module NewRelic
|
|
6
6
|
module Agent
|
7
7
|
module Instrumentation
|
8
8
|
module ActiveSupportLogger
|
9
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
10
|
+
|
9
11
|
# Mark @skip_instrumenting on any broadcasted loggers to instrument Rails.logger only
|
10
12
|
def broadcast_with_tracing(logger)
|
13
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
14
|
+
|
11
15
|
NewRelic::Agent::Instrumentation::Logger.mark_skip_instrumenting(logger)
|
12
16
|
yield
|
13
17
|
rescue => error
|
@@ -12,6 +12,7 @@ module NewRelic
|
|
12
12
|
DEFAULT_NAME = 'Default'
|
13
13
|
DEFAULT_TYPE = :direct
|
14
14
|
SLASH = '/'
|
15
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
15
16
|
|
16
17
|
def exchange_name(name)
|
17
18
|
name.empty? ? DEFAULT_NAME : name
|
@@ -28,6 +29,8 @@ module NewRelic
|
|
28
29
|
include Bunny
|
29
30
|
|
30
31
|
def publish_with_tracing(payload, opts = {})
|
32
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
33
|
+
|
31
34
|
begin
|
32
35
|
destination = exchange_name(name)
|
33
36
|
|
@@ -62,6 +65,8 @@ module NewRelic
|
|
62
65
|
include Bunny
|
63
66
|
|
64
67
|
def pop_with_tracing
|
68
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
69
|
+
|
65
70
|
bunny_error, delivery_info, message_properties, _payload = nil, nil, nil, nil
|
66
71
|
begin
|
67
72
|
t0 = Process.clock_gettime(Process::CLOCK_REALTIME)
|
@@ -104,6 +109,8 @@ module NewRelic
|
|
104
109
|
end
|
105
110
|
|
106
111
|
def purge_with_tracing
|
112
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
113
|
+
|
107
114
|
begin
|
108
115
|
type = server_named? ? :temporary_queue : :queue
|
109
116
|
segment = NewRelic::Agent::Tracer.start_message_broker_segment(
|
@@ -129,6 +136,8 @@ module NewRelic
|
|
129
136
|
include Bunny
|
130
137
|
|
131
138
|
def call_with_tracing(*args)
|
139
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
140
|
+
|
132
141
|
delivery_info, message_properties, _ = args
|
133
142
|
queue_name = queue.respond_to?(:name) ? queue.name : queue
|
134
143
|
|
@@ -5,10 +5,10 @@
|
|
5
5
|
module NewRelic::Agent::Instrumentation
|
6
6
|
module ConcurrentRuby
|
7
7
|
SEGMENT_NAME = 'Concurrent/Task'
|
8
|
-
|
8
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
9
9
|
|
10
10
|
def add_task_tracing(&task)
|
11
|
-
NewRelic::Agent.
|
11
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
12
12
|
|
13
13
|
NewRelic::Agent::Tracer.thread_block_with_current_transaction(
|
14
14
|
segment_name: SEGMENT_NAME,
|
@@ -68,6 +68,8 @@ module NewRelic
|
|
68
68
|
module Multi
|
69
69
|
include NewRelic::Agent::MethodTracer
|
70
70
|
|
71
|
+
INSTRUMENTATION_NAME = 'Curb'
|
72
|
+
|
71
73
|
# Add CAT with callbacks if the request is serial
|
72
74
|
def add_with_tracing(curl)
|
73
75
|
if curl.respond_to?(:_nr_serial) && curl._nr_serial
|
@@ -81,6 +83,8 @@ module NewRelic
|
|
81
83
|
def perform_with_tracing
|
82
84
|
return yield if first_request_is_serial?
|
83
85
|
|
86
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
87
|
+
|
84
88
|
trace_execution_scoped('External/Multiple/Curb::Multi/perform') do
|
85
89
|
yield
|
86
90
|
end
|
@@ -31,8 +31,11 @@ module NewRelic
|
|
31
31
|
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
|
32
32
|
|
33
33
|
NR_TRANSACTION_CATEGORY = 'OtherTransaction/DelayedJob'.freeze
|
34
|
+
INSTRUMENTATION_NAME = 'DelayedJob'
|
34
35
|
|
35
36
|
def invoke_job_with_tracing
|
37
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
38
|
+
|
36
39
|
options = {
|
37
40
|
:category => NR_TRANSACTION_CATEGORY,
|
38
41
|
:path => ::NewRelic::Agent::Instrumentation::DelayedJob::Naming.name_from_payload(payload_object)
|
@@ -8,15 +8,18 @@ module NewRelic::Agent::Instrumentation
|
|
8
8
|
module Elasticsearch
|
9
9
|
PRODUCT_NAME = 'Elasticsearch'
|
10
10
|
OPERATION = 'perform_request'
|
11
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
11
12
|
|
12
13
|
def perform_request_with_tracing(method, path, params = {}, body = nil, headers = nil)
|
13
14
|
return yield unless NewRelic::Agent::Tracer.tracing_enabled?
|
14
15
|
|
16
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
17
|
+
|
15
18
|
segment = NewRelic::Agent::Tracer.start_datastore_segment(
|
16
19
|
product: PRODUCT_NAME,
|
17
20
|
operation: nr_operation || OPERATION,
|
18
21
|
host: nr_hosts[:host],
|
19
|
-
port_path_or_id:
|
22
|
+
port_path_or_id: nr_hosts[:port],
|
20
23
|
database_name: nr_cluster_name
|
21
24
|
)
|
22
25
|
begin
|
@@ -6,6 +6,7 @@ module ::Excon
|
|
6
6
|
module Middleware
|
7
7
|
class NewRelicCrossAppTracing
|
8
8
|
TRACE_DATA_IVAR = :@newrelic_trace_data
|
9
|
+
INSTRUMENTATION_NAME = 'Excon'
|
9
10
|
|
10
11
|
def initialize(stack)
|
11
12
|
@stack = stack
|
@@ -18,6 +19,8 @@ module ::Excon
|
|
18
19
|
# :idempotent in the options, but there will be only a single
|
19
20
|
# accompanying response_call/error_call.
|
20
21
|
if datum[:connection] && !datum[:connection].instance_variable_get(TRACE_DATA_IVAR)
|
22
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
23
|
+
|
21
24
|
wrapped_request = ::NewRelic::Agent::HTTPClients::ExconHTTPRequest.new(datum)
|
22
25
|
segment = NewRelic::Agent::Tracer.start_external_request_segment(
|
23
26
|
library: wrapped_request.type,
|
@@ -9,6 +9,8 @@ module NewRelic::Agent::Instrumentation
|
|
9
9
|
module Instrumentation
|
10
10
|
extend self
|
11
11
|
|
12
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
13
|
+
|
12
14
|
# Since 1.2.0, the class `Grape::API` no longer refers to an API instance, rather, what used to be `Grape::API` is `Grape::API::Instance`
|
13
15
|
# https://github.com/ruby-grape/grape/blob/c20a73ac1e3f3ba1082005ed61bf69452373ba87/UPGRADING.md#upgrading-to--120
|
14
16
|
def instrumented_class
|
@@ -46,6 +48,8 @@ module NewRelic::Agent::Instrumentation
|
|
46
48
|
def handle_transaction(endpoint, class_name, version)
|
47
49
|
return unless endpoint && route = endpoint.route
|
48
50
|
|
51
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
52
|
+
|
49
53
|
name_transaction(route, class_name, version)
|
50
54
|
capture_params(endpoint)
|
51
55
|
end
|
@@ -12,10 +12,14 @@ module NewRelic
|
|
12
12
|
module Client
|
13
13
|
include NewRelic::Agent::Instrumentation::GRPC::Helper
|
14
14
|
|
15
|
+
INSTRUMENTATION_NAME = 'gRPC_Client'
|
16
|
+
|
15
17
|
def issue_request_with_tracing(grpc_type, method, requests, marshal, unmarshal,
|
16
18
|
deadline:, return_op:, parent:, credentials:, metadata:)
|
17
19
|
return yield unless trace_with_newrelic?
|
18
20
|
|
21
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
22
|
+
|
19
23
|
segment = request_segment(method)
|
20
24
|
request_wrapper = NewRelic::Agent::Instrumentation::GRPC::Client::RequestWrapper.new(@host)
|
21
25
|
# do not insert CAT headers for gRPC requests https://github.com/newrelic/newrelic-ruby-agent/issues/1730
|
@@ -11,6 +11,8 @@ module NewRelic
|
|
11
11
|
module Server
|
12
12
|
include NewRelic::Agent::Instrumentation::GRPC::Helper
|
13
13
|
|
14
|
+
INSTRUMENTATION_NAME = 'gRPC_Server'
|
15
|
+
|
14
16
|
DT_KEYS = [NewRelic::NEWRELIC_KEY, NewRelic::TRACEPARENT_KEY, NewRelic::TRACESTATE_KEY].freeze
|
15
17
|
INSTANCE_VAR_HOST = :@host_nr
|
16
18
|
INSTANCE_VAR_PORT = :@port_nr
|
@@ -23,6 +25,8 @@ module NewRelic
|
|
23
25
|
def handle_with_tracing(streamer_type, active_call, mth, _inter_ctx)
|
24
26
|
return yield unless trace_with_newrelic?
|
25
27
|
|
28
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
29
|
+
|
26
30
|
metadata = metadata_for_call(active_call)
|
27
31
|
txn = NewRelic::Agent::Transaction.start_new_transaction(NewRelic::Agent::Tracer.state,
|
28
32
|
CATEGORY,
|
@@ -13,7 +13,7 @@ DependencyDetection.defer do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
executes do
|
16
|
-
supportability_name =
|
16
|
+
supportability_name = NewRelic::Agent::Instrumentation::GRPC::Client::INSTRUMENTATION_NAME
|
17
17
|
if use_prepend?
|
18
18
|
prepend_instrument GRPC::ClientStub, NewRelic::Agent::Instrumentation::GRPC::Client::Prepend, supportability_name
|
19
19
|
else
|
@@ -14,7 +14,7 @@ DependencyDetection.defer do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
executes do
|
17
|
-
supportability_name =
|
17
|
+
supportability_name = NewRelic::Agent::Instrumentation::GRPC::Client::INSTRUMENTATION_NAME
|
18
18
|
if use_prepend?
|
19
19
|
prepend_instrument GRPC::RpcServer, NewRelic::Agent::Instrumentation::GRPC::Server::RpcServerPrepend, supportability_name
|
20
20
|
prepend_instrument GRPC::RpcDesc, NewRelic::Agent::Instrumentation::GRPC::Server::RpcDescPrepend, supportability_name
|
@@ -5,7 +5,11 @@
|
|
5
5
|
module NewRelic::Agent::Instrumentation
|
6
6
|
module HTTPClient
|
7
7
|
module Instrumentation
|
8
|
+
INSTRUMENTATION_NAME = 'HTTPClient'
|
9
|
+
|
8
10
|
def with_tracing(request, connection)
|
11
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
12
|
+
|
9
13
|
wrapped_request = NewRelic::Agent::HTTPClients::HTTPClientRequest.new(request)
|
10
14
|
segment = NewRelic::Agent::Tracer.start_external_request_segment(
|
11
15
|
library: wrapped_request.type,
|
@@ -4,7 +4,11 @@
|
|
4
4
|
|
5
5
|
module NewRelic::Agent::Instrumentation
|
6
6
|
module HTTPrb
|
7
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
8
|
+
|
7
9
|
def with_tracing(request)
|
10
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
11
|
+
|
8
12
|
wrapped_request = ::NewRelic::Agent::HTTPClients::HTTPRequest.new(request)
|
9
13
|
|
10
14
|
begin
|
@@ -6,6 +6,8 @@ module NewRelic
|
|
6
6
|
module Agent
|
7
7
|
module Instrumentation
|
8
8
|
module Logger
|
9
|
+
INSTRUMENTATION_NAME = 'Logger'
|
10
|
+
|
9
11
|
def skip_instrumenting?
|
10
12
|
defined?(@skip_instrumenting) && @skip_instrumenting
|
11
13
|
end
|
@@ -51,6 +53,7 @@ module NewRelic
|
|
51
53
|
mark_skip_instrumenting
|
52
54
|
|
53
55
|
unless ::NewRelic::Agent.agent.nil?
|
56
|
+
::NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
54
57
|
::NewRelic::Agent.agent.log_event_aggregator.record(formatted_message, severity)
|
55
58
|
formatted_message = LocalLogDecorator.decorate(formatted_message)
|
56
59
|
end
|
@@ -10,8 +10,11 @@ module NewRelic::Agent::Instrumentation
|
|
10
10
|
LOCALHOST = 'localhost'
|
11
11
|
MULTIGET_METRIC_NAME = 'get_multi_request'
|
12
12
|
MEMCACHED = 'Memcached'
|
13
|
+
INSTRUMENTATION_NAME = 'Dalli'
|
13
14
|
|
14
15
|
def with_newrelic_tracing(operation, *args)
|
16
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
17
|
+
|
15
18
|
segment = NewRelic::Agent::Tracer.start_datastore_segment(
|
16
19
|
product: MEMCACHED,
|
17
20
|
operation: operation
|
@@ -28,6 +31,8 @@ module NewRelic::Agent::Instrumentation
|
|
28
31
|
end
|
29
32
|
|
30
33
|
def server_for_key_with_newrelic_tracing
|
34
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
35
|
+
|
31
36
|
yield.tap do |server|
|
32
37
|
begin
|
33
38
|
if txn = ::NewRelic::Agent::Tracer.current_transaction
|
@@ -43,6 +48,8 @@ module NewRelic::Agent::Instrumentation
|
|
43
48
|
end
|
44
49
|
|
45
50
|
def get_multi_with_newrelic_tracing(method_name)
|
51
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
52
|
+
|
46
53
|
segment = NewRelic::Agent::Tracer.start_segment(
|
47
54
|
name: "Ruby/Memcached/Dalli/#{method_name}"
|
48
55
|
)
|
@@ -55,6 +62,8 @@ module NewRelic::Agent::Instrumentation
|
|
55
62
|
end
|
56
63
|
|
57
64
|
def send_multiget_with_newrelic_tracing(keys)
|
65
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
66
|
+
|
58
67
|
segment = ::NewRelic::Agent::Tracer.start_datastore_segment(
|
59
68
|
product: MEMCACHED,
|
60
69
|
operation: MULTIGET_METRIC_NAME
|
@@ -6,7 +6,11 @@ module NewRelic
|
|
6
6
|
module Agent
|
7
7
|
module Instrumentation
|
8
8
|
module NetHTTP
|
9
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
10
|
+
|
9
11
|
def request_with_tracing(request)
|
12
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
13
|
+
|
10
14
|
wrapped_request = NewRelic::Agent::HTTPClients::NetHTTPRequest.new(self, request)
|
11
15
|
|
12
16
|
segment = NewRelic::Agent::Tracer.start_external_request_segment(
|
@@ -47,6 +47,10 @@ module NewRelic
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
# The agent doesn't use the traditional ActiveSupport::Notifications.subscribe
|
51
|
+
# pattern due to threading issues discovered on initial instrumentation.
|
52
|
+
# Instead we define a #start and #finish method, which Rails responds to.
|
53
|
+
# See: https://github.com/rails/rails/issues/12069
|
50
54
|
def start(name, id, payload)
|
51
55
|
return unless state.is_execution_traced?
|
52
56
|
|
@@ -4,7 +4,11 @@
|
|
4
4
|
|
5
5
|
module NewRelic::Agent::Instrumentation
|
6
6
|
module Padrino
|
7
|
+
INSTRUMENTATION_NAME = NewRelic::Agent.base_name(name)
|
8
|
+
|
7
9
|
def invoke_route_with_tracing(*args)
|
10
|
+
NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)
|
11
|
+
|
8
12
|
begin
|
9
13
|
env['newrelic.last_route'] = args[0].original_path
|
10
14
|
rescue => e
|