newrelic_rpm 6.15.0 → 7.0.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 +96 -22
- data/README.md +2 -2
- data/lib/new_relic/agent.rb +0 -6
- data/lib/new_relic/agent/autostart.rb +1 -2
- data/lib/new_relic/agent/configuration/default_source.rb +270 -104
- data/lib/new_relic/agent/configuration/manager.rb +2 -2
- data/lib/new_relic/agent/datastores/redis.rb +0 -4
- data/lib/new_relic/agent/distributed_tracing.rb +0 -66
- data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +0 -16
- data/lib/new_relic/agent/instrumentation/bunny.rb +10 -152
- data/lib/new_relic/agent/instrumentation/bunny/chain.rb +45 -0
- data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +152 -0
- data/lib/new_relic/agent/instrumentation/bunny/prepend.rb +35 -0
- data/lib/new_relic/agent/instrumentation/curb.rb +9 -241
- data/lib/new_relic/agent/instrumentation/curb/chain.rb +93 -0
- data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +222 -0
- data/lib/new_relic/agent/instrumentation/curb/prepend.rb +63 -0
- data/lib/new_relic/agent/instrumentation/delayed_job/chain.rb +38 -0
- data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +53 -0
- data/lib/new_relic/agent/instrumentation/delayed_job/prepend.rb +34 -0
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +8 -50
- data/lib/new_relic/agent/instrumentation/excon.rb +2 -1
- data/lib/new_relic/agent/instrumentation/grape.rb +13 -113
- data/lib/new_relic/agent/instrumentation/grape/chain.rb +25 -0
- data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +100 -0
- data/lib/new_relic/agent/instrumentation/grape/prepend.rb +17 -0
- data/lib/new_relic/agent/instrumentation/httpclient.rb +8 -30
- data/lib/new_relic/agent/instrumentation/httpclient/chain.rb +25 -0
- data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +38 -0
- data/lib/new_relic/agent/instrumentation/httpclient/prepend.rb +17 -0
- data/lib/new_relic/agent/instrumentation/httprb.rb +29 -0
- data/lib/new_relic/agent/instrumentation/httprb/chain.rb +22 -0
- data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +30 -0
- data/lib/new_relic/agent/instrumentation/httprb/prepend.rb +15 -0
- data/lib/new_relic/agent/instrumentation/memcache.rb +54 -69
- data/lib/new_relic/agent/instrumentation/memcache/chain.rb +16 -0
- data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +38 -121
- data/lib/new_relic/agent/instrumentation/memcache/helper.rb +56 -0
- data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +88 -0
- data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +88 -0
- data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +2 -0
- data/lib/new_relic/agent/instrumentation/mongo.rb +7 -0
- data/lib/new_relic/agent/instrumentation/net_http.rb +39 -0
- data/lib/new_relic/agent/instrumentation/net_http/chain.rb +25 -0
- data/lib/new_relic/agent/instrumentation/{net_prepend.rb → net_http/instrumentation.rb} +3 -3
- data/lib/new_relic/agent/instrumentation/net_http/prepend.rb +21 -0
- data/lib/new_relic/agent/instrumentation/padrino.rb +18 -53
- data/lib/new_relic/agent/instrumentation/padrino/chain.rb +34 -0
- data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +27 -0
- data/lib/new_relic/agent/instrumentation/padrino/prepend.rb +20 -0
- data/lib/new_relic/agent/instrumentation/rack.rb +29 -139
- data/lib/new_relic/agent/instrumentation/rack/chain.rb +57 -0
- data/lib/new_relic/agent/instrumentation/rack/helpers.rb +32 -0
- data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +73 -0
- data/lib/new_relic/agent/instrumentation/rack/prepend.rb +36 -0
- data/lib/new_relic/agent/instrumentation/rake.rb +13 -154
- data/lib/new_relic/agent/instrumentation/rake/chain.rb +25 -0
- data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +144 -0
- data/lib/new_relic/agent/instrumentation/rake/prepend.rb +14 -0
- data/lib/new_relic/agent/instrumentation/redis.rb +10 -109
- data/lib/new_relic/agent/instrumentation/redis/chain.rb +34 -0
- data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +65 -0
- data/lib/new_relic/agent/instrumentation/redis/prepend.rb +24 -0
- data/lib/new_relic/agent/instrumentation/resque.rb +8 -28
- data/lib/new_relic/agent/instrumentation/resque/chain.rb +22 -0
- data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +33 -0
- data/lib/new_relic/agent/instrumentation/resque/prepend.rb +16 -0
- data/lib/new_relic/agent/instrumentation/sinatra.rb +20 -158
- data/lib/new_relic/agent/instrumentation/sinatra/chain.rb +55 -0
- data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +29 -34
- data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +118 -0
- data/lib/new_relic/agent/instrumentation/sinatra/prepend.rb +33 -0
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +10 -89
- data/lib/new_relic/agent/instrumentation/typhoeus/chain.rb +22 -0
- data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +82 -0
- data/lib/new_relic/agent/instrumentation/typhoeus/prepend.rb +14 -0
- data/lib/new_relic/agent/new_relic_service.rb +3 -12
- data/lib/new_relic/agent/sql_sampler.rb +1 -1
- data/lib/new_relic/agent/transaction.rb +1 -4
- data/lib/new_relic/control/frameworks/rails.rb +11 -9
- data/lib/new_relic/control/instance_methods.rb +1 -0
- data/lib/new_relic/dependency_detection.rb +116 -10
- data/lib/new_relic/noticed_error.rb +1 -5
- data/lib/new_relic/supportability_helper.rb +1 -2
- data/lib/new_relic/version.rb +2 -2
- data/newrelic_rpm.gemspec +1 -1
- metadata +53 -8
- data/cert/cacert.pem +0 -1177
- data/lib/new_relic/agent/instrumentation/http.rb +0 -49
- data/lib/new_relic/agent/instrumentation/net.rb +0 -70
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under New Relic's license terms.
|
3
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
|
+
|
5
|
+
module NewRelic::Agent::Instrumentation
|
6
|
+
module Sinatra
|
7
|
+
module Chain
|
8
|
+
def self.instrument!
|
9
|
+
::Sinatra::Base.class_eval do
|
10
|
+
include ::NewRelic::Agent::Instrumentation::Sinatra::Tracer
|
11
|
+
|
12
|
+
def dispatch_with_newrelic
|
13
|
+
dispatch_with_tracing { dispatch_without_newrelic }
|
14
|
+
end
|
15
|
+
alias dispatch_without_newrelic dispatch!
|
16
|
+
alias dispatch! dispatch_with_newrelic
|
17
|
+
|
18
|
+
def process_route_with_newrelic(*args, &block)
|
19
|
+
process_route_with_tracing(*args) do
|
20
|
+
process_route_without_newrelic(*args, &block)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
alias process_route_without_newrelic process_route
|
24
|
+
alias process_route process_route_with_newrelic
|
25
|
+
|
26
|
+
def route_eval_with_newrelic(*args, &block)
|
27
|
+
route_eval_with_tracing(*args) do
|
28
|
+
route_eval_without_newrelic(*args, &block)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
alias route_eval_without_newrelic route_eval
|
32
|
+
alias route_eval route_eval_with_newrelic
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module Build
|
38
|
+
module Chain
|
39
|
+
def self.instrument!
|
40
|
+
::Sinatra::Base.class_eval do
|
41
|
+
class << self
|
42
|
+
def build_with_newrelic(*args, &block)
|
43
|
+
build_with_tracing(*args) do
|
44
|
+
build_without_newrelic(*args, &block)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
alias build_without_newrelic build
|
48
|
+
alias build build_with_newrelic
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -2,49 +2,44 @@
|
|
2
2
|
# This file is distributed under New Relic's license terms.
|
3
3
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
4
|
|
5
|
-
module NewRelic
|
6
|
-
module
|
7
|
-
module
|
8
|
-
module Sinatra
|
9
|
-
module Ignorer
|
5
|
+
module NewRelic::Agent::Instrumentation
|
6
|
+
module Sinatra
|
7
|
+
module Ignorer
|
10
8
|
|
11
|
-
|
12
|
-
|
9
|
+
def self.should_ignore?(app, type)
|
10
|
+
return false if !app.settings.respond_to?(:newrelic_ignores)
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def newrelic_ignore(*routes)
|
20
|
-
set_newrelic_ignore(:routes, *routes)
|
21
|
-
end
|
12
|
+
app.settings.newrelic_ignores[type].any? do |pattern|
|
13
|
+
pattern.match(app.request.path_info)
|
14
|
+
end
|
15
|
+
end
|
22
16
|
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
def newrelic_ignore(*routes)
|
18
|
+
set_newrelic_ignore(:routes, *routes)
|
19
|
+
end
|
26
20
|
|
27
|
-
|
28
|
-
|
29
|
-
|
21
|
+
def newrelic_ignore_apdex(*routes)
|
22
|
+
set_newrelic_ignore(:apdex, *routes)
|
23
|
+
end
|
30
24
|
|
31
|
-
|
25
|
+
def newrelic_ignore_enduser(*routes)
|
26
|
+
set_newrelic_ignore(:enduser, *routes)
|
27
|
+
end
|
32
28
|
|
33
|
-
|
34
|
-
# Important to default this in the context of the actual app
|
35
|
-
# If it's done at register time, ignores end up shared between apps.
|
36
|
-
set :newrelic_ignores, Hash.new([]) if !respond_to?(:newrelic_ignores)
|
29
|
+
private
|
37
30
|
|
38
|
-
|
39
|
-
|
31
|
+
def set_newrelic_ignore(type, *routes)
|
32
|
+
# Important to default this in the context of the actual app
|
33
|
+
# If it's done at register time, ignores end up shared between apps.
|
34
|
+
set :newrelic_ignores, Hash.new([]) if !respond_to?(:newrelic_ignores)
|
40
35
|
|
41
|
-
|
42
|
-
|
43
|
-
# exactly Sinatra's mapping of route text to regex
|
44
|
-
Array(send(:compile, r)).first
|
45
|
-
end
|
46
|
-
end
|
36
|
+
# If we call an ignore without a route, it applies to the whole app
|
37
|
+
routes = ["*"] if routes.empty?
|
47
38
|
|
39
|
+
settings.newrelic_ignores[type] += routes.map do |r|
|
40
|
+
# Ugly sending to private Base#compile, but we want to mimic
|
41
|
+
# exactly Sinatra's mapping of route text to regex
|
42
|
+
Array(send(:compile, r)).first
|
48
43
|
end
|
49
44
|
end
|
50
45
|
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under New Relic's license terms.
|
3
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
|
+
|
5
|
+
# NewRelic instrumentation for Sinatra applications. Sinatra actions will
|
6
|
+
# appear in the UI similar to controller actions, and have breakdown charts
|
7
|
+
# and transaction traces.
|
8
|
+
#
|
9
|
+
# The actions in the UI will correspond to the pattern expression used
|
10
|
+
# to match them, not directly to full URL's.
|
11
|
+
module NewRelic::Agent::Instrumentation
|
12
|
+
module Sinatra
|
13
|
+
module Tracer
|
14
|
+
include ::NewRelic::Agent::Instrumentation::ControllerInstrumentation
|
15
|
+
|
16
|
+
def self.included(clazz)
|
17
|
+
clazz.extend(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Expected method for supporting ControllerInstrumentation
|
21
|
+
def newrelic_request_headers(_)
|
22
|
+
request.env
|
23
|
+
end
|
24
|
+
|
25
|
+
def newrelic_middlewares
|
26
|
+
middlewares = [NewRelic::Rack::BrowserMonitoring]
|
27
|
+
if NewRelic::Rack::AgentHooks.needed?
|
28
|
+
middlewares << NewRelic::Rack::AgentHooks
|
29
|
+
end
|
30
|
+
middlewares
|
31
|
+
end
|
32
|
+
|
33
|
+
def build_with_tracing(*args, &block)
|
34
|
+
unless NewRelic::Agent.config[:disable_sinatra_auto_middleware]
|
35
|
+
newrelic_middlewares.each do |middleware_class|
|
36
|
+
try_to_use(self, middleware_class)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
yield
|
40
|
+
end
|
41
|
+
|
42
|
+
def try_to_use(app, clazz)
|
43
|
+
has_middleware = app.middleware.any? { |info| info[0] == clazz }
|
44
|
+
app.use(clazz) unless has_middleware
|
45
|
+
end
|
46
|
+
|
47
|
+
# Capture last route we've seen. Will set for transaction on route_eval
|
48
|
+
def process_route_with_tracing(*args)
|
49
|
+
begin
|
50
|
+
env["newrelic.last_route"] = args[0]
|
51
|
+
rescue => e
|
52
|
+
::NewRelic::Agent.logger.debug("Failed determining last route in Sinatra", e)
|
53
|
+
end
|
54
|
+
yield
|
55
|
+
end
|
56
|
+
|
57
|
+
# If a transaction name is already set, this call will tromple over it.
|
58
|
+
# This is intentional, as typically passing to a separate route is like
|
59
|
+
# an entirely separate transaction, so we pick up the new name.
|
60
|
+
#
|
61
|
+
# If we're ignored, this remains safe, since set_transaction_name
|
62
|
+
# care for the gating on the transaction's existence for us.
|
63
|
+
def route_eval_with_tracing(*args)
|
64
|
+
begin
|
65
|
+
if txn_name = TransactionNamer.transaction_name_for_route(env, request)
|
66
|
+
::NewRelic::Agent::Transaction.set_default_transaction_name(
|
67
|
+
"#{self.class.name}/#{txn_name}", :sinatra)
|
68
|
+
end
|
69
|
+
rescue => e
|
70
|
+
::NewRelic::Agent.logger.debug("Failed during route_eval to set transaction name", e)
|
71
|
+
end
|
72
|
+
yield
|
73
|
+
end
|
74
|
+
|
75
|
+
def get_request_params
|
76
|
+
begin
|
77
|
+
@request.params
|
78
|
+
rescue => e
|
79
|
+
NewRelic::Agent.logger.debug("Failed to get params from Rack request.", e)
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def dispatch_with_tracing
|
85
|
+
request_params = get_request_params
|
86
|
+
filtered_params = ::NewRelic::Agent::ParameterFiltering::apply_filters(request.env, request_params || {})
|
87
|
+
|
88
|
+
name = TransactionNamer.initial_transaction_name(request)
|
89
|
+
perform_action_with_newrelic_trace(:category => :sinatra,
|
90
|
+
:name => name,
|
91
|
+
:params => filtered_params) do
|
92
|
+
begin
|
93
|
+
yield
|
94
|
+
ensure
|
95
|
+
# Will only see an error raised if :show_exceptions is true, but
|
96
|
+
# will always see them in the env hash if they occur
|
97
|
+
had_error = env.has_key?('sinatra.error')
|
98
|
+
::NewRelic::Agent.notice_error(env['sinatra.error']) if had_error
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def do_not_trace?
|
104
|
+
Ignorer.should_ignore?(self, :routes)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Overrides ControllerInstrumentation implementation
|
108
|
+
def ignore_apdex?
|
109
|
+
Ignorer.should_ignore?(self, :apdex)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Overrides ControllerInstrumentation implementation
|
113
|
+
def ignore_enduser?
|
114
|
+
Ignorer.should_ignore?(self, :enduser)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under New Relic's license terms.
|
3
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
|
+
|
5
|
+
module NewRelic::Agent::Instrumentation
|
6
|
+
module Sinatra
|
7
|
+
module Prepend
|
8
|
+
include ::NewRelic::Agent::Instrumentation::Sinatra::Tracer
|
9
|
+
|
10
|
+
def dispatch!
|
11
|
+
dispatch_with_tracing { super }
|
12
|
+
end
|
13
|
+
|
14
|
+
def process_route(*args, &block)
|
15
|
+
process_route_with_tracing(*args) { super }
|
16
|
+
end
|
17
|
+
|
18
|
+
def route_eval(*args, &block)
|
19
|
+
route_eval_with_tracing(*args) { super }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module Build
|
24
|
+
module Prepend
|
25
|
+
include ::NewRelic::Agent::Instrumentation::Sinatra::Tracer
|
26
|
+
|
27
|
+
def build(*args, &block)
|
28
|
+
build_with_tracing(*args) { super }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -2,6 +2,10 @@
|
|
2
2
|
# This file is distributed under New Relic's license terms.
|
3
3
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
4
|
|
5
|
+
require_relative 'typhoeus/instrumentation'
|
6
|
+
require_relative 'typhoeus/chain'
|
7
|
+
require_relative 'typhoeus/prepend'
|
8
|
+
|
5
9
|
DependencyDetection.defer do
|
6
10
|
named :typhoeus
|
7
11
|
|
@@ -10,7 +14,7 @@ DependencyDetection.defer do
|
|
10
14
|
end
|
11
15
|
|
12
16
|
depends_on do
|
13
|
-
NewRelic::Agent::Instrumentation::
|
17
|
+
NewRelic::Agent::Instrumentation::Typhoeus.is_supported_version?
|
14
18
|
end
|
15
19
|
|
16
20
|
executes do
|
@@ -22,7 +26,7 @@ DependencyDetection.defer do
|
|
22
26
|
# Basic request tracing
|
23
27
|
executes do
|
24
28
|
Typhoeus.before do |request|
|
25
|
-
NewRelic::Agent::Instrumentation::
|
29
|
+
NewRelic::Agent::Instrumentation::Typhoeus.trace(request)
|
26
30
|
|
27
31
|
# Ensure that we always return a truthy value from the before block,
|
28
32
|
# otherwise Typhoeus will bail out of the instrumentation.
|
@@ -32,93 +36,10 @@ DependencyDetection.defer do
|
|
32
36
|
|
33
37
|
# Apply single TT node for Hydra requests until async support
|
34
38
|
executes do
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
name: NewRelic::Agent::Instrumentation::TyphoeusTracing::HYDRA_SEGMENT_NAME
|
40
|
-
)
|
41
|
-
|
42
|
-
instance_variable_set :@__newrelic_hydra_segment, segment
|
43
|
-
|
44
|
-
begin
|
45
|
-
run_without_newrelic(*args)
|
46
|
-
ensure
|
47
|
-
segment.finish if segment
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
alias run_without_newrelic run
|
52
|
-
alias run run_with_newrelic
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
|
58
|
-
module NewRelic
|
59
|
-
module Agent
|
60
|
-
module Instrumentation
|
61
|
-
module TyphoeusTracing
|
62
|
-
|
63
|
-
HYDRA_SEGMENT_NAME = "External/Multiple/Typhoeus::Hydra/run"
|
64
|
-
NOTICIBLE_ERROR_CLASS = "Typhoeus::Errors::TyphoeusError"
|
65
|
-
|
66
|
-
EARLIEST_VERSION = Gem::Version.new("0.5.3")
|
67
|
-
def self.is_supported_version?
|
68
|
-
Gem::Version.new(Typhoeus::VERSION) >= NewRelic::Agent::Instrumentation::TyphoeusTracing::EARLIEST_VERSION
|
69
|
-
end
|
70
|
-
|
71
|
-
def self.request_is_hydra_enabled?(request)
|
72
|
-
request.respond_to?(:hydra) && request.hydra
|
73
|
-
end
|
74
|
-
|
75
|
-
def self.response_message(response)
|
76
|
-
if response.respond_to?(:response_message)
|
77
|
-
response.response_message
|
78
|
-
elsif response.respond_to?(:return_message)
|
79
|
-
response.return_message
|
80
|
-
else
|
81
|
-
# 0.5.4 seems to have lost xxxx_message methods altogether.
|
82
|
-
"timeout"
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def self.trace(request)
|
87
|
-
state = NewRelic::Agent::Tracer.state
|
88
|
-
return unless state.is_execution_traced?
|
89
|
-
|
90
|
-
wrapped_request = ::NewRelic::Agent::HTTPClients::TyphoeusHTTPRequest.new(request)
|
91
|
-
|
92
|
-
parent = if request_is_hydra_enabled?(request)
|
93
|
-
request.hydra.instance_variable_get(:@__newrelic_hydra_segment)
|
94
|
-
end
|
95
|
-
|
96
|
-
segment = NewRelic::Agent::Tracer.start_external_request_segment(
|
97
|
-
library: wrapped_request.type,
|
98
|
-
uri: wrapped_request.uri,
|
99
|
-
procedure: wrapped_request.method,
|
100
|
-
parent: parent
|
101
|
-
)
|
102
|
-
|
103
|
-
segment.add_request_headers wrapped_request
|
104
|
-
|
105
|
-
callback = Proc.new do
|
106
|
-
wrapped_response = HTTPClients::TyphoeusHTTPResponse.new(request.response)
|
107
|
-
|
108
|
-
segment.process_response_headers wrapped_response
|
109
|
-
|
110
|
-
if request.response.code == 0
|
111
|
-
segment.notice_error NoticibleError.new NOTICIBLE_ERROR_CLASS, response_message(request.response)
|
112
|
-
end
|
113
|
-
|
114
|
-
segment.finish if segment
|
115
|
-
end
|
116
|
-
request.on_complete.unshift(callback)
|
117
|
-
|
118
|
-
rescue => e
|
119
|
-
NewRelic::Agent.logger.error("Exception during trace setup for Typhoeus request", e)
|
120
|
-
end
|
121
|
-
end
|
39
|
+
if use_prepend?
|
40
|
+
prepend_instrument Typhoeus::Hydra, NewRelic::Agent::Instrumentation::Typhoeus::Prepend
|
41
|
+
else
|
42
|
+
chain_instrument NewRelic::Agent::Instrumentation::Typhoeus::Chain
|
122
43
|
end
|
123
44
|
end
|
124
45
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under New Relic's license terms.
|
3
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
|
+
|
5
|
+
module NewRelic::Agent::Instrumentation
|
6
|
+
module Typhoeus
|
7
|
+
module Chain
|
8
|
+
def self.instrument!
|
9
|
+
::Typhoeus::Hydra.class_eval do
|
10
|
+
include NewRelic::Agent::Instrumentation::Typhoeus
|
11
|
+
|
12
|
+
def run_with_newrelic(*args)
|
13
|
+
with_tracing { run_without_newrelic(*args) }
|
14
|
+
end
|
15
|
+
|
16
|
+
alias run_without_newrelic run
|
17
|
+
alias run run_with_newrelic
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under New Relic's license terms.
|
3
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
|
+
|
5
|
+
module NewRelic
|
6
|
+
module Agent
|
7
|
+
module Instrumentation
|
8
|
+
module Typhoeus
|
9
|
+
|
10
|
+
HYDRA_SEGMENT_NAME = "External/Multiple/Typhoeus::Hydra/run"
|
11
|
+
NOTICIBLE_ERROR_CLASS = "Typhoeus::Errors::TyphoeusError"
|
12
|
+
|
13
|
+
EARLIEST_VERSION = Gem::Version.new("0.5.3")
|
14
|
+
|
15
|
+
def self.is_supported_version?
|
16
|
+
Gem::Version.new(::Typhoeus::VERSION) >= EARLIEST_VERSION
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.request_is_hydra_enabled?(request)
|
20
|
+
request.respond_to?(:hydra) && request.hydra
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.response_message(response)
|
24
|
+
if response.respond_to?(:response_message)
|
25
|
+
response.response_message
|
26
|
+
elsif response.respond_to?(:return_message)
|
27
|
+
response.return_message
|
28
|
+
else
|
29
|
+
# 0.5.4 seems to have lost xxxx_message methods altogether.
|
30
|
+
"timeout"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def with_tracing
|
35
|
+
segment = NewRelic::Agent::Tracer.start_segment name: HYDRA_SEGMENT_NAME
|
36
|
+
instance_variable_set :@__newrelic_hydra_segment, segment
|
37
|
+
begin
|
38
|
+
yield
|
39
|
+
ensure
|
40
|
+
segment.finish if segment
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.trace(request)
|
45
|
+
state = NewRelic::Agent::Tracer.state
|
46
|
+
return unless state.is_execution_traced?
|
47
|
+
|
48
|
+
wrapped_request = ::NewRelic::Agent::HTTPClients::TyphoeusHTTPRequest.new(request)
|
49
|
+
|
50
|
+
parent = if request_is_hydra_enabled?(request)
|
51
|
+
request.hydra.instance_variable_get(:@__newrelic_hydra_segment)
|
52
|
+
end
|
53
|
+
|
54
|
+
segment = NewRelic::Agent::Tracer.start_external_request_segment(
|
55
|
+
library: wrapped_request.type,
|
56
|
+
uri: wrapped_request.uri,
|
57
|
+
procedure: wrapped_request.method,
|
58
|
+
parent: parent
|
59
|
+
)
|
60
|
+
|
61
|
+
segment.add_request_headers wrapped_request
|
62
|
+
|
63
|
+
callback = Proc.new do
|
64
|
+
wrapped_response = HTTPClients::TyphoeusHTTPResponse.new(request.response)
|
65
|
+
|
66
|
+
segment.process_response_headers wrapped_response
|
67
|
+
|
68
|
+
if request.response.code == 0
|
69
|
+
segment.notice_error NoticibleError.new NOTICIBLE_ERROR_CLASS, response_message(request.response)
|
70
|
+
end
|
71
|
+
|
72
|
+
segment.finish if segment
|
73
|
+
end
|
74
|
+
request.on_complete.unshift(callback)
|
75
|
+
|
76
|
+
rescue => e
|
77
|
+
NewRelic::Agent.logger.error("Exception during trace setup for Typhoeus request", e)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|