newrelic_rpm 8.12.0 → 8.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +14 -7
- data/CHANGELOG.md +33 -0
- data/README.md +1 -1
- data/lib/new_relic/agent/agent_logger.rb +1 -1
- data/lib/new_relic/agent/audit_logger.rb +1 -1
- data/lib/new_relic/agent/configuration/default_source.rb +1403 -1369
- data/lib/new_relic/agent/configuration/environment_source.rb +2 -2
- data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +1 -1
- data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +0 -2
- data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +0 -2
- data/lib/new_relic/agent/instrumentation/authlogic.rb +0 -2
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +0 -1
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +0 -2
- data/lib/new_relic/agent/instrumentation/excon.rb +17 -0
- data/lib/new_relic/agent/instrumentation/rack/chain.rb +10 -2
- data/lib/new_relic/agent/instrumentation/rack/prepend.rb +9 -2
- data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +0 -1
- data/lib/new_relic/agent/instrumentation/redis/chain.rb +18 -6
- data/lib/new_relic/agent/instrumentation/redis/constants.rb +17 -0
- data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +28 -18
- data/lib/new_relic/agent/instrumentation/redis/middleware.rb +16 -0
- data/lib/new_relic/agent/instrumentation/redis/prepend.rb +6 -0
- data/lib/new_relic/agent/instrumentation/redis.rb +6 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/client.rb +20 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +30 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/server.rb +37 -0
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +6 -70
- data/lib/new_relic/agent/instrumentation/sinatra.rb +0 -2
- data/lib/new_relic/agent/instrumentation/sunspot.rb +0 -2
- data/lib/new_relic/agent/method_tracer_helpers.rb +1 -1
- data/lib/new_relic/agent/parameter_filtering.rb +7 -1
- data/lib/new_relic/agent/tracer.rb +1 -1
- data/lib/new_relic/constants.rb +2 -0
- data/lib/new_relic/control/instrumentation.rb +4 -8
- data/lib/new_relic/local_environment.rb +1 -1
- data/lib/new_relic/rack/browser_monitoring.rb +1 -0
- data/lib/new_relic/version.rb +1 -1
- data/lib/tasks/helpers/prompt.rb +1 -1
- data/lib/tasks/instrumentation_generator/README.md +2 -2
- data/lib/tasks/instrumentation_generator/TODO.md +5 -5
- data/newrelic_rpm.gemspec +1 -1
- data/test/agent_helper.rb +18 -0
- metadata +9 -4
@@ -51,8 +51,8 @@ module NewRelic
|
|
51
51
|
|
52
52
|
def set_log_file
|
53
53
|
if ENV['NEW_RELIC_LOG']
|
54
|
-
if ENV['NEW_RELIC_LOG'].casecmp(
|
55
|
-
self[:log_file_path] = self[:log_file_name] =
|
54
|
+
if ENV['NEW_RELIC_LOG'].casecmp(NewRelic::STANDARD_OUT) == 0
|
55
|
+
self[:log_file_path] = self[:log_file_name] = NewRelic::STANDARD_OUT
|
56
56
|
else
|
57
57
|
self[:log_file_path] = File.dirname(ENV['NEW_RELIC_LOG'])
|
58
58
|
self[:log_file_name] = File.basename(ENV['NEW_RELIC_LOG'])
|
@@ -9,7 +9,7 @@ module NewRelic
|
|
9
9
|
module HTTPClients
|
10
10
|
class HTTPResponse < AbstractResponse
|
11
11
|
def [](key)
|
12
|
-
_, value = @wrapped_response.headers.find { |k, _| key.casecmp(k)
|
12
|
+
_, value = @wrapped_response.headers.find { |k, _| key.casecmp(k) == 0 }
|
13
13
|
value unless value.nil?
|
14
14
|
end
|
15
15
|
|
@@ -17,6 +17,7 @@ DependencyDetection.defer do
|
|
17
17
|
# so we could safely subscribe and not be clobbered by future subscribers,
|
18
18
|
# but alas, it does not yet.
|
19
19
|
|
20
|
+
# TODO: MAJOR VERSION - update min version to 0.56.0
|
20
21
|
EXCON_MIN_VERSION = Gem::Version.new("0.19.0")
|
21
22
|
|
22
23
|
depends_on do
|
@@ -32,6 +33,22 @@ DependencyDetection.defer do
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
36
|
+
executes do
|
37
|
+
next unless Gem::Version.new(::Excon::VERSION) < Gem::Version.new('0.56.0')
|
38
|
+
|
39
|
+
deprecation_msg = 'Instrumentation for Excon versions below 0.56.0 is deprecated.' \
|
40
|
+
'They will stop being monitored in version 9.0.0. ' \
|
41
|
+
'Please upgrade your Excon version to continue receiving full support. '
|
42
|
+
|
43
|
+
::NewRelic::Agent.logger.log_once(
|
44
|
+
:warn,
|
45
|
+
:deprecated_excon_version,
|
46
|
+
deprecation_msg
|
47
|
+
)
|
48
|
+
|
49
|
+
::NewRelic::Agent.record_metric("Supportability/Deprecated/Excon", 1)
|
50
|
+
end
|
51
|
+
|
35
52
|
def install_excon_instrumentation(excon_version)
|
36
53
|
require 'new_relic/agent/distributed_tracing/cross_app_tracing'
|
37
54
|
require 'new_relic/agent/http_clients/excon_wrappers'
|
@@ -21,8 +21,16 @@ module NewRelic::Agent::Instrumentation
|
|
21
21
|
if ::NewRelic::Agent::Instrumentation::RackHelpers.middleware_instrumentation_enabled?
|
22
22
|
::NewRelic::Agent.logger.info("Installing #{builder_class} middleware instrumentation")
|
23
23
|
|
24
|
-
def run_with_newrelic(app, *args)
|
25
|
-
|
24
|
+
def run_with_newrelic(app = nil, *args, &block)
|
25
|
+
app_or_block = app || block
|
26
|
+
run_with_tracing(app_or_block) do |wrapped|
|
27
|
+
# Rack::Builder#run for Rack v3+ supports a block, and does not
|
28
|
+
# support args. Whether a block or an app is provided, that
|
29
|
+
# callable object will be wrapped into a MiddlewareProxy
|
30
|
+
# instance. That proxy instance must then be passed to
|
31
|
+
# run_without_newrelic as the app argument.
|
32
|
+
block ? run_without_newrelic(wrapped, &nil) : run_without_newrelic(wrapped, *args)
|
33
|
+
end
|
26
34
|
end
|
27
35
|
|
28
36
|
alias_method(:run_without_newrelic, :run)
|
@@ -23,8 +23,15 @@ module NewRelic::Agent::Instrumentation
|
|
23
23
|
with_deferred_dependency_detection { super }
|
24
24
|
end
|
25
25
|
|
26
|
-
def run(app, *args)
|
27
|
-
|
26
|
+
def run(app = nil, *args, &block)
|
27
|
+
app_or_block = app || block
|
28
|
+
run_with_tracing(app_or_block) do |wrapped|
|
29
|
+
# Rack::Builder#run for Rack v3+ supports a block, and does not
|
30
|
+
# support args. Whether a block or an app is provided, that callable
|
31
|
+
# object will be wrapped into a MiddlewareProxy instance. That
|
32
|
+
# proxy instance must then be passed to super as the app argument.
|
33
|
+
block ? super(wrapped, &nil) : super(wrapped, *args)
|
34
|
+
end
|
28
35
|
end
|
29
36
|
|
30
37
|
def use(middleware_class, *args, &blk)
|
@@ -9,16 +9,28 @@ module NewRelic::Agent::Instrumentation
|
|
9
9
|
::Redis::Client.class_eval do
|
10
10
|
include NewRelic::Agent::Instrumentation::Redis
|
11
11
|
|
12
|
-
|
12
|
+
if method_defined?(:call_v)
|
13
|
+
alias_method(:call_v_without_new_relic, :call_v)
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
def call_v(*args, &block)
|
16
|
+
call_with_tracing(args[0]) { call_v_without_new_relic(*args, &block) }
|
17
|
+
end
|
16
18
|
end
|
17
19
|
|
18
|
-
|
20
|
+
if method_defined?(:call)
|
21
|
+
alias_method(:call_without_new_relic, :call)
|
19
22
|
|
20
|
-
|
21
|
-
|
23
|
+
def call(*args, &block)
|
24
|
+
call_with_tracing(args[0]) { call_without_new_relic(*args, &block) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
if method_defined?(:call_pipeline)
|
29
|
+
alias_method(:call_pipeline_without_new_relic, :call_pipeline)
|
30
|
+
|
31
|
+
def call_pipeline(*args, &block)
|
32
|
+
call_pipeline_with_tracing(args[0]) { call_pipeline_without_new_relic(*args, &block) }
|
33
|
+
end
|
22
34
|
end
|
23
35
|
|
24
36
|
alias_method(:connect_without_new_relic, :connect)
|
@@ -0,0 +1,17 @@
|
|
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::Agent::Instrumentation::Redis
|
6
|
+
class Constants
|
7
|
+
PRODUCT_NAME = 'Redis'
|
8
|
+
CONNECT = 'connect'
|
9
|
+
UNKNOWN = 'unknown'
|
10
|
+
LOCALHOST = 'localhost'
|
11
|
+
MULTI_OPERATION = 'multi'
|
12
|
+
PIPELINE_OPERATION = 'pipeline'
|
13
|
+
HAS_REDIS_CLIENT = defined?(::Redis) &&
|
14
|
+
Gem::Version.new(::Redis::VERSION) >= Gem::Version.new('5.0.0') &&
|
15
|
+
!!defined?(::RedisClient)
|
16
|
+
end
|
17
|
+
end
|
@@ -2,42 +2,48 @@
|
|
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 'constants'
|
6
|
+
|
5
7
|
module NewRelic::Agent::Instrumentation
|
6
8
|
module Redis
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
LOCALHOST = "localhost"
|
11
|
-
MULTI_OPERATION = 'multi'
|
12
|
-
PIPELINE_OPERATION = 'pipeline'
|
9
|
+
def connect_with_tracing
|
10
|
+
with_tracing(Constants::CONNECT, database: db) { yield }
|
11
|
+
end
|
13
12
|
|
14
13
|
def call_with_tracing(command, &block)
|
15
14
|
operation = command[0]
|
16
15
|
statement = ::NewRelic::Agent::Datastores::Redis.format_command(command)
|
17
16
|
|
18
|
-
with_tracing(operation, statement) { yield }
|
17
|
+
with_tracing(operation, statement: statement, database: db) { yield }
|
19
18
|
end
|
20
19
|
|
20
|
+
# Used for Redis 4.x and 3.x
|
21
21
|
def call_pipeline_with_tracing(pipeline)
|
22
|
-
operation = pipeline.is_a?(::Redis::Pipeline::Multi) ? MULTI_OPERATION : PIPELINE_OPERATION
|
22
|
+
operation = pipeline.is_a?(::Redis::Pipeline::Multi) ? Constants::MULTI_OPERATION : Constants::PIPELINE_OPERATION
|
23
23
|
statement = ::NewRelic::Agent::Datastores::Redis.format_pipeline_commands(pipeline.commands)
|
24
24
|
|
25
|
-
with_tracing(operation, statement) { yield }
|
25
|
+
with_tracing(operation, statement: statement, database: db) { yield }
|
26
26
|
end
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
# Used for Redis 5.x+
|
29
|
+
def call_pipelined_with_tracing(pipeline)
|
30
|
+
operation = pipeline.flatten.include?('MULTI') ? Constants::MULTI_OPERATION : Constants::PIPELINE_OPERATION
|
31
|
+
statement = ::NewRelic::Agent::Datastores::Redis.format_pipeline_commands(pipeline)
|
32
|
+
|
33
|
+
# call_pipelined isn't invoked on the client object, so use client.db to
|
34
|
+
# access the client instance var on self
|
35
|
+
with_tracing(operation, statement: statement, database: client.db) { yield }
|
30
36
|
end
|
31
37
|
|
32
38
|
private
|
33
39
|
|
34
|
-
def with_tracing(operation, statement
|
40
|
+
def with_tracing(operation, statement: nil, database: nil)
|
35
41
|
segment = NewRelic::Agent::Tracer.start_datastore_segment(
|
36
|
-
product: PRODUCT_NAME,
|
42
|
+
product: Constants::PRODUCT_NAME,
|
37
43
|
operation: operation,
|
38
44
|
host: _nr_hostname,
|
39
45
|
port_path_or_id: _nr_port_path_or_id,
|
40
|
-
database_name:
|
46
|
+
database_name: database
|
41
47
|
)
|
42
48
|
begin
|
43
49
|
segment.notice_nosql_statement(statement) if statement
|
@@ -48,17 +54,21 @@ module NewRelic::Agent::Instrumentation
|
|
48
54
|
end
|
49
55
|
|
50
56
|
def _nr_hostname
|
51
|
-
|
57
|
+
_nr_client.path ? Constants::LOCALHOST : _nr_client.host
|
52
58
|
rescue => e
|
53
59
|
NewRelic::Agent.logger.debug("Failed to retrieve Redis host: #{e}")
|
54
|
-
UNKNOWN
|
60
|
+
Constants::UNKNOWN
|
55
61
|
end
|
56
62
|
|
57
63
|
def _nr_port_path_or_id
|
58
|
-
|
64
|
+
_nr_client.path || _nr_client.port
|
59
65
|
rescue => e
|
60
66
|
NewRelic::Agent.logger.debug("Failed to retrieve Redis port_path_or_id: #{e}")
|
61
|
-
UNKNOWN
|
67
|
+
Constants::UNKNOWN
|
68
|
+
end
|
69
|
+
|
70
|
+
def _nr_client
|
71
|
+
@nr_client ||= self.is_a?(::Redis::Client) ? self : client
|
62
72
|
end
|
63
73
|
end
|
64
74
|
end
|
@@ -0,0 +1,16 @@
|
|
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::Agent::Instrumentation
|
6
|
+
module RedisClient
|
7
|
+
module Middleware
|
8
|
+
# This module is used to instrument Redis 5.x+
|
9
|
+
include NewRelic::Agent::Instrumentation::Redis
|
10
|
+
|
11
|
+
def call_pipelined(*args, &block)
|
12
|
+
call_pipelined_with_tracing(args[0]) { super }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -7,6 +7,12 @@ module NewRelic::Agent::Instrumentation
|
|
7
7
|
module Prepend
|
8
8
|
include NewRelic::Agent::Instrumentation::Redis
|
9
9
|
|
10
|
+
# Defined in version 5.x+
|
11
|
+
def call_v(*args, &block)
|
12
|
+
call_with_tracing(args[0]) { super }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Defined in version 4.x, 3.x
|
10
16
|
def call(*args, &block)
|
11
17
|
call_with_tracing(args[0]) { super }
|
12
18
|
end
|
@@ -7,7 +7,9 @@ require 'new_relic/agent/datastores/redis'
|
|
7
7
|
|
8
8
|
require_relative 'redis/instrumentation'
|
9
9
|
require_relative 'redis/chain'
|
10
|
+
require_relative 'redis/constants'
|
10
11
|
require_relative 'redis/prepend'
|
12
|
+
require_relative 'redis/middleware'
|
11
13
|
|
12
14
|
DependencyDetection.defer do
|
13
15
|
# Why not :redis? newrelic-redis used that name, so avoid conflicting
|
@@ -29,6 +31,10 @@ DependencyDetection.defer do
|
|
29
31
|
|
30
32
|
executes do
|
31
33
|
NewRelic::Agent.logger.info('Installing Redis Instrumentation')
|
34
|
+
if NewRelic::Agent::Instrumentation::Redis::Constants::HAS_REDIS_CLIENT
|
35
|
+
::RedisClient.register(NewRelic::Agent::Instrumentation::RedisClient::Middleware)
|
36
|
+
end
|
37
|
+
|
32
38
|
if use_prepend?
|
33
39
|
prepend_instrument ::Redis::Client, NewRelic::Agent::Instrumentation::Redis::Prepend
|
34
40
|
else
|
@@ -0,0 +1,20 @@
|
|
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::Agent::Instrumentation::Sidekiq
|
6
|
+
class Client
|
7
|
+
include Sidekiq::ClientMiddleware if defined?(Sidekiq::ClientMiddleware)
|
8
|
+
|
9
|
+
def call(_worker_class, job, *_)
|
10
|
+
job[NewRelic::NEWRELIC_KEY] ||= distributed_tracing_headers if ::NewRelic::Agent.config[:'distributed_tracing.enabled']
|
11
|
+
yield
|
12
|
+
end
|
13
|
+
|
14
|
+
def distributed_tracing_headers
|
15
|
+
headers = {}
|
16
|
+
::NewRelic::Agent::DistributedTracing.insert_distributed_trace_headers(headers)
|
17
|
+
headers
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# This file is distributed under New Relic's license terms.
|
2
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
# TODO: remove this class once Sidekiq v6 is no longer supported.
|
6
|
+
# Delayed extensions are disabled by default in Sidekiq 5 and 6 and
|
7
|
+
# were removed entirely in Sidekiq 7.
|
8
|
+
#
|
9
|
+
# see https://github.com/mperham/sidekiq/issues/5076 for the discussion
|
10
|
+
# of the removal, which includes mentions of alternatives
|
11
|
+
if defined?(Sidekiq::VERSION) && Sidekiq::VERSION < '7.0.0'
|
12
|
+
class Sidekiq::Extensions::DelayedClass
|
13
|
+
def newrelic_trace_args(msg, queue)
|
14
|
+
(target, method_name, _args) = if YAML.respond_to?(:unsafe_load)
|
15
|
+
YAML.unsafe_load(msg['args'][0])
|
16
|
+
else
|
17
|
+
YAML.load(msg['args'][0])
|
18
|
+
end
|
19
|
+
|
20
|
+
{
|
21
|
+
:name => method_name,
|
22
|
+
:class_name => target.name,
|
23
|
+
:category => 'OtherTransaction/SidekiqJob'
|
24
|
+
}
|
25
|
+
rescue => e
|
26
|
+
NewRelic::Agent.logger.error("Failure during deserializing YAML for Sidekiq::Extensions::DelayedClass", e)
|
27
|
+
NewRelic::Agent::Instrumentation::Sidekiq::Server.default_trace_args(msg)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,37 @@
|
|
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::Agent::Instrumentation::Sidekiq
|
6
|
+
class Server
|
7
|
+
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
|
8
|
+
include Sidekiq::ServerMiddleware if defined?(Sidekiq::ServerMiddleware)
|
9
|
+
|
10
|
+
# Client middleware has additional parameters, and our tests use the
|
11
|
+
# middleware client-side to work inline.
|
12
|
+
def call(worker, msg, queue, *_)
|
13
|
+
trace_args = if worker.respond_to?(:newrelic_trace_args)
|
14
|
+
worker.newrelic_trace_args(msg, queue)
|
15
|
+
else
|
16
|
+
self.class.default_trace_args(msg)
|
17
|
+
end
|
18
|
+
trace_headers = msg.delete(NewRelic::NEWRELIC_KEY)
|
19
|
+
|
20
|
+
perform_action_with_newrelic_trace(trace_args) do
|
21
|
+
NewRelic::Agent::Transaction.merge_untrusted_agent_attributes(msg['args'], :'job.sidekiq.args',
|
22
|
+
NewRelic::Agent::AttributeFilter::DST_NONE)
|
23
|
+
|
24
|
+
::NewRelic::Agent::DistributedTracing::accept_distributed_trace_headers(trace_headers, "Other") if ::NewRelic::Agent.config[:'distributed_tracing.enabled']
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.default_trace_args(msg)
|
30
|
+
{
|
31
|
+
:name => 'perform',
|
32
|
+
:class_name => msg['class'],
|
33
|
+
:category => 'OtherTransaction/SidekiqJob'
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,6 +1,9 @@
|
|
1
1
|
# This file is distributed under New Relic's license terms.
|
2
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
3
3
|
# frozen_string_literal: true
|
4
|
+
require_relative 'sidekiq/client'
|
5
|
+
require_relative 'sidekiq/server'
|
6
|
+
require_relative 'sidekiq/extensions/delayed_class'
|
4
7
|
|
5
8
|
DependencyDetection.defer do
|
6
9
|
@name = :sidekiq
|
@@ -14,83 +17,18 @@ DependencyDetection.defer do
|
|
14
17
|
end
|
15
18
|
|
16
19
|
executes do
|
17
|
-
module NewRelic::SidekiqInstrumentation
|
18
|
-
class Server
|
19
|
-
include NewRelic::Agent::Instrumentation::ControllerInstrumentation
|
20
|
-
|
21
|
-
# Client middleware has additional parameters, and our tests use the
|
22
|
-
# middleware client-side to work inline.
|
23
|
-
def call(worker, msg, queue, *_)
|
24
|
-
trace_args = if worker.respond_to?(:newrelic_trace_args)
|
25
|
-
worker.newrelic_trace_args(msg, queue)
|
26
|
-
else
|
27
|
-
self.class.default_trace_args(msg)
|
28
|
-
end
|
29
|
-
trace_headers = msg.delete(NewRelic::NEWRELIC_KEY)
|
30
|
-
|
31
|
-
perform_action_with_newrelic_trace(trace_args) do
|
32
|
-
NewRelic::Agent::Transaction.merge_untrusted_agent_attributes(msg['args'], :'job.sidekiq.args',
|
33
|
-
NewRelic::Agent::AttributeFilter::DST_NONE)
|
34
|
-
|
35
|
-
::NewRelic::Agent::DistributedTracing::accept_distributed_trace_headers(trace_headers, "Other") if ::NewRelic::Agent.config[:'distributed_tracing.enabled']
|
36
|
-
yield
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.default_trace_args(msg)
|
41
|
-
{
|
42
|
-
:name => 'perform',
|
43
|
-
:class_name => msg['class'],
|
44
|
-
:category => 'OtherTransaction/SidekiqJob'
|
45
|
-
}
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
class Client
|
50
|
-
def call(_worker_class, job, *_)
|
51
|
-
job[NewRelic::NEWRELIC_KEY] ||= distributed_tracing_headers if ::NewRelic::Agent.config[:'distributed_tracing.enabled']
|
52
|
-
yield
|
53
|
-
end
|
54
|
-
|
55
|
-
def distributed_tracing_headers
|
56
|
-
headers = {}
|
57
|
-
::NewRelic::Agent::DistributedTracing.insert_distributed_trace_headers(headers)
|
58
|
-
headers
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
class Sidekiq::Extensions::DelayedClass
|
64
|
-
def newrelic_trace_args(msg, queue)
|
65
|
-
(target, method_name, _args) = if YAML.respond_to?(:unsafe_load)
|
66
|
-
YAML.unsafe_load(msg['args'][0])
|
67
|
-
else
|
68
|
-
YAML.load(msg['args'][0])
|
69
|
-
end
|
70
|
-
|
71
|
-
{
|
72
|
-
:name => method_name,
|
73
|
-
:class_name => target.name,
|
74
|
-
:category => 'OtherTransaction/SidekiqJob'
|
75
|
-
}
|
76
|
-
rescue => e
|
77
|
-
NewRelic::Agent.logger.error("Failure during deserializing YAML for Sidekiq::Extensions::DelayedClass", e)
|
78
|
-
NewRelic::SidekiqInstrumentation::Server.default_trace_args(msg)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
20
|
Sidekiq.configure_client do |config|
|
83
21
|
config.client_middleware do |chain|
|
84
|
-
chain.add(NewRelic::
|
22
|
+
chain.add(NewRelic::Agent::Instrumentation::Sidekiq::Client)
|
85
23
|
end
|
86
24
|
end
|
87
25
|
|
88
26
|
Sidekiq.configure_server do |config|
|
89
27
|
config.client_middleware do |chain|
|
90
|
-
chain.add(NewRelic::
|
28
|
+
chain.add(NewRelic::Agent::Instrumentation::Sidekiq::Client)
|
91
29
|
end
|
92
30
|
config.server_middleware do |chain|
|
93
|
-
chain.add(NewRelic::
|
31
|
+
chain.add(NewRelic::Agent::Instrumentation::Sidekiq::Server)
|
94
32
|
end
|
95
33
|
|
96
34
|
if config.respond_to?(:error_handlers)
|
@@ -113,7 +51,5 @@ DependencyDetection.defer do
|
|
113
51
|
:deprecated_sidekiq_version,
|
114
52
|
deprecation_msg
|
115
53
|
)
|
116
|
-
|
117
|
-
::NewRelic::Agent.record_metric("Supportability/Deprecated/Sidekiq", 1)
|
118
54
|
end
|
119
55
|
end
|
@@ -106,7 +106,7 @@ module NewRelic
|
|
106
106
|
klass = object.singleton_class? ? klassify_singleton(object) : object
|
107
107
|
name = klass.name || '(Anonymous)'
|
108
108
|
is_class_method = false
|
109
|
-
method = if klass.instance_methods.include?(method_name)
|
109
|
+
method = if (klass.instance_methods + klass.private_instance_methods).include?(method_name)
|
110
110
|
klass.instance_method(method_name)
|
111
111
|
else
|
112
112
|
is_class_method = true
|
@@ -34,7 +34,7 @@ module NewRelic
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def filter_using_rails(params, filters)
|
37
|
-
return params
|
37
|
+
return params unless rails_filter_class?
|
38
38
|
|
39
39
|
pre_filtered_params = filter_rails_request_parameters(params)
|
40
40
|
RAILS_FILTER_CLASS.new(filters).filter(pre_filtered_params)
|
@@ -60,6 +60,12 @@ module NewRelic
|
|
60
60
|
result.delete("action")
|
61
61
|
result
|
62
62
|
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def rails_filter_class?
|
67
|
+
defined?(RAILS_FILTER_CLASS) && !RAILS_FILTER_CLASS.nil?
|
68
|
+
end
|
63
69
|
end
|
64
70
|
end
|
65
71
|
end
|
data/lib/new_relic/constants.rb
CHANGED
@@ -27,6 +27,8 @@ module NewRelic
|
|
27
27
|
TRACEPARENT_KEY = "traceparent"
|
28
28
|
TRACESTATE_KEY = "tracestate"
|
29
29
|
|
30
|
+
STANDARD_OUT = 'STDOUT'
|
31
|
+
|
30
32
|
HTTP_TRACEPARENT_KEY = "HTTP_#{TRACEPARENT_KEY.upcase}"
|
31
33
|
HTTP_TRACESTATE_KEY = "HTTP_#{TRACESTATE_KEY.upcase}"
|
32
34
|
HTTP_NEWRELIC_KEY = "HTTP_#{NEWRELIC_KEY.upcase}"
|
@@ -62,7 +62,7 @@ module NewRelic
|
|
62
62
|
File.join(instrumentation_path, app.to_s, '*.rb')
|
63
63
|
@instrumentation_files.each { |pattern| load_instrumentation_files(pattern) }
|
64
64
|
DependencyDetection.detect!
|
65
|
-
|
65
|
+
ruby_deprecation
|
66
66
|
rails_32_deprecation
|
67
67
|
::NewRelic::Agent.logger.info("Finished instrumentation")
|
68
68
|
end
|
@@ -79,14 +79,12 @@ module NewRelic
|
|
79
79
|
:deprecated_rails_version,
|
80
80
|
deprecation_msg
|
81
81
|
)
|
82
|
-
|
83
|
-
::NewRelic::Agent.record_metric("Supportability/Deprecated/Rails32", 1)
|
84
82
|
end
|
85
83
|
|
86
|
-
def
|
87
|
-
return unless RUBY_VERSION
|
84
|
+
def ruby_deprecation
|
85
|
+
return unless RUBY_VERSION < '2.4.0'
|
88
86
|
|
89
|
-
deprecation_msg = 'The Ruby Agent is dropping support for
|
87
|
+
deprecation_msg = 'The Ruby Agent is dropping support for Rubies below 2.4 ' \
|
90
88
|
'in version 9.0.0. Please upgrade your Ruby version to continue receiving support. ' \
|
91
89
|
|
92
90
|
::NewRelic::Agent.logger.log_once(
|
@@ -94,8 +92,6 @@ module NewRelic
|
|
94
92
|
:deprecated_ruby_version,
|
95
93
|
deprecation_msg
|
96
94
|
)
|
97
|
-
|
98
|
-
::NewRelic::Agent.record_metric("Supportability/Deprecated/Ruby22", 1)
|
99
95
|
end
|
100
96
|
|
101
97
|
include Instrumentation
|