newrelic_rpm 9.13.0 → 9.15.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 +115 -5
- data/lib/new_relic/agent/aws.rb +3 -48
- data/lib/new_relic/agent/configuration/default_source.rb +91 -1
- data/lib/new_relic/agent/configuration/environment_source.rb +5 -1
- data/lib/new_relic/agent/configuration/manager.rb +16 -1
- data/lib/new_relic/agent/database/obfuscation_helpers.rb +11 -11
- data/lib/new_relic/agent/instrumentation/active_support_broadcast_logger.rb +0 -2
- data/lib/new_relic/agent/instrumentation/active_support_logger.rb +0 -2
- data/lib/new_relic/agent/instrumentation/async_http.rb +1 -2
- data/lib/new_relic/agent/instrumentation/aws_sqs.rb +0 -2
- data/lib/new_relic/agent/instrumentation/bunny.rb +3 -4
- data/lib/new_relic/agent/instrumentation/concurrent_ruby.rb +0 -2
- data/lib/new_relic/agent/instrumentation/curb.rb +3 -4
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +0 -4
- data/lib/new_relic/agent/instrumentation/dynamodb/instrumentation.rb +2 -8
- data/lib/new_relic/agent/instrumentation/dynamodb.rb +0 -2
- data/lib/new_relic/agent/instrumentation/elasticsearch.rb +0 -2
- data/lib/new_relic/agent/instrumentation/ethon.rb +0 -4
- data/lib/new_relic/agent/instrumentation/fiber.rb +0 -2
- data/lib/new_relic/agent/instrumentation/grape.rb +1 -3
- data/lib/new_relic/agent/instrumentation/httpclient.rb +0 -1
- data/lib/new_relic/agent/instrumentation/httprb.rb +0 -1
- data/lib/new_relic/agent/instrumentation/httpx.rb +0 -4
- data/lib/new_relic/agent/instrumentation/logger.rb +1 -3
- data/lib/new_relic/agent/instrumentation/logstasher.rb +0 -2
- data/lib/new_relic/agent/instrumentation/memcache.rb +0 -1
- data/lib/new_relic/agent/instrumentation/opensearch.rb +0 -2
- data/lib/new_relic/agent/instrumentation/padrino.rb +3 -3
- data/lib/new_relic/agent/instrumentation/rake.rb +0 -1
- data/lib/new_relic/agent/instrumentation/rdkafka/chain.rb +72 -0
- data/lib/new_relic/agent/instrumentation/rdkafka/instrumentation.rb +70 -0
- data/lib/new_relic/agent/instrumentation/rdkafka/prepend.rb +67 -0
- data/lib/new_relic/agent/instrumentation/rdkafka.rb +25 -0
- data/lib/new_relic/agent/instrumentation/redis.rb +0 -1
- data/lib/new_relic/agent/instrumentation/resque.rb +0 -4
- data/lib/new_relic/agent/instrumentation/roda.rb +4 -4
- data/lib/new_relic/agent/instrumentation/ruby_kafka/chain.rb +55 -0
- data/lib/new_relic/agent/instrumentation/ruby_kafka/instrumentation.rb +67 -0
- data/lib/new_relic/agent/instrumentation/ruby_kafka/prepend.rb +60 -0
- data/lib/new_relic/agent/instrumentation/ruby_kafka.rb +25 -0
- data/lib/new_relic/agent/instrumentation/sinatra.rb +3 -6
- data/lib/new_relic/agent/instrumentation/thread.rb +0 -2
- data/lib/new_relic/agent/instrumentation/tilt.rb +0 -4
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +0 -1
- data/lib/new_relic/agent/instrumentation/view_component/instrumentation.rb +7 -5
- data/lib/new_relic/agent/instrumentation/view_component.rb +0 -2
- data/lib/new_relic/agent/javascript_instrumentor.rb +2 -3
- data/lib/new_relic/agent/messaging.rb +11 -5
- data/lib/new_relic/agent/span_event_primitive.rb +4 -2
- data/lib/new_relic/agent/transaction/request_attributes.rb +13 -1
- data/lib/new_relic/agent.rb +93 -0
- data/lib/new_relic/control/frameworks/rails4.rb +1 -5
- data/lib/new_relic/dependency_detection.rb +10 -5
- data/lib/new_relic/environment_report.rb +1 -5
- data/lib/new_relic/helper.rb +15 -0
- data/lib/new_relic/language_support.rb +1 -5
- data/lib/new_relic/version.rb +1 -1
- data/lib/sequel/extensions/new_relic_instrumentation.rb +1 -1
- data/lib/tasks/instrumentation_generator/templates/dependency_detection.tt +9 -6
- data/newrelic.yml +58 -0
- data/test/agent_helper.rb +1 -1
- metadata +11 -3
@@ -164,9 +164,8 @@ module NewRelic
|
|
164
164
|
|
165
165
|
def add_ssl_for_http(data)
|
166
166
|
ssl_for_http = NewRelic::Agent.config[:'browser_monitoring.ssl_for_http']
|
167
|
-
|
168
|
-
|
169
|
-
end
|
167
|
+
|
168
|
+
data[SSL_FOR_HTTP_KEY] = ssl_for_http if ssl_for_http
|
170
169
|
end
|
171
170
|
|
172
171
|
def add_attributes(data, txn)
|
@@ -117,7 +117,8 @@ module NewRelic
|
|
117
117
|
queue_name: nil,
|
118
118
|
exchange_type: nil,
|
119
119
|
reply_to: nil,
|
120
|
-
correlation_id: nil
|
120
|
+
correlation_id: nil,
|
121
|
+
action: nil)
|
121
122
|
|
122
123
|
state = Tracer.state
|
123
124
|
return yield if state.current_transaction
|
@@ -125,12 +126,12 @@ module NewRelic
|
|
125
126
|
txn = nil
|
126
127
|
|
127
128
|
begin
|
128
|
-
txn_name = transaction_name(library, destination_type, destination_name)
|
129
|
+
txn_name = transaction_name(library, destination_type, destination_name, action)
|
129
130
|
|
130
131
|
txn = Tracer.start_transaction(name: txn_name, category: :message)
|
131
|
-
|
132
132
|
if headers
|
133
|
-
|
133
|
+
NewRelic::Agent::DistributedTracing::accept_distributed_trace_headers(headers, library) # to handle the new w3c headers
|
134
|
+
txn.distributed_tracer.consume_message_headers(headers, state, library) # to do the expected old things
|
134
135
|
CrossAppTracing.reject_messaging_cat_headers(headers).each do |k, v|
|
135
136
|
txn.add_agent_attribute(:"message.headers.#{k}", v, AttributeFilter::DST_NONE) unless v.nil?
|
136
137
|
end
|
@@ -327,12 +328,17 @@ module NewRelic
|
|
327
328
|
NewRelic::Agent.config[:'message_tracer.segment_parameters.enabled']
|
328
329
|
end
|
329
330
|
|
330
|
-
def transaction_name(library, destination_type, destination_name)
|
331
|
+
def transaction_name(library, destination_type, destination_name, action = nil)
|
331
332
|
transaction_name = Transaction::MESSAGE_PREFIX + library
|
332
333
|
transaction_name << NewRelic::SLASH
|
333
334
|
transaction_name << Transaction::MessageBrokerSegment::TYPES[destination_type]
|
334
335
|
transaction_name << NewRelic::SLASH
|
335
336
|
|
337
|
+
if action == :consume
|
338
|
+
transaction_name << 'Consume'
|
339
|
+
transaction_name << NewRelic::SLASH
|
340
|
+
end
|
341
|
+
|
336
342
|
case destination_type
|
337
343
|
when :queue
|
338
344
|
transaction_name << Transaction::MessageBrokerSegment::NAMED
|
@@ -52,6 +52,8 @@ module NewRelic
|
|
52
52
|
DATASTORE_CATEGORY = 'datastore'
|
53
53
|
CLIENT = 'client'
|
54
54
|
|
55
|
+
DB_STATEMENT_MAX_BYTES = 4096
|
56
|
+
|
55
57
|
# Builds a Hash of error attributes as well as the Span ID when
|
56
58
|
# an error is present. Otherwise, returns nil when no error present.
|
57
59
|
def error_attributes(segment)
|
@@ -114,9 +116,9 @@ module NewRelic
|
|
114
116
|
agent_attributes[DB_SYSTEM_KEY] = segment.product if allowed?(DB_SYSTEM_KEY)
|
115
117
|
|
116
118
|
if segment.sql_statement && allowed?(DB_STATEMENT_KEY)
|
117
|
-
agent_attributes[DB_STATEMENT_KEY] = truncate(segment.sql_statement.safe_sql,
|
119
|
+
agent_attributes[DB_STATEMENT_KEY] = truncate(segment.sql_statement.safe_sql, DB_STATEMENT_MAX_BYTES)
|
118
120
|
elsif segment.nosql_statement && allowed?(DB_STATEMENT_KEY)
|
119
|
-
agent_attributes[DB_STATEMENT_KEY] = truncate(segment.nosql_statement,
|
121
|
+
agent_attributes[DB_STATEMENT_KEY] = truncate(segment.nosql_statement, DB_STATEMENT_MAX_BYTES)
|
120
122
|
end
|
121
123
|
|
122
124
|
[intrinsics, custom_attributes(segment), agent_attributes.merge(agent_attributes(segment))]
|
@@ -24,7 +24,7 @@ module NewRelic
|
|
24
24
|
@referer = referer_from_request(request)
|
25
25
|
@accept = attribute_from_env(request, HTTP_ACCEPT_HEADER_KEY)
|
26
26
|
@content_length = content_length_from_request(request)
|
27
|
-
@content_type =
|
27
|
+
@content_type = content_type_attribute_from_request(request)
|
28
28
|
@host = attribute_from_request(request, :host)
|
29
29
|
@port = port_from_request(request)
|
30
30
|
@user_agent = attribute_from_request(request, :user_agent)
|
@@ -127,6 +127,18 @@ module NewRelic
|
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
|
+
def content_type_attribute_from_request(request)
|
131
|
+
# Rails 7.0 changed the behavior of `content_type`. We want just the MIME type, so use `media_type` if available.
|
132
|
+
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#actiondispatch-request-content-type-now-returns-content-type-header-as-it-is
|
133
|
+
content_type = if request.respond_to?(:media_type)
|
134
|
+
:media_type
|
135
|
+
elsif request.respond_to?(:content_type)
|
136
|
+
:content_type
|
137
|
+
end
|
138
|
+
|
139
|
+
request.send(content_type) if content_type
|
140
|
+
end
|
141
|
+
|
130
142
|
def attribute_from_env(request, key)
|
131
143
|
if env = attribute_from_request(request, :env)
|
132
144
|
env[key]
|
data/lib/new_relic/agent.rb
CHANGED
@@ -85,6 +85,10 @@ module NewRelic
|
|
85
85
|
# An exception that forces an agent to stop reporting until its mongrel is restarted.
|
86
86
|
class ForceDisconnectException < StandardError; end
|
87
87
|
|
88
|
+
# Error handling for the automated custom instrumentation tracer logic
|
89
|
+
class AutomaticTracerParseException < StandardError; end
|
90
|
+
class AutomaticTracerTraceException < StandardError; end
|
91
|
+
|
88
92
|
# An exception that forces an agent to restart.
|
89
93
|
class ForceRestartException < StandardError
|
90
94
|
def message
|
@@ -109,6 +113,9 @@ module NewRelic
|
|
109
113
|
# placeholder name used when we cannot determine a transaction's name
|
110
114
|
UNKNOWN_METRIC = '(unknown)'.freeze
|
111
115
|
LLM_FEEDBACK_MESSAGE = 'LlmFeedbackMessage'
|
116
|
+
# give the observed app time to load the code that automatic tracers have
|
117
|
+
# been configured for
|
118
|
+
AUTOMATIC_TRACER_MAX_ATTEMPTS = 60 # 60 = try about twice a second for 30 seconds
|
112
119
|
|
113
120
|
attr_reader :error_group_callback
|
114
121
|
attr_reader :llm_token_count_callback
|
@@ -163,6 +170,92 @@ module NewRelic
|
|
163
170
|
end
|
164
171
|
end
|
165
172
|
|
173
|
+
# @api private
|
174
|
+
def self.add_automatic_method_tracers(arr)
|
175
|
+
return unless arr
|
176
|
+
return arr if arr.respond_to?(:empty?) && arr.empty?
|
177
|
+
|
178
|
+
arr = arr.split(/\s*,\s*/) if arr.is_a?(String)
|
179
|
+
|
180
|
+
add_tracers_once_methods_are_defined(arr.dup)
|
181
|
+
|
182
|
+
arr
|
183
|
+
end
|
184
|
+
|
185
|
+
# spawn a thread that will attempt to establish a tracer for each of the
|
186
|
+
# configured methods. the thread will continue to keep trying with each
|
187
|
+
# tracer until one of the following happens:
|
188
|
+
# - the tracer is successfully established
|
189
|
+
# - the configured method string couldn't be parsed
|
190
|
+
# - establishing a tracer for a successfully parsed string failed
|
191
|
+
# - the maximum number of attempts has been reached
|
192
|
+
# the thread will only be spawned once per agent initialization, to account
|
193
|
+
# for configuration reloading scenarios.
|
194
|
+
#
|
195
|
+
# @api private
|
196
|
+
def self.add_tracers_once_methods_are_defined(notations)
|
197
|
+
# this class method can be invoked multiple times at agent startup, so
|
198
|
+
# we return asap here instead of using a traditional memoization of
|
199
|
+
# waiting for the method's body to finish being executed
|
200
|
+
if defined?(@add_tracers_once_methods_are_defined)
|
201
|
+
return
|
202
|
+
else
|
203
|
+
@add_tracers_once_methods_are_defined = true
|
204
|
+
end
|
205
|
+
|
206
|
+
Thread.new do
|
207
|
+
AUTOMATIC_TRACER_MAX_ATTEMPTS.times do
|
208
|
+
notations.delete_if { |notation| prep_tracer_for(notation) }
|
209
|
+
|
210
|
+
break if notations.empty?
|
211
|
+
|
212
|
+
sleep 0.5
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
# returns `true` if the notation string has either been successfully
|
218
|
+
# processed or raised an error during processing. returns `false` if the
|
219
|
+
# string seems good but the (customer) code to be traced has not yet been
|
220
|
+
# loaded into the Ruby VM
|
221
|
+
#
|
222
|
+
# @api private
|
223
|
+
def self.prep_tracer_for(fully_qualified_method_notation)
|
224
|
+
delimiters = fully_qualified_method_notation.scan(/\.|#/)
|
225
|
+
raise AutomaticTracerParseException.new("Expected exactly one '.' or '#' delimiter.") unless delimiters.size == 1
|
226
|
+
|
227
|
+
delimiter = delimiters.first
|
228
|
+
namespace, method_name = fully_qualified_method_notation.split(delimiter)
|
229
|
+
unless namespace && !namespace.empty?
|
230
|
+
raise AutomaticTracerParseException.new("Nothing found to the left of the #{delimiter} delimiter.")
|
231
|
+
end
|
232
|
+
unless method_name && !method_name.empty?
|
233
|
+
raise AutomaticTracerParseException.new("Nothing found to the right of the #{delimiter} delimiter.")
|
234
|
+
end
|
235
|
+
|
236
|
+
begin
|
237
|
+
klass = ::NewRelic::LanguageSupport.constantize(namespace)
|
238
|
+
return false unless klass
|
239
|
+
|
240
|
+
klass_to_trace = delimiter.eql?('.') ? klass.singleton_class : klass
|
241
|
+
add_or_defer_method_tracer(klass_to_trace, method_name, nil, {})
|
242
|
+
rescue StandardError => e
|
243
|
+
raise AutomaticTracerTraceException.new("#{e.class} - #{e.message}")
|
244
|
+
end
|
245
|
+
|
246
|
+
true
|
247
|
+
rescue AutomaticTracerParseException => e
|
248
|
+
NewRelic::Agent.logger.error('Unable to parse out a usable method name to trace. Expected a valid, fully ' \
|
249
|
+
"qualified method notation. Got: '#{fully_qualified_method_notation}'. " \
|
250
|
+
"Error: #{e.message}")
|
251
|
+
true
|
252
|
+
rescue AutomaticTracerTraceException => e
|
253
|
+
NewRelic::Agent.logger.error('Unable to automatically apply a tracer to method ' \
|
254
|
+
"'#{fully_qualified_method_notation}'. Error: #{e.message}")
|
255
|
+
true
|
256
|
+
end
|
257
|
+
|
258
|
+
# @api private
|
166
259
|
def add_deferred_method_tracers_now
|
167
260
|
@tracer_lock.synchronize do
|
168
261
|
@tracer_queue.each do |receiver, method_name, metric_name, options|
|
@@ -9,11 +9,7 @@ module NewRelic
|
|
9
9
|
module Frameworks
|
10
10
|
class Rails4 < NewRelic::Control::Frameworks::Rails3
|
11
11
|
def rails_gem_list
|
12
|
-
|
13
|
-
Bundler.rubygems.installed_specs.map { |gem| "#{gem.name} (#{gem.version})" }
|
14
|
-
else
|
15
|
-
Bundler.rubygems.all_specs.map { |gem| "#{gem.name} (#{gem.version})" }
|
16
|
-
end
|
12
|
+
NewRelic::Helper.rubygems_specs.map { |gem| "#{gem.name} (#{gem.version})" }
|
17
13
|
end
|
18
14
|
|
19
15
|
def append_plugin_list
|
@@ -25,11 +25,9 @@ module DependencyDetection
|
|
25
25
|
|
26
26
|
def detect!
|
27
27
|
@items.each do |item|
|
28
|
-
if item.
|
29
|
-
|
30
|
-
|
31
|
-
item.configure_as_unsatisfied unless item.disabled_configured?
|
32
|
-
end
|
28
|
+
next if item.executed || item.disabled_configured?
|
29
|
+
|
30
|
+
item.dependencies_satisfied? ? item.execute : item.configure_as_unsatisfied
|
33
31
|
end
|
34
32
|
end
|
35
33
|
|
@@ -65,6 +63,13 @@ module DependencyDetection
|
|
65
63
|
end
|
66
64
|
|
67
65
|
def configure_as_unsatisfied
|
66
|
+
# TODO: currently using :unsatisfied for Padrino will clobber the value
|
67
|
+
# already set for Sinatra, so skip Padrino and circle back with a
|
68
|
+
# new Padrino specific solution in the future.
|
69
|
+
#
|
70
|
+
# https://github.com/newrelic/newrelic-ruby-agent/issues/2912
|
71
|
+
return if name == :padrino
|
72
|
+
|
68
73
|
NewRelic::Agent.config.instance_variable_get(:@cache)[config_key] = :unsatisfied
|
69
74
|
end
|
70
75
|
|
@@ -44,11 +44,7 @@ module NewRelic
|
|
44
44
|
####################################
|
45
45
|
report_on('Gems') do
|
46
46
|
begin
|
47
|
-
|
48
|
-
Bundler.rubygems.installed_specs.map { |gem| "#{gem.name}(#{gem.version})" }
|
49
|
-
else
|
50
|
-
Bundler.rubygems.all_specs.map { |gem| "#{gem.name}(#{gem.version})" }
|
51
|
-
end
|
47
|
+
NewRelic::Helper.rubygems_specs.map { |gem| "#{gem.name}(#{gem.version})" }
|
52
48
|
rescue
|
53
49
|
# There are certain rubygem, bundler, rails combinations (e.g. gem
|
54
50
|
# 1.6.2, rails 2.3, bundler 1.2.3) where the code above throws an error
|
data/lib/new_relic/helper.rb
CHANGED
@@ -82,5 +82,20 @@ module NewRelic
|
|
82
82
|
File.exist?(executable_path) && File.file?(executable_path) && File.executable?(executable_path)
|
83
83
|
end
|
84
84
|
end
|
85
|
+
|
86
|
+
# Bundler version 2.5.12 deprecated all_specs and added installed_specs.
|
87
|
+
# To support newer Bundler versions, try to use installed_specs first,
|
88
|
+
# then fall back to all_specs.
|
89
|
+
# All callers expect this to be an array, so return an array if Bundler isn't defined
|
90
|
+
# @api private
|
91
|
+
def rubygems_specs
|
92
|
+
return [] unless defined?(Bundler)
|
93
|
+
|
94
|
+
if Bundler.rubygems.respond_to?(:installed_specs)
|
95
|
+
Bundler.rubygems.installed_specs
|
96
|
+
else
|
97
|
+
Bundler.rubygems.all_specs
|
98
|
+
end
|
99
|
+
end
|
85
100
|
end
|
86
101
|
end
|
@@ -90,11 +90,7 @@ module NewRelic
|
|
90
90
|
def bundled_gem?(gem_name)
|
91
91
|
return false unless defined?(Bundler)
|
92
92
|
|
93
|
-
|
94
|
-
Bundler.rubygems.installed_specs.map(&:name).include?(gem_name)
|
95
|
-
else
|
96
|
-
Bundler.rubygems.all_specs.map(&:name).include?(gem_name)
|
97
|
-
end
|
93
|
+
NewRelic::Helper.rubygems_specs.map(&:name).include?(gem_name)
|
98
94
|
rescue => e
|
99
95
|
::NewRelic::Agent.logger.info("Could not determine if third party #{gem_name} gem is installed", e)
|
100
96
|
false
|
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.
|
82
|
+
(defined?(::Sequel::TimedQueueConnectionPool) && RUBY_VERSION >= '3.2' && ::Sequel::TimedQueueConnectionPool)
|
83
83
|
].compact.freeze
|
84
84
|
|
85
85
|
def explainer_for(sql)
|
@@ -2,12 +2,8 @@
|
|
2
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
3
3
|
# frozen_string_literal: true
|
4
4
|
|
5
|
-
require_relative '<%= @snake_name.downcase %>/instrumentation'
|
6
|
-
require_relative '<%= @snake_name.downcase %>/chain'
|
7
|
-
require_relative '<%= @snake_name.downcase %>/prepend'
|
8
|
-
|
9
5
|
DependencyDetection.defer do
|
10
|
-
named :<%= @
|
6
|
+
named :<%= @snake_name %>
|
11
7
|
|
12
8
|
depends_on do
|
13
9
|
# The class that needs to be defined to prepend/chain onto. This can be used
|
@@ -18,11 +14,18 @@ DependencyDetection.defer do
|
|
18
14
|
end
|
19
15
|
|
20
16
|
executes do
|
21
|
-
|
17
|
+
require_relative '<%= @snake_name.downcase %>/instrumentation'
|
22
18
|
|
19
|
+
# prepend_instrument and chain_instrument call extract_supportability_name
|
20
|
+
# to get the library name for supportability metrics and info-level logging.
|
21
|
+
# This is done by spliting on the 2nd to last spot of the instrumented
|
22
|
+
# module. If this isn't how we want the name to appear, pass in the desired
|
23
|
+
# name as a third argument.
|
23
24
|
if use_prepend?
|
25
|
+
require_relative '<%= @snake_name.downcase %>/prepend'
|
24
26
|
prepend_instrument <%= @class_name %>, NewRelic::Agent::Instrumentation::<%= @class_name %>::Prepend
|
25
27
|
else
|
28
|
+
require_relative '<%= @snake_name.downcase %>/chain'
|
26
29
|
chain_instrument NewRelic::Agent::Instrumentation::<%= @class_name %>::Chain
|
27
30
|
end
|
28
31
|
end
|
data/newrelic.yml
CHANGED
@@ -113,6 +113,53 @@ common: &default_settings
|
|
113
113
|
# Specifies a path to the audit log file (including the filename).
|
114
114
|
# audit_log.path: log/newrelic_audit.log
|
115
115
|
|
116
|
+
# An array of CLASS#METHOD (for instance methods) and/or CLASS.METHOD (for class
|
117
|
+
# methods) strings representing Ruby methods for the agent to automatically
|
118
|
+
# add custom instrumentation to without the need for altering any of the
|
119
|
+
# source code that defines the methods.
|
120
|
+
#
|
121
|
+
# Use fully qualified class names (using the :: delimiter) that include any
|
122
|
+
# module or class namespacing.
|
123
|
+
#
|
124
|
+
# Here is some Ruby source code that defines a render_png instance method for an
|
125
|
+
# Image class and a notify class method for a User class, both within a
|
126
|
+
# MyCompany module namespace:
|
127
|
+
#
|
128
|
+
# module MyCompany
|
129
|
+
# class Image
|
130
|
+
# def render_png
|
131
|
+
# # code to render a PNG
|
132
|
+
# end
|
133
|
+
# end
|
134
|
+
#
|
135
|
+
# class User
|
136
|
+
# def self.notify
|
137
|
+
# # code to notify users
|
138
|
+
# end
|
139
|
+
# end
|
140
|
+
# end
|
141
|
+
#
|
142
|
+
# Given that source code, the newrelic.yml config file might request
|
143
|
+
# instrumentation for both of these methods like so:
|
144
|
+
#
|
145
|
+
# automatic_custom_instrumentation_method_list:
|
146
|
+
# - MyCompany::Image#render_png
|
147
|
+
# - MyCompany::User.notify
|
148
|
+
#
|
149
|
+
# That configuration example uses YAML array syntax to specify both methods.
|
150
|
+
# Alternatively, a comma-delimited string can be used instead:
|
151
|
+
#
|
152
|
+
# automatic_custom_instrumentation_method_list: 'MyCompany::Image#render_png, MyCompany::User.notify'
|
153
|
+
#
|
154
|
+
# Whitespace around the comma(s) in the list is optional. When configuring the
|
155
|
+
# agent with a list of methods via the
|
156
|
+
# NEW_RELIC_AUTOMATIC_CUSTOM_INSTRUMENTATION_METHOD_LIST environment variable,
|
157
|
+
# this comma-delimited string format should be used:
|
158
|
+
#
|
159
|
+
# export NEW_RELIC_AUTOMATIC_CUSTOM_INSTRUMENTATION_METHOD_LIST='MyCompany::Image#render_png, MyCompany::User.notify'
|
160
|
+
#
|
161
|
+
# automatic_custom_instrumentation_method_list: []
|
162
|
+
|
116
163
|
# Specify a list of constants that should prevent the agent from starting
|
117
164
|
# automatically. Separate individual constants with a comma ,. For example,
|
118
165
|
# "Rails::Console,UninstrumentedBackgroundJob".
|
@@ -169,6 +216,9 @@ common: &default_settings
|
|
169
216
|
# If true, the agent will clear Tracer::State in Agent.drop_buffered_data.
|
170
217
|
# clear_transaction_state_after_fork: false
|
171
218
|
|
219
|
+
# The AWS account ID for the AWS account associated with this app
|
220
|
+
# cloud.aws.account_id: nil
|
221
|
+
|
172
222
|
# If true, the agent will report source code level metrics for traced methods.
|
173
223
|
# See:
|
174
224
|
# https://docs.newrelic.com/docs/apm/agents/ruby-agent/features/ruby-codestream-integration/
|
@@ -535,6 +585,10 @@ common: &default_settings
|
|
535
585
|
# prepend, chain, disabled.
|
536
586
|
# instrumentation.rake: auto
|
537
587
|
|
588
|
+
# Controls auto-instrumentation of the rdkafka library at start-up. May be one
|
589
|
+
# of auto, prepend, chain, disabled.
|
590
|
+
# instrumentation.rdkafka: auto
|
591
|
+
|
538
592
|
# Controls auto-instrumentation of Redis at start-up. May be one of: auto,
|
539
593
|
# prepend, chain, disabled.
|
540
594
|
# instrumentation.redis: auto
|
@@ -547,6 +601,10 @@ common: &default_settings
|
|
547
601
|
# prepend, chain, disabled.
|
548
602
|
# instrumentation.roda: auto
|
549
603
|
|
604
|
+
# Controls auto-instrumentation of the ruby-kafka library at start-up. May be
|
605
|
+
# one of auto, prepend, chain, disabled.
|
606
|
+
# instrumentation.ruby_kafka: auto
|
607
|
+
|
550
608
|
# Controls auto-instrumentation of the ruby-openai gem at start-up. May be one
|
551
609
|
# of: auto, prepend, chain, disabled. Defaults to disabled in high security
|
552
610
|
# mode.
|
data/test/agent_helper.rb
CHANGED
@@ -112,7 +112,7 @@ def assert_log_contains(log, message)
|
|
112
112
|
lines = log.array
|
113
113
|
|
114
114
|
assert (lines.any? { |line| line.match(message) }),
|
115
|
-
"Could not find message. Log contained: #{lines.join("\n")}"
|
115
|
+
"Could not find message: '#{message.inspect}'. Log contained: #{lines.join("\n")}"
|
116
116
|
end
|
117
117
|
|
118
118
|
def assert_audit_log_contains(audit_log_contents, needle)
|
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.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tanna McClure
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2024-
|
14
|
+
date: 2024-10-31 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -509,6 +509,10 @@ files:
|
|
509
509
|
- lib/new_relic/agent/instrumentation/rake/chain.rb
|
510
510
|
- lib/new_relic/agent/instrumentation/rake/instrumentation.rb
|
511
511
|
- lib/new_relic/agent/instrumentation/rake/prepend.rb
|
512
|
+
- lib/new_relic/agent/instrumentation/rdkafka.rb
|
513
|
+
- lib/new_relic/agent/instrumentation/rdkafka/chain.rb
|
514
|
+
- lib/new_relic/agent/instrumentation/rdkafka/instrumentation.rb
|
515
|
+
- lib/new_relic/agent/instrumentation/rdkafka/prepend.rb
|
512
516
|
- lib/new_relic/agent/instrumentation/redis.rb
|
513
517
|
- lib/new_relic/agent/instrumentation/redis/chain.rb
|
514
518
|
- lib/new_relic/agent/instrumentation/redis/cluster_middleware.rb
|
@@ -527,6 +531,10 @@ files:
|
|
527
531
|
- lib/new_relic/agent/instrumentation/roda/instrumentation.rb
|
528
532
|
- lib/new_relic/agent/instrumentation/roda/prepend.rb
|
529
533
|
- lib/new_relic/agent/instrumentation/roda/roda_transaction_namer.rb
|
534
|
+
- lib/new_relic/agent/instrumentation/ruby_kafka.rb
|
535
|
+
- lib/new_relic/agent/instrumentation/ruby_kafka/chain.rb
|
536
|
+
- lib/new_relic/agent/instrumentation/ruby_kafka/instrumentation.rb
|
537
|
+
- lib/new_relic/agent/instrumentation/ruby_kafka/prepend.rb
|
530
538
|
- lib/new_relic/agent/instrumentation/ruby_openai.rb
|
531
539
|
- lib/new_relic/agent/instrumentation/ruby_openai/chain.rb
|
532
540
|
- lib/new_relic/agent/instrumentation/ruby_openai/instrumentation.rb
|
@@ -770,7 +778,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
770
778
|
- !ruby/object:Gem::Version
|
771
779
|
version: 1.3.1
|
772
780
|
requirements: []
|
773
|
-
rubygems_version: 3.5.
|
781
|
+
rubygems_version: 3.5.16
|
774
782
|
signing_key:
|
775
783
|
specification_version: 4
|
776
784
|
summary: New Relic Ruby Agent
|