newrelic_rpm 9.23.0 → 9.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/lib/new_relic/agent/configuration/default_source.rb +61 -15
- data/lib/new_relic/agent/configuration/sampler_config_validator.rb +54 -0
- data/lib/new_relic/agent/datastores.rb +27 -9
- data/lib/new_relic/agent/opentelemetry_bridge.rb +8 -5
- data/lib/new_relic/agent/sql_sampler.rb +3 -0
- data/lib/new_relic/agent/transaction/distributed_tracing.rb +11 -19
- data/lib/new_relic/agent/transaction/trace_context.rb +28 -6
- data/lib/new_relic/agent/transaction.rb +43 -2
- data/lib/new_relic/version.rb +1 -1
- data/newrelic.yml +3 -4
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2a513be9b409b6ae8c4e08416ded683ef6abeb372607baf25ba7aa10f7a916f5
|
|
4
|
+
data.tar.gz: 3604c7f4df3c33a1f61cd2b3b984dce971bac3b3b028862929a0c99c79931f4c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5ecb0cd5c7b6476b008ac82be5bbda20b2c4e8b58465f457057a9357ac499f82b3779b9bbbcdaa2e5c2376db98e000957f653875bb9e98436f41b1a4f718dc42
|
|
7
|
+
data.tar.gz: 72e77abe6f9b63be2ae7af1bd99dcb285ec82d54725826e38c5c54df391c13bc983b7d50fe4b9e0795ef6b28f02c732d196db1ebe40f7e590d031f3d8394c3a6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# New Relic Ruby Agent Release Notes
|
|
2
2
|
|
|
3
|
+
## v9.24.0
|
|
4
|
+
|
|
5
|
+
- **Feature: Deprecation reminder for SqlSampler#notice_sql API**
|
|
6
|
+
|
|
7
|
+
The `NewRelic::Agent::SqlSampler#notice_sql` method is deprecated and will be removed in a future major version. Instead, users should call `NewRelic::Agent::Datastores.notice_sql`. [PR#3345](https://github.com/newrelic/newrelic-ruby-agent/pull/3345)
|
|
8
|
+
|
|
9
|
+
- **Feature: Deprecation notice for second and third arguments in Datastores.notice_sql API**
|
|
10
|
+
|
|
11
|
+
The second (`scoped_metric`) and third (`elapsed`) arguments in the `NewRelic::Agent::Datastores.notice_sql` method are deprecated. They have not been used by the method for some time. Instead, these values will be set based on the current segment when the API is called. [PR#3345](https://github.com/newrelic/newrelic-ruby-agent/pull/3345)
|
|
12
|
+
|
|
13
|
+
- **Feature: Deprecation notice for second argument in Datastores.notice_statement API**
|
|
14
|
+
|
|
15
|
+
The second (`elapsed`) argument in the `NewRelic::Agent::Datastores.notice_statement` method is deprecated. It has not been used by the method for some time. Instead, this value will be set based on the current segment when the API is called. [PR#3346](https://github.com/newrelic/newrelic-ruby-agent/pull/3346)
|
|
16
|
+
|
|
17
|
+
- **Feature: Deprecation notice for proc's second and third arguments in Datastores.wrap API**
|
|
18
|
+
|
|
19
|
+
The `NewRelic::Agent::Datastores.wrap` method is changing. In a future major version, proc will only accept a single argument, the result of the yield. The scoped metric name and elapsed arguments will be removed, as they are being removed from the `Datastores.notice_sql` method. The scoped metric name and elapsed values are derived from the current segment when the wrap yields. [PR#3346](https://github.com/newrelic/newrelic-ruby-agent/pull/3346)
|
|
20
|
+
|
|
3
21
|
## v9.23.0
|
|
4
22
|
|
|
5
23
|
- **Feature: Add sidekiq.ignore_retry_errors configuration option**
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
require 'forwardable'
|
|
6
6
|
require_relative '../../constants'
|
|
7
|
+
require_relative 'sampler_config_validator'
|
|
7
8
|
|
|
8
9
|
module NewRelic
|
|
9
10
|
module Agent
|
|
@@ -281,16 +282,6 @@ module NewRelic
|
|
|
281
282
|
constants.compact!
|
|
282
283
|
constants
|
|
283
284
|
end
|
|
284
|
-
|
|
285
|
-
def self.enforce_fallback(allowed_values: nil, fallback: nil)
|
|
286
|
-
proc do |configured_value|
|
|
287
|
-
if allowed_values.any? { |v| v =~ /#{configured_value}/i }
|
|
288
|
-
configured_value
|
|
289
|
-
else
|
|
290
|
-
fallback
|
|
291
|
-
end
|
|
292
|
-
end
|
|
293
|
-
end
|
|
294
285
|
end
|
|
295
286
|
|
|
296
287
|
AUTOSTART_DENYLISTED_RAKE_TASKS = [
|
|
@@ -1463,19 +1454,68 @@ module NewRelic
|
|
|
1463
1454
|
:allowed_from_server => true,
|
|
1464
1455
|
:description => 'Distributed tracing lets you see the path that a request takes through your distributed system. Enabling distributed tracing changes the behavior of some New Relic features, so carefully consult the [transition guide](/docs/transition-guide-distributed-tracing) before you enable this feature.'
|
|
1465
1456
|
},
|
|
1457
|
+
:'distributed_tracing.sampler.root' => {
|
|
1458
|
+
:default => 'default',
|
|
1459
|
+
:public => false,
|
|
1460
|
+
:type => String,
|
|
1461
|
+
:allowed_from_server => false,
|
|
1462
|
+
:allowlist => %w[default adaptive always_on always_off trace_id_ratio_based],
|
|
1463
|
+
:transform => SamplerConfigValidator.validate_sampler_strategy_with_ratio(
|
|
1464
|
+
:'distributed_tracing.sampler.root',
|
|
1465
|
+
:'distributed_tracing.sampler.root.trace_id_ratio_based.ratio'
|
|
1466
|
+
),
|
|
1467
|
+
:description => 'This setting controls the behavior of transaction sampling for transactions without a remote parent, traces that originate within this instance of the New Relic agent. Available values are `default`, `adaptive`, `always_on`, `always_off`, and `trace_id_ratio_based`. At this time `default` and `adaptive` are the same.'
|
|
1468
|
+
},
|
|
1466
1469
|
:'distributed_tracing.sampler.remote_parent_sampled' => {
|
|
1467
1470
|
:default => 'default',
|
|
1468
1471
|
:public => true,
|
|
1469
1472
|
:type => String,
|
|
1470
|
-
:allowed_from_server =>
|
|
1471
|
-
:
|
|
1473
|
+
:allowed_from_server => false,
|
|
1474
|
+
:allowlist => %w[default adaptive always_on always_off trace_id_ratio_based],
|
|
1475
|
+
:transform => SamplerConfigValidator.validate_sampler_strategy_with_ratio(
|
|
1476
|
+
:'distributed_tracing.sampler.remote_parent_sampled',
|
|
1477
|
+
:'distributed_tracing.sampler.remote_parent_sampled.trace_id_ratio_based.ratio'
|
|
1478
|
+
),
|
|
1479
|
+
:description => 'This setting controls the behavior of transaction sampling when a remote parent is sampled. Available values are `default`, `always_on`, and `always_off`.'
|
|
1472
1480
|
},
|
|
1473
1481
|
:'distributed_tracing.sampler.remote_parent_not_sampled' => {
|
|
1474
1482
|
:default => 'default',
|
|
1475
1483
|
:public => true,
|
|
1476
1484
|
:type => String,
|
|
1477
|
-
:allowed_from_server =>
|
|
1478
|
-
:
|
|
1485
|
+
:allowed_from_server => false,
|
|
1486
|
+
:allowlist => %w[default adaptive always_on always_off trace_id_ratio_based],
|
|
1487
|
+
:transform => SamplerConfigValidator.validate_sampler_strategy_with_ratio(
|
|
1488
|
+
:'distributed_tracing.sampler.remote_parent_not_sampled',
|
|
1489
|
+
:'distributed_tracing.sampler.remote_parent_not_sampled.trace_id_ratio_based.ratio'
|
|
1490
|
+
),
|
|
1491
|
+
:description => 'This setting controls the behavior of transaction sampling when a remote parent is not sampled. Available values are `default`, `always_on`, and `always_off`.'
|
|
1492
|
+
},
|
|
1493
|
+
:'distributed_tracing.sampler.root.trace_id_ratio_based.ratio' => {
|
|
1494
|
+
:default => nil,
|
|
1495
|
+
:public => false,
|
|
1496
|
+
:type => Float,
|
|
1497
|
+
:allow_nil => true,
|
|
1498
|
+
:allowed_from_server => false,
|
|
1499
|
+
:transform => SamplerConfigValidator.method(:validate_sampling_ratio),
|
|
1500
|
+
:description => 'The ratio used for the trace_id_ratio_based sampling decision for the root sampler. This must be a float between 0.0 and 1.0. If you provide an invalid value, the sampler will not use the trace_id_ratio_based sampler and will return to the default behavior. If you do not provide a value, the sampler will not use the trace_id_ratio_based_sampler and fall back to the default sampler.'
|
|
1501
|
+
},
|
|
1502
|
+
:'distributed_tracing.sampler.remote_parent_sampled.trace_id_ratio_based.ratio' => {
|
|
1503
|
+
:default => nil,
|
|
1504
|
+
:public => false,
|
|
1505
|
+
:type => Float,
|
|
1506
|
+
:allow_nil => true,
|
|
1507
|
+
:allowed_from_server => false,
|
|
1508
|
+
:transform => SamplerConfigValidator.method(:validate_sampling_ratio),
|
|
1509
|
+
:description => 'The ratio used for the trace_id_ratio_based sampling decision for the remote parent sampled sampler. This must be a float between 0.0 and 1.0. If you provide an invalid value, the sampler will not use the trace_id_ratio_based sampler and will return to the default behavior. If you do not provide a value, the sampler will not use the trace_id_ratio_based_sampler and fall back to the default sampler.'
|
|
1510
|
+
},
|
|
1511
|
+
:'distributed_tracing.sampler.remote_parent_not_sampled.trace_id_ratio_based.ratio' => {
|
|
1512
|
+
:default => nil,
|
|
1513
|
+
:public => false,
|
|
1514
|
+
:type => Float,
|
|
1515
|
+
:allow_nil => true,
|
|
1516
|
+
:allowed_from_server => false,
|
|
1517
|
+
:transform => SamplerConfigValidator.method(:validate_sampling_ratio),
|
|
1518
|
+
:description => 'The ratio used for the trace_id_ratio_based sampling decision for the remote parent not sampled sampler. This must be a float between 0.0 and 1.0. If you provide an invalid value or do not provide a value, the sampler will not use the trace_id_ratio_based_sampler and fall back to the default sampler.'
|
|
1479
1519
|
},
|
|
1480
1520
|
# Elasticsearch
|
|
1481
1521
|
:'elasticsearch.capture_cluster_name' => {
|
|
@@ -2516,8 +2556,14 @@ module NewRelic
|
|
|
2516
2556
|
:allowed_from_server => true,
|
|
2517
2557
|
:description => 'Number of seconds betwixt connections to the New Relic span event collection services.'
|
|
2518
2558
|
},
|
|
2519
|
-
# TODO: Sync with the other agents to see what the config should be named, how it should be enabled, how it should be described
|
|
2520
2559
|
:'opentelemetry.enabled' => {
|
|
2560
|
+
:default => false,
|
|
2561
|
+
:public => false,
|
|
2562
|
+
:type => Boolean,
|
|
2563
|
+
:allowed_from_server => false,
|
|
2564
|
+
:description => 'A global configuration option for disabling all OpenTelemetry signals sent through New Relic. If false, no OpenTelemetry signals will be sent to New Relic. If true, the signal-specific enabled config option (e.g. opentelemetry.traces.enabled) determines whether telemetry of that signal type will be reported to New Relic.'
|
|
2565
|
+
},
|
|
2566
|
+
:'opentelemetry.traces.enabled' => {
|
|
2521
2567
|
:default => false,
|
|
2522
2568
|
:public => false,
|
|
2523
2569
|
:type => Boolean,
|
|
@@ -0,0 +1,54 @@
|
|
|
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 Configuration
|
|
8
|
+
# Handles validation for the `distributed_tracing.sampler.*` configs
|
|
9
|
+
# Focuses on validating the trace id ratio based ratios
|
|
10
|
+
module SamplerConfigValidator
|
|
11
|
+
@sampler_strategy_warnings = {}
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
def validate_sampling_ratio(ratio)
|
|
15
|
+
return nil if ratio.nil?
|
|
16
|
+
return nil unless valid_ratio?(ratio)
|
|
17
|
+
|
|
18
|
+
ratio
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def validate_sampler_strategy_with_ratio(strategy_key, ratio_key)
|
|
22
|
+
proc do |strategy|
|
|
23
|
+
next strategy unless strategy == 'trace_id_ratio_based'
|
|
24
|
+
|
|
25
|
+
ratio = NewRelic::Agent.config[ratio_key]
|
|
26
|
+
|
|
27
|
+
next strategy if valid_ratio?(ratio)
|
|
28
|
+
|
|
29
|
+
unless @sampler_strategy_warnings[strategy_key]
|
|
30
|
+
NewRelic::Agent.logger.warn(
|
|
31
|
+
"Invalid or missing ratio for #{ratio_key} (value: #{ratio.inspect}). " \
|
|
32
|
+
"Falling back to 'default' for #{strategy_key}."
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
@sampler_strategy_warnings[strategy_key] = true
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
'default'
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def valid_ratio?(ratio)
|
|
43
|
+
ratio.is_a?(Float) && (0.0..1.0).cover?(ratio)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# used for testing
|
|
47
|
+
def reset_warnings!
|
|
48
|
+
@sampler_strategy_warnings = {}
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -85,9 +85,11 @@ module NewRelic
|
|
|
85
85
|
# statement-level metrics (i.e. table or model name)
|
|
86
86
|
#
|
|
87
87
|
# @param [Proc,#call] callback proc or other callable to invoke after
|
|
88
|
-
# running the datastore block. Receives three arguments:
|
|
89
|
-
#
|
|
90
|
-
#
|
|
88
|
+
# running the datastore block. Receives three arguments:
|
|
89
|
+
# * result of the yield
|
|
90
|
+
# * (optional, deprecated) the most specific (scoped) metric name
|
|
91
|
+
# * (optional, deprecated) elapsed time of the call
|
|
92
|
+
# An example use is attaching SQL to Transaction Traces at the end
|
|
91
93
|
# of a wrapped datastore call.
|
|
92
94
|
#
|
|
93
95
|
# callback = Proc.new do |result, metrics, elapsed|
|
|
@@ -107,6 +109,11 @@ module NewRelic
|
|
|
107
109
|
# @api public
|
|
108
110
|
#
|
|
109
111
|
def self.wrap(product, operation, collection = nil, callback = nil)
|
|
112
|
+
NewRelic::Agent.logger.warn('The NewRelic::Agent::Datastores.wrap method is changing. ' \
|
|
113
|
+
'In a future major version, proc will only accept a single argument, the result of the yield. ' \
|
|
114
|
+
'The scoped metric name and elapsed arguments will be removed, as they are being removed from the ' \
|
|
115
|
+
'Datastores.notice_sql method. The scoped metric name and elapsed values are derived from the ' \
|
|
116
|
+
'current segment when the wrap yields.')
|
|
110
117
|
NewRelic::Agent.record_api_supportability_metric(:wrap)
|
|
111
118
|
|
|
112
119
|
return yield unless operation
|
|
@@ -145,11 +152,12 @@ module NewRelic
|
|
|
145
152
|
# some dialects of SQL (or non-SQL queries) are not guaranteed to be
|
|
146
153
|
# properly obfuscated by these routines!
|
|
147
154
|
#
|
|
148
|
-
# @param [String] scoped_metric The most specific
|
|
149
|
-
# query. Typically the result of
|
|
155
|
+
# @param [String] scoped_metric (optional, deprecated) The most specific
|
|
156
|
+
# metric relating to this query. Typically the result of
|
|
150
157
|
# NewRelic::Agent::Datastores::MetricHelper#metrics_for
|
|
151
158
|
#
|
|
152
|
-
# @param [Float] elapsed the elapsed time during
|
|
159
|
+
# @param [Float] elapsed (optional, deprecated) the elapsed time during
|
|
160
|
+
# query execution
|
|
153
161
|
#
|
|
154
162
|
# @note THERE ARE SECURITY CONCERNS WHEN CAPTURING QUERY TEXT!
|
|
155
163
|
# New Relic's Transaction Tracing and Slow SQL features will
|
|
@@ -159,7 +167,11 @@ module NewRelic
|
|
|
159
167
|
#
|
|
160
168
|
# @api public
|
|
161
169
|
#
|
|
162
|
-
def self.notice_sql(query, scoped_metric, elapsed)
|
|
170
|
+
def self.notice_sql(query, scoped_metric = '', elapsed = 0.0)
|
|
171
|
+
NewRelic::Agent.logger.warn('The NewRelic::Agent::Datastores.notice_sql method is changing. ' \
|
|
172
|
+
'In a future major version, the scoped_metric and elapsed arguments will be removed. ' \
|
|
173
|
+
'The scoped_metric and elapsed values are now based on the current segment when the notice_sql method ' \
|
|
174
|
+
'was called.')
|
|
163
175
|
NewRelic::Agent.record_api_supportability_metric(:notice_sql)
|
|
164
176
|
|
|
165
177
|
if (txn = Tracer.current_transaction) && (segment = txn.current_segment) && segment.respond_to?(:notice_sql)
|
|
@@ -180,7 +192,8 @@ module NewRelic
|
|
|
180
192
|
#
|
|
181
193
|
# @param [String] statement text of the statement to capture.
|
|
182
194
|
#
|
|
183
|
-
# @param [Float] elapsed the elapsed time during
|
|
195
|
+
# @param [Float] elapsed (optional, deprecated) the elapsed time during
|
|
196
|
+
# query execution
|
|
184
197
|
#
|
|
185
198
|
# @note THERE ARE SECURITY CONCERNS WHEN CAPTURING STATEMENTS!
|
|
186
199
|
# This method will properly ignore statements when the user has turned
|
|
@@ -191,7 +204,12 @@ module NewRelic
|
|
|
191
204
|
#
|
|
192
205
|
# @api public
|
|
193
206
|
#
|
|
194
|
-
def self.notice_statement(statement, elapsed)
|
|
207
|
+
def self.notice_statement(statement, elapsed = 0.0)
|
|
208
|
+
NewRelic::Agent.logger.warn('The ' \
|
|
209
|
+
'NewRelic::Agent::Datastores.notice_statement method is changing. ' \
|
|
210
|
+
'In a future major version, the elapsed argument will be removed. ' \
|
|
211
|
+
'The elapsed value is now based on the current segment when the ' \
|
|
212
|
+
'notice_statement method was called.')
|
|
195
213
|
NewRelic::Agent.record_api_supportability_metric(:notice_statement)
|
|
196
214
|
|
|
197
215
|
# Settings may change eventually, but for now we follow the same
|
|
@@ -6,11 +6,14 @@ module NewRelic
|
|
|
6
6
|
module Agent
|
|
7
7
|
class OpenTelemetryBridge
|
|
8
8
|
def initialize
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
# currently, we only have support for traces
|
|
10
|
+
# this method should change when we add support for metrics and logs.
|
|
11
|
+
if defined?(OpenTelemetry) && Agent.config[:'opentelemetry.enabled'] && Agent.config[:'opentelemetry.traces.enabled']
|
|
12
|
+
OpenTelemetryBridge.install
|
|
13
|
+
NewRelic::Agent.record_metric('Supportability/Tracing/Ruby/OpenTelemetryBridge/enabled', 0.0)
|
|
14
|
+
else
|
|
15
|
+
NewRelic::Agent.record_metric('Supportability/Tracing/Ruby/OpenTelemetryBridge/disabled', 0.0)
|
|
16
|
+
end
|
|
14
17
|
end
|
|
15
18
|
|
|
16
19
|
private
|
|
@@ -140,6 +140,9 @@ module NewRelic
|
|
|
140
140
|
# @deprecated Use {Datastores.notice_sql} instead.
|
|
141
141
|
#
|
|
142
142
|
def notice_sql(sql, metric_name, config, duration, state = nil, explainer = nil, binds = nil, name = nil) # THREAD_LOCAL_ACCESS sometimes
|
|
143
|
+
NewRelic::Agent.logger.warn(
|
|
144
|
+
'The SqlSampler#notice_sql method is deprecated. Please use Datastores.notice_sql instead.'
|
|
145
|
+
)
|
|
143
146
|
state ||= Tracer.state
|
|
144
147
|
data = state.sql_sampler_transaction_data
|
|
145
148
|
return unless data
|
|
@@ -161,29 +161,21 @@ module NewRelic
|
|
|
161
161
|
transaction.parent_span_id = payload.id
|
|
162
162
|
|
|
163
163
|
unless payload.sampled.nil?
|
|
164
|
-
if payload.sampled
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
if payload.sampled
|
|
165
|
+
set_priority_and_sampled(
|
|
166
|
+
NewRelic::Agent.config[:'distributed_tracing.sampler.remote_parent_sampled'],
|
|
167
|
+
NewRelic::Agent.config[:'distributed_tracing.sampler.remote_parent_sampled.trace_id_ratio_based.ratio'],
|
|
168
|
+
payload
|
|
169
|
+
)
|
|
168
170
|
else
|
|
169
|
-
|
|
170
|
-
|
|
171
|
+
set_priority_and_sampled(
|
|
172
|
+
NewRelic::Agent.config[:'distributed_tracing.sampler.remote_parent_not_sampled'],
|
|
173
|
+
NewRelic::Agent.config[:'distributed_tracing.sampler.remote_parent_not_sampled.trace_id_ratio_based.ratio'],
|
|
174
|
+
payload
|
|
175
|
+
)
|
|
171
176
|
end
|
|
172
177
|
end
|
|
173
178
|
end
|
|
174
|
-
|
|
175
|
-
def set_priority_and_sampled_newrelic_header(config, payload)
|
|
176
|
-
if config == 'always_on'
|
|
177
|
-
transaction.sampled = true
|
|
178
|
-
transaction.priority = 2.0
|
|
179
|
-
elsif config == 'always_off'
|
|
180
|
-
transaction.sampled = false
|
|
181
|
-
transaction.priority = 0
|
|
182
|
-
else # case for 'default' value
|
|
183
|
-
transaction.sampled = payload.sampled
|
|
184
|
-
transaction.priority = payload.priority if payload.priority
|
|
185
|
-
end
|
|
186
|
-
end
|
|
187
179
|
end
|
|
188
180
|
end
|
|
189
181
|
end
|
|
@@ -154,9 +154,17 @@ module NewRelic
|
|
|
154
154
|
|
|
155
155
|
def determine_sampling_decision(payload, trace_flags)
|
|
156
156
|
if trace_flags == '01'
|
|
157
|
-
set_priority_and_sampled(
|
|
157
|
+
set_priority_and_sampled(
|
|
158
|
+
NewRelic::Agent.config[:'distributed_tracing.sampler.remote_parent_sampled'],
|
|
159
|
+
NewRelic::Agent.config[:'distributed_tracing.sampler.remote_parent_sampled.trace_id_ratio_based.ratio'],
|
|
160
|
+
payload
|
|
161
|
+
)
|
|
158
162
|
elsif trace_flags == '00'
|
|
159
|
-
set_priority_and_sampled(
|
|
163
|
+
set_priority_and_sampled(
|
|
164
|
+
NewRelic::Agent.config[:'distributed_tracing.sampler.remote_parent_not_sampled'],
|
|
165
|
+
NewRelic::Agent.config[:'distributed_tracing.sampler.remote_parent_not_sampled.trace_id_ratio_based.ratio'],
|
|
166
|
+
payload
|
|
167
|
+
)
|
|
160
168
|
else
|
|
161
169
|
use_nr_tracestate_sampled(payload)
|
|
162
170
|
end
|
|
@@ -171,14 +179,28 @@ module NewRelic
|
|
|
171
179
|
end
|
|
172
180
|
end
|
|
173
181
|
|
|
174
|
-
def set_priority_and_sampled(
|
|
175
|
-
|
|
182
|
+
def set_priority_and_sampled(sampler, ratio, payload)
|
|
183
|
+
# Ruby evaluates case statements top to bottom. Listing the statements
|
|
184
|
+
# in the order of most likely to match keeps things performant.
|
|
185
|
+
# If we put more than one string in a condition, it'll check to see if
|
|
186
|
+
# the case matches any one of those conditions before moving on to the
|
|
187
|
+
# next one.
|
|
188
|
+
#
|
|
189
|
+
# Even though adaptive behaves the same as default, I hypothesize it
|
|
190
|
+
# will be used so infrequently, it should just be listed last.
|
|
191
|
+
case sampler
|
|
192
|
+
when 'default'
|
|
193
|
+
use_nr_tracestate_sampled(payload)
|
|
194
|
+
when 'always_on'
|
|
176
195
|
transaction.sampled = true
|
|
177
196
|
transaction.priority = 2.0
|
|
178
|
-
|
|
197
|
+
when 'always_off'
|
|
179
198
|
transaction.sampled = false
|
|
180
199
|
transaction.priority = 0
|
|
181
|
-
|
|
200
|
+
when 'trace_id_ratio_based'
|
|
201
|
+
transaction.sampled = transaction.trace_ratio_sampled?(ratio)
|
|
202
|
+
transaction.priority = transaction.default_priority
|
|
203
|
+
when 'adaptive'
|
|
182
204
|
use_nr_tracestate_sampled(payload)
|
|
183
205
|
end
|
|
184
206
|
end
|
|
@@ -294,11 +294,41 @@ module NewRelic
|
|
|
294
294
|
return false unless Agent.config[:'distributed_tracing.enabled']
|
|
295
295
|
|
|
296
296
|
if @sampled.nil?
|
|
297
|
-
|
|
297
|
+
# Ruby evaluates case statements top to bottom. Listing the statements
|
|
298
|
+
# in the order of most likely to match keeps things performant.
|
|
299
|
+
# If we put more than one string in a condition, it'll check to see if
|
|
300
|
+
# the case matches any one of those conditions before moving on to the
|
|
301
|
+
# next one.
|
|
302
|
+
#
|
|
303
|
+
# Even though adaptive behaves the same as default, I hypothesize it
|
|
304
|
+
# will be used so infrequently, it should just be listed last.
|
|
305
|
+
@sampled = case NewRelic::Agent.config[:'distributed_tracing.sampler.root']
|
|
306
|
+
when 'default'
|
|
307
|
+
NewRelic::Agent.instance.adaptive_sampler.sampled?
|
|
308
|
+
when 'always_on'
|
|
309
|
+
true
|
|
310
|
+
when 'always_off'
|
|
311
|
+
false
|
|
312
|
+
when 'trace_id_ratio_based'
|
|
313
|
+
trace_ratio_sampled?(NewRelic::Agent.config[:'distributed_tracing.sampler.root.trace_id_ratio_based.ratio'])
|
|
314
|
+
when 'adaptive'
|
|
315
|
+
NewRelic::Agent.instance.adaptive_sampler.sampled?
|
|
316
|
+
end
|
|
298
317
|
end
|
|
299
318
|
@sampled
|
|
300
319
|
end
|
|
301
320
|
|
|
321
|
+
def trace_ratio_sampled?(ratio)
|
|
322
|
+
# In the opentelemetry-sdk TraceIdRatioBased sampler, the algorithm
|
|
323
|
+
# looks like this:
|
|
324
|
+
# ratio == 1.0 || trace_id[8, 8].unpack1('Q>') < (ratio * (2**64 - 1)).ceil
|
|
325
|
+
# OTel stores their trace ids as binary strings
|
|
326
|
+
# ex. Array(trace_id).pack('H*')
|
|
327
|
+
# Since we don't store our trace ids as binary strings, this way is
|
|
328
|
+
# faster, but still gets the same result.
|
|
329
|
+
ratio == 1.0 || Integer(trace_id[16, 16], 16) < (ratio * (2**64 - 1)).ceil
|
|
330
|
+
end
|
|
331
|
+
|
|
302
332
|
def trace_id
|
|
303
333
|
@trace_id ||= NewRelic::Agent::GuidGenerator.generate_guid(32)
|
|
304
334
|
end
|
|
@@ -307,8 +337,19 @@ module NewRelic
|
|
|
307
337
|
@trace_id = value
|
|
308
338
|
end
|
|
309
339
|
|
|
340
|
+
def default_priority
|
|
341
|
+
(sampled? ? rand + 1.0 : rand).round(NewRelic::PRIORITY_PRECISION)
|
|
342
|
+
end
|
|
343
|
+
|
|
310
344
|
def priority
|
|
311
|
-
@priority ||=
|
|
345
|
+
@priority ||= case NewRelic::Agent.config[:'distributed_tracing.sampler.root']
|
|
346
|
+
when 'default', 'trace_id_ratio_based', 'adaptive'
|
|
347
|
+
default_priority
|
|
348
|
+
when 'always_on'
|
|
349
|
+
2.0
|
|
350
|
+
when 'always_off'
|
|
351
|
+
0
|
|
352
|
+
end
|
|
312
353
|
end
|
|
313
354
|
|
|
314
355
|
def referer
|
data/lib/new_relic/version.rb
CHANGED
data/newrelic.yml
CHANGED
|
@@ -361,13 +361,12 @@ common: &default_settings
|
|
|
361
361
|
# distributed_tracing.enabled: true
|
|
362
362
|
|
|
363
363
|
# This setting controls the behavior of transaction sampling when a remote
|
|
364
|
-
# parent is not sampled
|
|
365
|
-
#
|
|
364
|
+
# parent is not sampled. Available values are default, always_on, and
|
|
365
|
+
# always_off.
|
|
366
366
|
# distributed_tracing.sampler.remote_parent_not_sampled: default
|
|
367
367
|
|
|
368
368
|
# This setting controls the behavior of transaction sampling when a remote
|
|
369
|
-
# parent is sampled
|
|
370
|
-
# values are default, always_on, and always_off.
|
|
369
|
+
# parent is sampled. Available values are default, always_on, and always_off.
|
|
371
370
|
# distributed_tracing.sampler.remote_parent_sampled: default
|
|
372
371
|
|
|
373
372
|
# If true, the agent captures the Elasticsearch cluster name in transaction
|
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: 9.
|
|
4
|
+
version: 9.24.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tanna McClure
|
|
@@ -301,6 +301,7 @@ files:
|
|
|
301
301
|
- lib/new_relic/agent/configuration/manager.rb
|
|
302
302
|
- lib/new_relic/agent/configuration/manual_source.rb
|
|
303
303
|
- lib/new_relic/agent/configuration/mask_defaults.rb
|
|
304
|
+
- lib/new_relic/agent/configuration/sampler_config_validator.rb
|
|
304
305
|
- lib/new_relic/agent/configuration/security_policy_source.rb
|
|
305
306
|
- lib/new_relic/agent/configuration/server_source.rb
|
|
306
307
|
- lib/new_relic/agent/configuration/yaml_source.rb
|