newrelic_rpm 9.17.0 → 9.21.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/.build_ignore +1 -0
- data/CHANGELOG.md +105 -1
- data/lib/new_relic/agent/agent.rb +2 -0
- data/lib/new_relic/agent/agent_helpers/connect.rb +3 -3
- data/lib/new_relic/agent/agent_helpers/harvest.rb +3 -3
- data/lib/new_relic/agent/agent_helpers/shutdown.rb +1 -1
- data/lib/new_relic/agent/agent_helpers/start_worker_thread.rb +1 -1
- data/lib/new_relic/agent/agent_helpers/startup.rb +4 -4
- data/lib/new_relic/agent/configuration/default_source.rb +145 -120
- data/lib/new_relic/agent/configuration/manager.rb +5 -2
- data/lib/new_relic/agent/configuration/yaml_source.rb +4 -4
- data/lib/new_relic/agent/database.rb +1 -1
- data/lib/new_relic/agent/database_adapter.rb +1 -1
- data/lib/new_relic/agent/datastores/redis.rb +1 -1
- data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +1 -1
- data/lib/new_relic/agent/distributed_tracing.rb +2 -0
- data/lib/new_relic/agent/external.rb +2 -0
- data/lib/new_relic/agent/http_clients/uri_util.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_dispatch.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_dispatch_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_mailbox.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_mailer.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_job.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_job_subscriber.rb +6 -2
- data/lib/new_relic/agent/instrumentation/active_record.rb +6 -4
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +2 -2
- data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +11 -9
- data/lib/new_relic/agent/instrumentation/active_record_prepend.rb +2 -2
- data/lib/new_relic/agent/instrumentation/async_http.rb +1 -1
- data/lib/new_relic/agent/instrumentation/aws_sdk_kinesis/instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +1 -1
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/curb.rb +1 -1
- data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +1 -2
- data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +1 -0
- data/lib/new_relic/agent/instrumentation/elasticsearch.rb +1 -1
- data/lib/new_relic/agent/instrumentation/ethon.rb +1 -1
- data/lib/new_relic/agent/instrumentation/excon.rb +1 -1
- data/lib/new_relic/agent/instrumentation/fiber/chain.rb +1 -1
- data/lib/new_relic/agent/instrumentation/fiber/prepend.rb +1 -1
- data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -4
- data/lib/new_relic/agent/instrumentation/httpx/instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/httpx.rb +1 -1
- data/lib/new_relic/agent/instrumentation/logstasher.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache/helper.rb +2 -2
- data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +1 -1
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +1 -1
- data/lib/new_relic/agent/instrumentation/net_http/instrumentation.rb +3 -3
- data/lib/new_relic/agent/instrumentation/net_http.rb +2 -1
- data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +0 -2
- data/lib/new_relic/agent/instrumentation/rake.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rdkafka/chain.rb +2 -2
- data/lib/new_relic/agent/instrumentation/rdkafka/prepend.rb +2 -2
- data/lib/new_relic/agent/instrumentation/redis/constants.rb +2 -2
- data/lib/new_relic/agent/instrumentation/resque.rb +2 -2
- data/lib/new_relic/agent/instrumentation/roda.rb +1 -1
- data/lib/new_relic/agent/instrumentation/ruby_kafka/prepend.rb +1 -1
- data/lib/new_relic/agent/instrumentation/ruby_openai.rb +2 -2
- data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delay_extensions.rb +24 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +1 -1
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +9 -1
- data/lib/new_relic/agent/instrumentation/stripe.rb +1 -1
- data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +2 -2
- data/lib/new_relic/agent/llm/chat_completion_summary.rb +1 -1
- data/lib/new_relic/agent/llm/embedding.rb +1 -1
- data/lib/new_relic/agent/local_log_decorator.rb +1 -1
- data/lib/new_relic/agent/logging.rb +1 -1
- data/lib/new_relic/agent/messaging.rb +5 -0
- data/lib/new_relic/agent/method_tracer.rb +3 -0
- data/lib/new_relic/agent/monitors/inbound_request_monitor.rb +1 -1
- data/lib/new_relic/agent/monitors/synthetics_monitor.rb +1 -1
- data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +2 -2
- data/lib/new_relic/agent/new_relic_service.rb +2 -2
- data/lib/new_relic/agent/opentelemetry/context/propagation/trace_propagator.rb +66 -0
- data/lib/new_relic/agent/opentelemetry/context/propagation.rb +15 -0
- data/lib/{tasks/instrumentation_generator/templates/Envfile.tt → new_relic/agent/opentelemetry/context.rb} +9 -5
- data/lib/new_relic/agent/opentelemetry/trace/span.rb +31 -0
- data/lib/new_relic/agent/opentelemetry/trace/tracer.rb +129 -0
- data/lib/new_relic/agent/opentelemetry/trace/tracer_provider.rb +18 -0
- data/lib/new_relic/agent/opentelemetry/trace.rb +15 -0
- data/lib/new_relic/agent/opentelemetry/transaction_patch.rb +69 -0
- data/lib/new_relic/agent/opentelemetry_bridge.rb +32 -0
- data/lib/new_relic/agent/parameter_filtering.rb +1 -1
- data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -1
- data/lib/new_relic/agent/samplers/memory_sampler.rb +1 -1
- data/lib/new_relic/agent/serverless_handler.rb +7 -1
- data/lib/new_relic/agent/span_event_primitive.rb +8 -1
- data/lib/new_relic/agent/tracer.rb +1 -1
- data/lib/new_relic/agent/transaction/abstract_segment.rb +2 -1
- data/lib/new_relic/agent/transaction/datastore_segment.rb +1 -1
- data/lib/new_relic/agent/transaction/distributed_tracer.rb +3 -3
- data/lib/new_relic/agent/transaction/message_broker_segment.rb +1 -1
- data/lib/new_relic/agent/transaction/request_attributes.rb +1 -6
- data/lib/new_relic/agent/transaction/trace_context.rb +33 -4
- data/lib/new_relic/agent/transaction/tracing.rb +3 -3
- data/lib/new_relic/agent/transaction.rb +2 -1
- data/lib/new_relic/agent/transaction_time_aggregator.rb +1 -1
- data/lib/new_relic/agent/utilization/ecs.rb +22 -0
- data/lib/new_relic/agent/utilization/ecs_v4.rb +22 -0
- data/lib/new_relic/agent/utilization_data.rb +40 -5
- data/lib/new_relic/agent/vm/c_ruby_vm.rb +3 -3
- data/lib/new_relic/agent.rb +28 -0
- data/lib/new_relic/constants.rb +1 -0
- data/lib/new_relic/control/instance_methods.rb +5 -0
- data/lib/new_relic/control/instrumentation.rb +1 -1
- data/lib/new_relic/dependency_detection.rb +0 -1
- data/lib/new_relic/helper.rb +7 -0
- data/lib/new_relic/version.rb +1 -1
- data/lib/sequel/extensions/new_relic_instrumentation.rb +1 -1
- data/lib/tasks/helpers/newrelicyml.rb +6 -2
- data/newrelic.yml +80 -43
- data/newrelic_rpm.gemspec +1 -1
- metadata +17 -19
- data/lib/tasks/instrumentation_generator/README.md +0 -63
- data/lib/tasks/instrumentation_generator/TODO.md +0 -33
- data/lib/tasks/instrumentation_generator/instrumentation.thor +0 -130
- data/lib/tasks/instrumentation_generator/templates/chain.tt +0 -21
- data/lib/tasks/instrumentation_generator/templates/chain_method.tt +0 -7
- data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +0 -32
- data/lib/tasks/instrumentation_generator/templates/instrumentation.tt +0 -13
- data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +0 -3
- data/lib/tasks/instrumentation_generator/templates/newrelic.yml.tt +0 -19
- data/lib/tasks/instrumentation_generator/templates/prepend.tt +0 -13
- data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +0 -3
- data/lib/tasks/instrumentation_generator/templates/test.tt +0 -15
@@ -19,7 +19,7 @@ module NewRelic
|
|
19
19
|
# after its parent. We will use the optimized exclusive duration
|
20
20
|
# calculation in all other cases.
|
21
21
|
#
|
22
|
-
attr_reader :start_time, :end_time, :duration, :exclusive_duration, :guid, :starting_segment_key
|
22
|
+
attr_reader :start_time, :end_time, :duration, :exclusive_duration, :guid, :starting_segment_key, :thread_id
|
23
23
|
attr_accessor :name, :parent, :children_time, :transaction, :transaction_name, :llm_event
|
24
24
|
attr_writer :record_metrics, :record_scoped_metric, :record_on_finish
|
25
25
|
attr_reader :noticed_error
|
@@ -30,6 +30,7 @@ module NewRelic
|
|
30
30
|
def initialize(name = nil, start_time = nil)
|
31
31
|
@name = name
|
32
32
|
@starting_segment_key = NewRelic::Agent::Tracer.current_segment_key
|
33
|
+
@thread_id = Thread.current.object_id
|
33
34
|
@transaction_name = nil
|
34
35
|
@transaction = nil
|
35
36
|
@guid = NewRelic::Agent::GuidGenerator.generate_guid
|
@@ -11,7 +11,7 @@ module NewRelic
|
|
11
11
|
module Agent
|
12
12
|
class Transaction
|
13
13
|
class DatastoreSegment < Segment
|
14
|
-
UNKNOWN =
|
14
|
+
UNKNOWN = NewRelic::UNKNOWN_LOWER
|
15
15
|
|
16
16
|
attr_reader :product, :operation, :collection, :sql_statement, :nosql_statement, :host, :port_path_or_id
|
17
17
|
attr_accessor :database_name, :record_sql
|
@@ -35,7 +35,7 @@ module NewRelic
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def caller_transport_type
|
38
|
-
@caller_transport_type ||=
|
38
|
+
@caller_transport_type ||= NewRelic::UNKNOWN
|
39
39
|
end
|
40
40
|
|
41
41
|
def accept_transport_type_from_api(value)
|
@@ -127,7 +127,7 @@ module NewRelic
|
|
127
127
|
def consume_message_synthetics_headers(headers)
|
128
128
|
synthetics_header = headers[CrossAppTracing::NR_MESSAGE_BROKER_SYNTHETICS_HEADER]
|
129
129
|
if synthetics_header and
|
130
|
-
incoming_payload = ::JSON.
|
130
|
+
incoming_payload = ::JSON.parse(deobfuscate(synthetics_header)) and
|
131
131
|
SyntheticsMonitor.is_valid_payload?(incoming_payload) and
|
132
132
|
SyntheticsMonitor.is_supported_version?(incoming_payload) and
|
133
133
|
SyntheticsMonitor.is_trusted?(incoming_payload)
|
@@ -167,7 +167,7 @@ module NewRelic
|
|
167
167
|
return unless CrossAppTracing.trusted_valid_cross_app_id?(decoded_id)
|
168
168
|
|
169
169
|
txn_header = headers[CrossAppTracing::NR_MESSAGE_BROKER_TXN_HEADER]
|
170
|
-
txn_info = ::JSON.
|
170
|
+
txn_info = ::JSON.parse(deobfuscate(txn_header))
|
171
171
|
payload = CrossAppPayload.new(decoded_id, transaction, txn_info)
|
172
172
|
|
173
173
|
@cross_app_payload = payload
|
@@ -43,12 +43,7 @@ module NewRelic
|
|
43
43
|
end
|
44
44
|
|
45
45
|
if request_path
|
46
|
-
|
47
|
-
default_destinations
|
48
|
-
else
|
49
|
-
AttributeFilter::DST_TRANSACTION_TRACER | AttributeFilter::DST_ERROR_COLLECTOR
|
50
|
-
end
|
51
|
-
txn.add_agent_attribute(:'request.uri', request_path, destinations)
|
46
|
+
txn.add_agent_attribute(:'request.uri', request_path, default_destinations)
|
52
47
|
end
|
53
48
|
|
54
49
|
if accept
|
@@ -136,10 +136,8 @@ module NewRelic
|
|
136
136
|
|
137
137
|
transaction.distributed_tracer.parent_transaction_id = payload.transaction_id
|
138
138
|
|
139
|
-
|
140
|
-
|
141
|
-
transaction.priority = payload.priority if payload.priority
|
142
|
-
end
|
139
|
+
determine_sampling_decision(payload, header_data.trace_parent['trace_flags'])
|
140
|
+
|
143
141
|
NewRelic::Agent.increment_metric(ACCEPT_SUCCESS_METRIC)
|
144
142
|
true
|
145
143
|
rescue => e
|
@@ -148,6 +146,37 @@ module NewRelic
|
|
148
146
|
false
|
149
147
|
end
|
150
148
|
|
149
|
+
def determine_sampling_decision(payload, trace_flags)
|
150
|
+
if trace_flags == '01'
|
151
|
+
set_priority_and_sampled(NewRelic::Agent.config[:'distributed_tracing.sampler.remote_parent_sampled'], payload)
|
152
|
+
elsif trace_flags == '00'
|
153
|
+
set_priority_and_sampled(NewRelic::Agent.config[:'distributed_tracing.sampler.remote_parent_not_sampled'], payload)
|
154
|
+
else
|
155
|
+
use_nr_tracestate_sampled(payload)
|
156
|
+
end
|
157
|
+
rescue
|
158
|
+
use_nr_tracestate_sampled(payload)
|
159
|
+
end
|
160
|
+
|
161
|
+
def use_nr_tracestate_sampled(payload)
|
162
|
+
unless payload.sampled.nil?
|
163
|
+
transaction.sampled = payload.sampled
|
164
|
+
transaction.priority = payload.priority if payload.priority
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def set_priority_and_sampled(config, payload)
|
169
|
+
if config == 'always_on'
|
170
|
+
transaction.sampled = true
|
171
|
+
transaction.priority = 2.0
|
172
|
+
elsif config == 'always_off'
|
173
|
+
transaction.sampled = false
|
174
|
+
transaction.priority = 0
|
175
|
+
else # default
|
176
|
+
use_nr_tracestate_sampled(payload)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
151
180
|
def ignore_trace_context?
|
152
181
|
if trace_context_header_data
|
153
182
|
NewRelic::Agent.increment_metric(IGNORE_MULTIPLE_ACCEPT_METRIC)
|
@@ -25,7 +25,7 @@ module NewRelic
|
|
25
25
|
segment.parent = parent || thread_starting_span || current_segment
|
26
26
|
set_current_segment(segment)
|
27
27
|
if @segments.length < segment_limit
|
28
|
-
@segments << segment
|
28
|
+
@segment_lock.synchronize { @segments << segment }
|
29
29
|
else
|
30
30
|
segment.record_on_finish = true
|
31
31
|
::NewRelic::Agent.logger.debug("Segment limit of #{segment_limit} reached, ceasing collection.")
|
@@ -51,7 +51,7 @@ module NewRelic
|
|
51
51
|
|
52
52
|
def segment_complete(segment)
|
53
53
|
# if parent was in another thread, remove the current_segment entry for this thread
|
54
|
-
if segment.parent
|
54
|
+
if segment.parent&.starting_segment_key != NewRelic::Agent::Tracer.current_segment_key
|
55
55
|
remove_current_segment_by_thread_id(NewRelic::Agent::Tracer.current_segment_key)
|
56
56
|
else
|
57
57
|
set_current_segment(segment.parent)
|
@@ -65,7 +65,7 @@ module NewRelic
|
|
65
65
|
private
|
66
66
|
|
67
67
|
def finalize_segments
|
68
|
-
segments.each { |s| s
|
68
|
+
@segment_lock.synchronize { segments.each { |s| s&.finalize } }
|
69
69
|
end
|
70
70
|
|
71
71
|
WEB_TRANSACTION_TOTAL_TIME = 'WebTransactionTotalTime'.freeze
|
@@ -215,6 +215,7 @@ module NewRelic
|
|
215
215
|
@nesting_max_depth = 0
|
216
216
|
@current_segment_by_thread = {}
|
217
217
|
@current_segment_lock = Mutex.new
|
218
|
+
@segment_lock = Mutex.new
|
218
219
|
@segments = []
|
219
220
|
|
220
221
|
self.default_name = options[:transaction_name]
|
@@ -437,7 +438,7 @@ module NewRelic
|
|
437
438
|
end
|
438
439
|
|
439
440
|
def initial_segment
|
440
|
-
segments
|
441
|
+
segments&.first
|
441
442
|
end
|
442
443
|
|
443
444
|
def finished?
|
@@ -150,7 +150,7 @@ module NewRelic
|
|
150
150
|
# rubocop:disable Style/SafeNavigation
|
151
151
|
transaction_name = transaction_name = Tracer.current_transaction &&
|
152
152
|
Tracer.current_transaction.best_name ||
|
153
|
-
|
153
|
+
NewRelic::UNKNOWN_LOWER
|
154
154
|
# rubocop:enable Style/SafeNavigation
|
155
155
|
NewRelic::Agent.logger.warn("Unable to calculate elapsed transaction time for #{transaction_name}")
|
156
156
|
end
|
@@ -0,0 +1,22 @@
|
|
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/utilization/vendor'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
module Utilization
|
10
|
+
class ECS < Vendor
|
11
|
+
vendor_name 'ecs'
|
12
|
+
endpoint ENV['ECS_CONTAINER_METADATA_URI'] || ''
|
13
|
+
headers 'Metadata' => 'true'
|
14
|
+
keys %w[DockerId]
|
15
|
+
|
16
|
+
def transform_key(key)
|
17
|
+
'ecs' + key
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
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/utilization/vendor'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
module Utilization
|
10
|
+
class ECSV4 < Vendor
|
11
|
+
vendor_name 'ecs_v4'
|
12
|
+
endpoint ENV['ECS_CONTAINER_METADATA_URI_V4'] || ''
|
13
|
+
headers 'Metadata' => 'true'
|
14
|
+
keys %w[DockerId]
|
15
|
+
|
16
|
+
def transform_key(key)
|
17
|
+
'ecs' + key
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -6,6 +6,8 @@ require 'new_relic/agent/utilization/aws'
|
|
6
6
|
require 'new_relic/agent/utilization/gcp'
|
7
7
|
require 'new_relic/agent/utilization/azure'
|
8
8
|
require 'new_relic/agent/utilization/pcf'
|
9
|
+
require 'new_relic/agent/utilization/ecs'
|
10
|
+
require 'new_relic/agent/utilization/ecs_v4'
|
9
11
|
|
10
12
|
module NewRelic
|
11
13
|
module Agent
|
@@ -84,18 +86,51 @@ module NewRelic
|
|
84
86
|
result
|
85
87
|
end
|
86
88
|
|
89
|
+
def append_ecs_info(collector_hash)
|
90
|
+
return unless Agent.config[:'utilization.detect_aws']
|
91
|
+
|
92
|
+
Thread.new do
|
93
|
+
# try v4 first, and only try unversioned endpoint if v4 fails
|
94
|
+
ecs = Utilization::ECSV4.new
|
95
|
+
if ecs.detect
|
96
|
+
collector_hash[:vendors] ||= {}
|
97
|
+
collector_hash[:vendors][:ecs] = ecs.metadata
|
98
|
+
else
|
99
|
+
ecs = Utilization::ECS.new
|
100
|
+
if ecs.detect
|
101
|
+
collector_hash[:vendors] ||= {}
|
102
|
+
collector_hash[:vendors][:ecs] = ecs.metadata
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
87
108
|
def append_vendor_info(collector_hash)
|
109
|
+
threads = []
|
110
|
+
complete = false
|
111
|
+
|
112
|
+
# ecs needs be checked even if AWS check succeeds
|
113
|
+
ecs_thread = append_ecs_info(collector_hash)
|
114
|
+
|
88
115
|
VENDORS.each_pair do |klass, config_option|
|
89
116
|
next unless Agent.config[config_option]
|
90
117
|
|
91
|
-
|
118
|
+
threads << Thread.new do
|
119
|
+
vendor = klass.new
|
92
120
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
121
|
+
if vendor.detect
|
122
|
+
collector_hash[:vendors] ||= {}
|
123
|
+
collector_hash[:vendors][vendor.vendor_name.to_sym] = vendor.metadata
|
124
|
+
|
125
|
+
complete = true
|
126
|
+
end
|
97
127
|
end
|
98
128
|
end
|
129
|
+
|
130
|
+
while complete == false && threads.any?(&:alive?)
|
131
|
+
sleep 0.01
|
132
|
+
end
|
133
|
+
ecs_thread&.join
|
99
134
|
end
|
100
135
|
|
101
136
|
def append_docker_info(collector_hash)
|
@@ -61,7 +61,7 @@ module NewRelic
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def gather_constant_cache_invalidations
|
64
|
-
RubyVM.stat[RUBY_VERSION >= '3.2.0' ? :constant_cache_invalidations : :global_constant_state]
|
64
|
+
RubyVM.stat[NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '3.2.0') ? :constant_cache_invalidations : :global_constant_state]
|
65
65
|
end
|
66
66
|
|
67
67
|
def gather_constant_cache_misses
|
@@ -86,9 +86,9 @@ module NewRelic
|
|
86
86
|
when :gc_total_time
|
87
87
|
NewRelic::LanguageSupport.gc_profiler_enabled?
|
88
88
|
when :method_cache_invalidations
|
89
|
-
RUBY_VERSION < '3.0.0'
|
89
|
+
NewRelic::Helper.version_satisfied?(RUBY_VERSION, '<', '3.0.0')
|
90
90
|
when :constant_cache_misses
|
91
|
-
RUBY_VERSION >= '3.2.0'
|
91
|
+
NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '3.2.0')
|
92
92
|
else
|
93
93
|
false
|
94
94
|
end
|
data/lib/new_relic/agent.rb
CHANGED
@@ -293,6 +293,7 @@ module NewRelic
|
|
293
293
|
#
|
294
294
|
# This method is safe to use from any thread.
|
295
295
|
#
|
296
|
+
# @!scope class
|
296
297
|
# @api public
|
297
298
|
def record_metric(metric_name, value) # THREAD_LOCAL_ACCESS
|
298
299
|
record_api_supportability_metric(:record_metric)
|
@@ -333,6 +334,7 @@ module NewRelic
|
|
333
334
|
#
|
334
335
|
# This method is safe to use from any thread.
|
335
336
|
#
|
337
|
+
# @!scope class
|
336
338
|
# @api public
|
337
339
|
#
|
338
340
|
def increment_metric(metric_name, amount = 1) # THREAD_LOCAL_ACCESS
|
@@ -360,6 +362,7 @@ module NewRelic
|
|
360
362
|
#
|
361
363
|
# Return the new block or the existing filter Proc if no block is passed.
|
362
364
|
#
|
365
|
+
# @!scope class
|
363
366
|
# @api public
|
364
367
|
#
|
365
368
|
def ignore_error_filter(&block)
|
@@ -398,6 +401,7 @@ module NewRelic
|
|
398
401
|
# them if you are calling <code>notice_error</code> outside a
|
399
402
|
# transaction.
|
400
403
|
#
|
404
|
+
# @!scope class
|
401
405
|
# @api public
|
402
406
|
#
|
403
407
|
def notice_error(exception, options = {})
|
@@ -435,6 +439,7 @@ module NewRelic
|
|
435
439
|
# :'error.expected' => Whether (true) or not (false) the error was expected
|
436
440
|
# :options => The options hash passed to `NewRelic::Agent.notice_error`
|
437
441
|
#
|
442
|
+
# @!scope class
|
438
443
|
# @api public
|
439
444
|
#
|
440
445
|
def set_error_group_callback(callback_proc)
|
@@ -474,6 +479,7 @@ module NewRelic
|
|
474
479
|
# may be strings, symbols, numeric values or
|
475
480
|
# booleans.
|
476
481
|
#
|
482
|
+
# @!scope class
|
477
483
|
# @api public
|
478
484
|
#
|
479
485
|
def record_custom_event(event_type, event_attrs)
|
@@ -506,6 +512,7 @@ module NewRelic
|
|
506
512
|
# @param [optional, Hash] Set of key-value pairs to store any other
|
507
513
|
# desired data to submit with the feedback event.
|
508
514
|
#
|
515
|
+
# @!scope class
|
509
516
|
# @api public
|
510
517
|
#
|
511
518
|
def record_llm_feedback_event(trace_id:,
|
@@ -559,6 +566,7 @@ module NewRelic
|
|
559
566
|
# :model => [String] The name of the LLM model
|
560
567
|
# :content => [String] The message content or prompt
|
561
568
|
#
|
569
|
+
# @!scope class
|
562
570
|
# @api public
|
563
571
|
#
|
564
572
|
def set_llm_token_count_callback(callback_proc)
|
@@ -591,6 +599,7 @@ module NewRelic
|
|
591
599
|
# file logger. The setting for the newrelic.yml section to use
|
592
600
|
# (ie, RAILS_ENV) can be overridden with an :env argument.
|
593
601
|
#
|
602
|
+
# @!scope class
|
594
603
|
# @api public
|
595
604
|
#
|
596
605
|
def manual_start(options = {})
|
@@ -623,6 +632,7 @@ module NewRelic
|
|
623
632
|
# connection, this tells me to only try it once so this method returns
|
624
633
|
# quickly if there is some kind of latency with the server.
|
625
634
|
#
|
635
|
+
# @!scope class
|
626
636
|
# @api public
|
627
637
|
#
|
628
638
|
def after_fork(options = {})
|
@@ -636,6 +646,7 @@ module NewRelic
|
|
636
646
|
#
|
637
647
|
# @param options [Hash] Unused options Hash, for back compatibility only
|
638
648
|
#
|
649
|
+
# @!scope class
|
639
650
|
# @api public
|
640
651
|
#
|
641
652
|
def shutdown(options = {})
|
@@ -646,6 +657,7 @@ module NewRelic
|
|
646
657
|
# Clear out any data the agent has buffered but has not yet transmitted
|
647
658
|
# to the collector.
|
648
659
|
#
|
660
|
+
# @!scope class
|
649
661
|
# @api public
|
650
662
|
def drop_buffered_data
|
651
663
|
# the following line needs else branch coverage
|
@@ -660,6 +672,7 @@ module NewRelic
|
|
660
672
|
# register instrumentation than just loading the files directly,
|
661
673
|
# although that probably also works.
|
662
674
|
#
|
675
|
+
# @!scope class
|
663
676
|
# @api public
|
664
677
|
#
|
665
678
|
def add_instrumentation(file_pattern)
|
@@ -669,6 +682,7 @@ module NewRelic
|
|
669
682
|
|
670
683
|
# Require agent testing helper methods
|
671
684
|
#
|
685
|
+
# @!scope class
|
672
686
|
# @api public
|
673
687
|
def require_test_helper
|
674
688
|
record_api_supportability_metric(:require_test_helper)
|
@@ -689,6 +703,7 @@ module NewRelic
|
|
689
703
|
# my_obfuscator(sql)
|
690
704
|
# end
|
691
705
|
#
|
706
|
+
# @!scope class
|
692
707
|
# @api public
|
693
708
|
#
|
694
709
|
def set_sql_obfuscator(type = :replace, &block)
|
@@ -704,6 +719,7 @@ module NewRelic
|
|
704
719
|
# traced errors, transaction traces, Insights events, slow SQL traces,
|
705
720
|
# or RUM injection will happen for this transaction.
|
706
721
|
#
|
722
|
+
# @!scope class
|
707
723
|
# @api public
|
708
724
|
#
|
709
725
|
def ignore_transaction
|
@@ -714,6 +730,7 @@ module NewRelic
|
|
714
730
|
# This method disables the recording of Apdex metrics in the current
|
715
731
|
# transaction.
|
716
732
|
#
|
733
|
+
# @!scope class
|
717
734
|
# @api public
|
718
735
|
#
|
719
736
|
def ignore_apdex
|
@@ -724,6 +741,7 @@ module NewRelic
|
|
724
741
|
# This method disables browser monitoring javascript injection in the
|
725
742
|
# current transaction.
|
726
743
|
#
|
744
|
+
# @!scope class
|
727
745
|
# @api public
|
728
746
|
#
|
729
747
|
def ignore_enduser
|
@@ -736,6 +754,7 @@ module NewRelic
|
|
736
754
|
# track of the first entry point and turn on tracing again after
|
737
755
|
# leaving that block. This uses the thread local Tracer::State.
|
738
756
|
#
|
757
|
+
# @!scope class
|
739
758
|
# @api public
|
740
759
|
#
|
741
760
|
def disable_all_tracing
|
@@ -760,6 +779,7 @@ module NewRelic
|
|
760
779
|
# ...
|
761
780
|
# end
|
762
781
|
#
|
782
|
+
# @!scope class
|
763
783
|
# @api public
|
764
784
|
#
|
765
785
|
def disable_sql_recording
|
@@ -798,6 +818,7 @@ module NewRelic
|
|
798
818
|
# may be strings, symbols, numeric values or
|
799
819
|
# booleans.
|
800
820
|
#
|
821
|
+
# @!scope class
|
801
822
|
# @api public
|
802
823
|
#
|
803
824
|
def add_custom_attributes(params) # THREAD_LOCAL_ACCESS
|
@@ -838,6 +859,7 @@ module NewRelic
|
|
838
859
|
# booleans.
|
839
860
|
#
|
840
861
|
# @see https://docs.newrelic.com/docs/using-new-relic/welcome-new-relic/get-started/glossary#span
|
862
|
+
# @!scope class
|
841
863
|
# @api public
|
842
864
|
def add_custom_span_attributes(params)
|
843
865
|
record_api_supportability_metric(:add_custom_span_attributes)
|
@@ -879,6 +901,7 @@ module NewRelic
|
|
879
901
|
#
|
880
902
|
# Attribute pairs with empty or nil contents
|
881
903
|
# will be dropped.
|
904
|
+
# @!scope class
|
882
905
|
# @api public
|
883
906
|
def add_custom_log_attributes(params)
|
884
907
|
record_api_supportability_metric(:add_custom_log_attributes)
|
@@ -894,6 +917,7 @@ module NewRelic
|
|
894
917
|
#
|
895
918
|
# @param [String] user_id The user id to add to the current transaction attributes
|
896
919
|
#
|
920
|
+
# @!scope class
|
897
921
|
# @api public
|
898
922
|
def set_user_id(user_id)
|
899
923
|
record_api_supportability_metric(:set_user_id)
|
@@ -937,6 +961,7 @@ module NewRelic
|
|
937
961
|
#
|
938
962
|
# The default category is the same as the running transaction.
|
939
963
|
#
|
964
|
+
# @!scope class
|
940
965
|
# @api public
|
941
966
|
#
|
942
967
|
def set_transaction_name(name, options = {})
|
@@ -947,6 +972,7 @@ module NewRelic
|
|
947
972
|
# Get the name of the current running transaction. This is useful if you
|
948
973
|
# want to modify the default name.
|
949
974
|
#
|
975
|
+
# @!scope class
|
950
976
|
# @api public
|
951
977
|
#
|
952
978
|
def get_transaction_name # THREAD_LOCAL_ACCESS
|
@@ -1018,6 +1044,7 @@ module NewRelic
|
|
1018
1044
|
# * entity.guid - The guid of the current entity.
|
1019
1045
|
# * hostname - The fully qualified hostname.
|
1020
1046
|
#
|
1047
|
+
# @!scope class
|
1021
1048
|
# @api public
|
1022
1049
|
def linking_metadata
|
1023
1050
|
metadata = Hash.new
|
@@ -1044,6 +1071,7 @@ module NewRelic
|
|
1044
1071
|
#
|
1045
1072
|
# @param [String] nonce The nonce to use in the javascript tag for browser instrumentation
|
1046
1073
|
#
|
1074
|
+
# @!scope class
|
1047
1075
|
# @api public
|
1048
1076
|
#
|
1049
1077
|
def browser_timing_header(nonce = nil)
|
data/lib/new_relic/constants.rb
CHANGED
@@ -74,6 +74,7 @@ module NewRelic
|
|
74
74
|
NewRelic::Agent.agent = NewRelic::Agent::Agent.instance
|
75
75
|
init_instrumentation
|
76
76
|
init_security_agent
|
77
|
+
report_agent_version_metric
|
77
78
|
end
|
78
79
|
|
79
80
|
def determine_env(options)
|
@@ -171,6 +172,10 @@ module NewRelic
|
|
171
172
|
def stdout
|
172
173
|
STDOUT
|
173
174
|
end
|
175
|
+
|
176
|
+
def report_agent_version_metric
|
177
|
+
NewRelic::Agent.record_metric_once("Supportability/AgentVersion/newrelic_rpm/#{NewRelic::VERSION::STRING}")
|
178
|
+
end
|
174
179
|
end
|
175
180
|
include InstanceMethods
|
176
181
|
end
|
@@ -68,7 +68,7 @@ module NewRelic
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def rails_32_deprecation
|
71
|
-
return unless defined?(Rails::VERSION) &&
|
71
|
+
return unless defined?(Rails::VERSION) && NewRelic::Helper.version_satisfied?(Rails::VERSION::STRING, '<=', '3.2')
|
72
72
|
|
73
73
|
deprecation_msg = 'The Ruby agent is dropping support for Rails 3.2 ' \
|
74
74
|
'in a future major release. Please upgrade your Rails version to continue receiving support. ' \
|
@@ -179,7 +179,6 @@ module DependencyDetection
|
|
179
179
|
# logs the resolved value during debug mode.
|
180
180
|
def fetch_config_value(key)
|
181
181
|
valid_value = valid_config_value(::NewRelic::Agent.config[key].to_s.to_sym)
|
182
|
-
::NewRelic::Agent.logger.debug("Using #{valid_value} configuration value for #{self.name} to configure instrumentation")
|
183
182
|
return valid_value
|
184
183
|
end
|
185
184
|
|
data/lib/new_relic/helper.rb
CHANGED
@@ -83,6 +83,13 @@ module NewRelic
|
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
+
def version_satisfied?(left, operator, right)
|
87
|
+
left = Gem::Version.new(left) unless left.is_a?(Gem::Version)
|
88
|
+
right = Gem::Version.new(right) unless right.is_a?(Gem::Version)
|
89
|
+
|
90
|
+
left.public_send(operator, right)
|
91
|
+
end
|
92
|
+
|
86
93
|
# Bundler version 2.5.12 deprecated all_specs and added installed_specs.
|
87
94
|
# To support newer Bundler versions, try to use installed_specs first,
|
88
95
|
# then fall back to all_specs.
|
data/lib/new_relic/version.rb
CHANGED
@@ -79,7 +79,7 @@ module Sequel
|
|
79
79
|
|
80
80
|
THREAD_SAFE_CONNECTION_POOL_CLASSES = [
|
81
81
|
(defined?(::Sequel::ThreadedConnectionPool) && ::Sequel::ThreadedConnectionPool),
|
82
|
-
(defined?(::Sequel::TimedQueueConnectionPool) && RUBY_VERSION >= '3.2' && ::Sequel::TimedQueueConnectionPool)
|
82
|
+
(defined?(::Sequel::TimedQueueConnectionPool) && NewRelic::Helper.version_satisfied?(RUBY_VERSION, '>=', '3.2') && ::Sequel::TimedQueueConnectionPool)
|
83
83
|
].compact.freeze
|
84
84
|
|
85
85
|
def explainer_for(sql)
|
@@ -141,6 +141,8 @@ module NewRelicYML
|
|
141
141
|
description.gsub!(/<InlinePopover type="(.*)" \/>/, '\1')
|
142
142
|
# remove hyperlinks
|
143
143
|
description.gsub!(/\[([^\]]+)\]\([^\)]+\)/, '\1')
|
144
|
+
# delete lines with code fences including the language
|
145
|
+
description.gsub!(/```[a-zA-Z0-9_]*\n(.*?)```/m, '\1')
|
144
146
|
# remove single pairs of backticks
|
145
147
|
description.gsub!(/`([^`]+)`/, '\1')
|
146
148
|
# removed href links
|
@@ -150,11 +152,13 @@ module NewRelicYML
|
|
150
152
|
end
|
151
153
|
|
152
154
|
def self.format_description(description)
|
155
|
+
# remove all tab characters
|
156
|
+
description.delete!("\t")
|
153
157
|
# remove leading and trailing whitespace
|
154
158
|
description.strip!
|
155
159
|
# wrap text after 80 characters, assuming we're at one tabstop's (two
|
156
|
-
# spaces') level of indentation already
|
157
|
-
description.gsub!(/(.{1,78})(\s
|
160
|
+
# spaces') level of indentation already, keep leading whitespace
|
161
|
+
description.gsub!(/(.{1,78})(\s|\Z)/, "\\1\n")
|
158
162
|
# add hashtags to lines
|
159
163
|
description = description.split("\n").map { |line| " # #{line}" }.join("\n")
|
160
164
|
|