tingyun_rpm 1.4.2 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +0 -0
- data/lib/ting_yun/agent.rb +7 -1
- data/lib/ting_yun/agent/collector/error_collector.rb +103 -25
- data/lib/ting_yun/agent/collector/error_collector/error_trace_array.rb +2 -0
- data/lib/ting_yun/agent/collector/error_collector/noticed_error.rb +20 -13
- data/lib/ting_yun/agent/collector/transaction_sampler.rb +4 -1
- data/lib/ting_yun/agent/collector/transaction_sampler/class_method.rb +4 -4
- data/lib/ting_yun/agent/cross_app/cross_app_tracing.rb +1 -3
- data/lib/ting_yun/agent/instance_methods/container_data_manager.rb +6 -0
- data/lib/ting_yun/agent/method_tracer_helpers.rb +6 -4
- data/lib/ting_yun/agent/transaction.rb +15 -15
- data/lib/ting_yun/agent/transaction/apdex.rb +1 -1
- data/lib/ting_yun/agent/transaction/class_method.rb +14 -17
- data/lib/ting_yun/agent/transaction/exceptions.rb +19 -6
- data/lib/ting_yun/agent/transaction/instance_method.rb +8 -4
- data/lib/ting_yun/agent/transaction/trace.rb +23 -4
- data/lib/ting_yun/agent/transaction/trace_node.rb +26 -6
- data/lib/ting_yun/agent/transaction/traced_method_stack.rb +2 -2
- data/lib/ting_yun/agent/transaction/transaction_sample_builder.rb +17 -8
- data/lib/ting_yun/configuration/default_source.rb +22 -1
- data/lib/ting_yun/http/abstract_request.rb +23 -0
- data/lib/ting_yun/http/curb_wrappers.rb +76 -0
- data/lib/ting_yun/http/excon_wrappers.rb +81 -0
- data/lib/ting_yun/http/http_client_request.rb +2 -2
- data/lib/ting_yun/http/net_http_request.rb +2 -2
- data/lib/ting_yun/http/typhoeus_wrappers.rb +88 -0
- data/lib/ting_yun/instrumentation/bunny.rb +3 -3
- data/lib/ting_yun/instrumentation/curb.rb +191 -0
- data/lib/ting_yun/instrumentation/excon.rb +131 -0
- data/lib/ting_yun/instrumentation/grape.rb +4 -2
- data/lib/ting_yun/instrumentation/kafka.rb +3 -3
- data/lib/ting_yun/instrumentation/memcached.rb +1 -1
- data/lib/ting_yun/instrumentation/middleware_proxy.rb +17 -1
- data/lib/ting_yun/instrumentation/middleware_tracing.rb +1 -1
- data/lib/ting_yun/instrumentation/mongo_command_log_subscriber.rb +1 -0
- data/lib/ting_yun/instrumentation/net.rb +24 -24
- data/lib/ting_yun/instrumentation/rack.rb +10 -10
- data/lib/ting_yun/instrumentation/rails3/action_controller.rb +1 -1
- data/lib/ting_yun/instrumentation/rake.rb +8 -4
- data/lib/ting_yun/instrumentation/support/action_controller_subscriber.rb +1 -1
- data/lib/ting_yun/instrumentation/support/action_view_subscriber.rb +2 -2
- data/lib/ting_yun/instrumentation/support/active_record_subscriber.rb +2 -2
- data/lib/ting_yun/instrumentation/support/controller_instrumentation.rb +3 -3
- data/lib/ting_yun/instrumentation/support/external_error.rb +4 -4
- data/lib/ting_yun/instrumentation/support/external_helper.rb +6 -1
- data/lib/ting_yun/instrumentation/thrift.rb +1 -1
- data/lib/ting_yun/instrumentation/typhoeus.rb +75 -0
- data/lib/ting_yun/support/exception.rb +2 -0
- data/lib/ting_yun/support/http_clients/uri_util.rb +12 -7
- data/lib/ting_yun/ting_yun_service.rb +1 -1
- data/lib/ting_yun/ting_yun_service/upload_service.rb +15 -3
- data/lib/ting_yun/version.rb +2 -2
- metadata +9 -3
- data/lib/ting_yun/http/generic_request.rb +0 -8
@@ -0,0 +1,76 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'ting_yun/http/abstract_request'
|
3
|
+
|
4
|
+
module TingYun
|
5
|
+
module Http
|
6
|
+
|
7
|
+
|
8
|
+
class CurbRequest
|
9
|
+
CURB = 'Curb'.freeze
|
10
|
+
LHOST = 'host'.freeze
|
11
|
+
UHOST = 'Host'.freeze
|
12
|
+
|
13
|
+
def initialize( curlobj )
|
14
|
+
@curlobj = curlobj
|
15
|
+
end
|
16
|
+
|
17
|
+
def type
|
18
|
+
CURB
|
19
|
+
end
|
20
|
+
|
21
|
+
def from
|
22
|
+
"curb%2Fhttp"
|
23
|
+
end
|
24
|
+
|
25
|
+
def host_from_header
|
26
|
+
self[LHOST] || self[UHOST]
|
27
|
+
end
|
28
|
+
|
29
|
+
def host
|
30
|
+
host_from_header || self.uri.host
|
31
|
+
end
|
32
|
+
|
33
|
+
def method
|
34
|
+
@curlobj._ty_http_verb
|
35
|
+
end
|
36
|
+
|
37
|
+
def []( key )
|
38
|
+
@curlobj.headers[ key ]
|
39
|
+
end
|
40
|
+
|
41
|
+
def []=( key, value )
|
42
|
+
@curlobj.headers[ key ] = value
|
43
|
+
end
|
44
|
+
|
45
|
+
def uri
|
46
|
+
@uri ||= TingYun::Agent::HTTPClients::URIUtil.parse_and_normalize_url(@curlobj.url)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
class CurbResponse < AbstractRequest
|
52
|
+
def initialize(curlobj)
|
53
|
+
@headers = {}
|
54
|
+
@curlobj = curlobj
|
55
|
+
end
|
56
|
+
|
57
|
+
def [](key)
|
58
|
+
@headers[ key.downcase ]
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_hash
|
62
|
+
@headers.dup
|
63
|
+
end
|
64
|
+
|
65
|
+
def append_header_data( data )
|
66
|
+
key, value = data.split( /:\s*/, 2 )
|
67
|
+
@headers[ key.downcase ] = value
|
68
|
+
@curlobj._ty_header_str ||= ''
|
69
|
+
@curlobj._ty_header_str << data
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'ting_yun/http/abstract_request'
|
3
|
+
|
4
|
+
module TingYun
|
5
|
+
module Http
|
6
|
+
|
7
|
+
class ExconHTTPResponse
|
8
|
+
|
9
|
+
def initialize(response)
|
10
|
+
@response = response
|
11
|
+
# Since HTTP headers are case-insensitive, we normalize all of them to
|
12
|
+
# upper case here, and then also in our [](key) implementation.
|
13
|
+
@normalized_headers = {}
|
14
|
+
headers = response.respond_to?(:headers) ? response.headers : response[:headers]
|
15
|
+
(headers || {}).each do |key, val|
|
16
|
+
@normalized_headers[key.upcase] = val
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def [](key)
|
22
|
+
@normalized_headers[key.upcase]
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_hash
|
26
|
+
@normalized_headers.dup
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class ExconHTTPRequest < AbstractRequest
|
31
|
+
attr_reader :method
|
32
|
+
|
33
|
+
EXCON = "Excon".freeze
|
34
|
+
LHOST = 'host'.freeze
|
35
|
+
UHOST = 'Host'.freeze
|
36
|
+
COLON = ':'.freeze
|
37
|
+
|
38
|
+
def initialize(datum)
|
39
|
+
@datum = datum
|
40
|
+
|
41
|
+
@method = @datum[:method].to_s.upcase
|
42
|
+
@scheme = @datum[:scheme]
|
43
|
+
@port = @datum[:port]
|
44
|
+
@path = @datum[:path]
|
45
|
+
end
|
46
|
+
|
47
|
+
def type
|
48
|
+
EXCON
|
49
|
+
end
|
50
|
+
|
51
|
+
def from
|
52
|
+
"excon%2Fhttp"
|
53
|
+
end
|
54
|
+
|
55
|
+
def host_from_header
|
56
|
+
headers = @datum[:headers]
|
57
|
+
if hostname = (headers[LHOST] || headers[UHOST])
|
58
|
+
hostname.split(COLON).first
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def host
|
63
|
+
host_from_header || @datum[:host]
|
64
|
+
end
|
65
|
+
|
66
|
+
def [](key)
|
67
|
+
@datum[:headers][key]
|
68
|
+
end
|
69
|
+
|
70
|
+
def []=(key, value)
|
71
|
+
@datum[:headers] ||= {}
|
72
|
+
@datum[:headers][key] = value
|
73
|
+
end
|
74
|
+
|
75
|
+
def uri
|
76
|
+
URI.parse("#{@scheme}://#{host}:#{@port}#{@path}")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require 'ting_yun/http/
|
1
|
+
require 'ting_yun/http/abstract_request'
|
2
2
|
module TingYun
|
3
3
|
module Http
|
4
|
-
class HttpClientRequest <
|
4
|
+
class HttpClientRequest < AbstractRequest
|
5
5
|
attr_reader :method, :header
|
6
6
|
|
7
7
|
def initialize(proxy, *args, &block)
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require 'ting_yun/http/
|
1
|
+
require 'ting_yun/http/abstract_request'
|
2
2
|
module TingYun
|
3
3
|
module Http
|
4
|
-
class NetHttpRequest <
|
4
|
+
class NetHttpRequest < AbstractRequest
|
5
5
|
def initialize(connection, request)
|
6
6
|
@connection = connection
|
7
7
|
@request = request
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'ting_yun/http/abstract_request'
|
3
|
+
|
4
|
+
module TingYun
|
5
|
+
module Http
|
6
|
+
|
7
|
+
class TyphoeusHTTPResponse
|
8
|
+
def initialize(response)
|
9
|
+
@response = response
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](key)
|
13
|
+
unless headers.nil?
|
14
|
+
result = headers[key]
|
15
|
+
|
16
|
+
# Typhoeus 0.5.3 has a bug where asking the headers hash for a
|
17
|
+
# non-existent header will return the hash itself, not what we want.
|
18
|
+
result == headers ? nil : result
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_hash
|
23
|
+
hash = {}
|
24
|
+
headers.each do |(k,v)|
|
25
|
+
hash[k] = v
|
26
|
+
end
|
27
|
+
hash
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def headers
|
33
|
+
@response.headers
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class TyphoeusHTTPRequest < AbstractRequest
|
38
|
+
def initialize(request)
|
39
|
+
@request = request
|
40
|
+
@uri = case request.url
|
41
|
+
when ::URI then request.url
|
42
|
+
else TingYun::Agent::HTTPClients::URIUtil.parse_and_normalize_url(request.url)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
TYPHOEUS = "Typhoeus".freeze
|
47
|
+
|
48
|
+
def type
|
49
|
+
TYPHOEUS
|
50
|
+
end
|
51
|
+
def from
|
52
|
+
"typhoeus%2Fhttp"
|
53
|
+
end
|
54
|
+
|
55
|
+
LHOST = 'host'.freeze
|
56
|
+
UHOST = 'Host'.freeze
|
57
|
+
|
58
|
+
def host_from_header
|
59
|
+
self[LHOST] || self[UHOST]
|
60
|
+
end
|
61
|
+
|
62
|
+
def host
|
63
|
+
host_from_header || @uri.host
|
64
|
+
end
|
65
|
+
|
66
|
+
GET = 'GET'.freeze
|
67
|
+
|
68
|
+
def method
|
69
|
+
(@request.options[:method] || GET).to_s.upcase
|
70
|
+
end
|
71
|
+
|
72
|
+
def [](key)
|
73
|
+
return nil unless @request.options && @request.options[:headers]
|
74
|
+
@request.options[:headers][key]
|
75
|
+
end
|
76
|
+
|
77
|
+
def []=(key, value)
|
78
|
+
@request.options[:headers] ||= {}
|
79
|
+
@request.options[:headers][key] = value
|
80
|
+
end
|
81
|
+
|
82
|
+
def uri
|
83
|
+
@uri
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -40,7 +40,7 @@ TingYun::Support::LibraryDetection.defer do
|
|
40
40
|
metric_name << "Exchange%2F#{name}/Produce"
|
41
41
|
end
|
42
42
|
summary_metrics = TingYun::Instrumentation::Support::ExternalHelper.metrics_for_message('RabbitMQ', "#{@channel.connection.host}:#{@channel.connection.port}", 'Produce')
|
43
|
-
TingYun::Agent::
|
43
|
+
TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(summary_metrics.unshift(metric_name), {}, nil, metric_name) do
|
44
44
|
opts[:headers] = {} unless opts[:headers]
|
45
45
|
opts[:headers]["TingyunID"] = create_tingyun_id("mq") if TingYun::Agent.config[:'nbs.transaction_tracer.enabled']
|
46
46
|
TingYun::Agent.record_metric("#{metric_name}%2FByte",payload.bytesize) if payload
|
@@ -148,14 +148,14 @@ TingYun::Support::LibraryDetection.defer do
|
|
148
148
|
state = TingYun::Agent::TransactionState.tl_get
|
149
149
|
metric_name = "#{@connection.host}:#{@connection.port}%2FQueue%2F#{args[0]}/Consume"
|
150
150
|
summary_metrics = TingYun::Instrumentation::Support::ExternalHelper.metrics_for_message('RabbitMQ', "#{connection.host}:#{connection.port}", 'Consume')
|
151
|
-
TingYun::Agent::
|
151
|
+
TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(summary_metrics, {}, nil, "Message RabbitMQ/#{metric_name}") do
|
152
152
|
basic_get_without_tingyun(*args)
|
153
153
|
end
|
154
154
|
rescue =>e
|
155
155
|
TingYun::Agent.logger.error("Failed to Bunny basic_get_with_tingyun : ", e)
|
156
156
|
basic_get_without_tingyun(*args)
|
157
157
|
ensure
|
158
|
-
TingYun::Agent::Transaction.stop(state, Time.now, summary_metrics)
|
158
|
+
TingYun::Agent::Transaction.stop(state, Time.now.to_f, summary_metrics)
|
159
159
|
end
|
160
160
|
end
|
161
161
|
|
@@ -0,0 +1,191 @@
|
|
1
|
+
TingYun::Support::LibraryDetection.defer do
|
2
|
+
named :curb
|
3
|
+
|
4
|
+
CURB_MIN_VERSION = Gem::Version.new("0.8.1")
|
5
|
+
|
6
|
+
depends_on do
|
7
|
+
defined?(::Curl) && defined?(::Curl::CURB_VERSION) &&
|
8
|
+
Gem::Version.new(::Curl::CURB_VERSION) >= CURB_MIN_VERSION
|
9
|
+
end
|
10
|
+
|
11
|
+
executes do
|
12
|
+
::TingYun::Agent.logger.info 'Installing Curb instrumentation'
|
13
|
+
require 'ting_yun/agent/cross_app/cross_app_tracing'
|
14
|
+
require 'ting_yun/agent/method_tracer_helpers'
|
15
|
+
require 'ting_yun/http/curb_wrappers'
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
executes do
|
21
|
+
class Curl::Easy
|
22
|
+
|
23
|
+
attr_accessor :_ty_instrumented,
|
24
|
+
:_ty_http_verb,
|
25
|
+
:_ty_header_str,
|
26
|
+
:_ty_original_on_header,
|
27
|
+
:_ty_original_on_complete,
|
28
|
+
:_ty_serial
|
29
|
+
|
30
|
+
# We have to hook these three methods separately, as they don't use
|
31
|
+
# Curl::Easy#http
|
32
|
+
def http_head_with_tingyun(*args, &blk)
|
33
|
+
self._ty_http_verb = :HEAD
|
34
|
+
http_head_without_tingyun(*args, &blk)
|
35
|
+
end
|
36
|
+
alias_method :http_head_without_tingyun, :http_head
|
37
|
+
alias_method :http_head, :http_head_with_tingyun
|
38
|
+
|
39
|
+
def http_post_with_tingyun(*args, &blk)
|
40
|
+
self._ty_http_verb = :POST
|
41
|
+
http_post_without_tingyun(*args, &blk)
|
42
|
+
end
|
43
|
+
alias_method :http_post_without_tingyun, :http_post
|
44
|
+
alias_method :http_post, :http_post_with_tingyun
|
45
|
+
|
46
|
+
def http_put_with_tingyun(*args, &blk)
|
47
|
+
self._ty_http_verb = :PUT
|
48
|
+
http_put_without_tingyun(*args, &blk)
|
49
|
+
end
|
50
|
+
alias_method :http_put_without_tingyun, :http_put
|
51
|
+
alias_method :http_put, :http_put_with_tingyun
|
52
|
+
|
53
|
+
|
54
|
+
# Hook the #http method to set the verb.
|
55
|
+
def http_with_tingyun( verb )
|
56
|
+
self._ty_http_verb = verb.to_s.upcase
|
57
|
+
http_without_tingyun( verb )
|
58
|
+
end
|
59
|
+
|
60
|
+
alias_method :http_without_tingyun, :http
|
61
|
+
alias_method :http, :http_with_tingyun
|
62
|
+
|
63
|
+
|
64
|
+
# Hook the #perform method to mark the request as non-parallel.
|
65
|
+
def perform_with_tingyun
|
66
|
+
self._ty_serial = true
|
67
|
+
perform_without_tingyun
|
68
|
+
end
|
69
|
+
|
70
|
+
alias_method :perform_without_tingyun, :perform
|
71
|
+
alias_method :perform, :perform_with_tingyun
|
72
|
+
|
73
|
+
# We override this method in order to ensure access to header_str even
|
74
|
+
# though we use an on_header callback
|
75
|
+
def header_str_with_tingyun
|
76
|
+
if self._ty_serial
|
77
|
+
self._ty_header_str
|
78
|
+
else
|
79
|
+
# Since we didn't install a header callback for a non-serial request,
|
80
|
+
# just fall back to the original implementation.
|
81
|
+
header_str_without_tingyun
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
alias_method :header_str_without_tingyun, :header_str
|
86
|
+
alias_method :header_str, :header_str_with_tingyun
|
87
|
+
end # class Curl::Easy
|
88
|
+
|
89
|
+
class Curl::Multi
|
90
|
+
|
91
|
+
|
92
|
+
# Add CAT with callbacks if the request is serial
|
93
|
+
def add_with_tingyun(curl) #THREAD_LOCAL_ACCESS
|
94
|
+
if curl.respond_to?(:_ty_serial) && curl._ty_serial
|
95
|
+
hook_pending_request(curl) if TingYun::Agent.tl_is_execution_traced?
|
96
|
+
end
|
97
|
+
|
98
|
+
return add_without_tingyun( curl )
|
99
|
+
end
|
100
|
+
|
101
|
+
alias_method :add_without_tingyun, :add
|
102
|
+
alias_method :add, :add_with_tingyun
|
103
|
+
|
104
|
+
|
105
|
+
# Trace as an External/Multiple call if the first request isn't serial.
|
106
|
+
def perform_with_tingyun(&blk)
|
107
|
+
return perform_without_tingyun if
|
108
|
+
self.requests.first &&
|
109
|
+
self.requests.first.respond_to?(:_ty_serial) &&
|
110
|
+
self.requests.first._ty_serial
|
111
|
+
|
112
|
+
TingYun::Agent::MethodTracerHelpers.trace_execution_scoped("External/Multiple/Curb::Multi/perform") do
|
113
|
+
perform_without_tingyun(&blk)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
alias_method :perform_without_tingyun, :perform
|
118
|
+
alias_method :perform, :perform_with_tingyun
|
119
|
+
|
120
|
+
|
121
|
+
# Instrument the specified +request+ (a Curl::Easy object) and set up cross-application
|
122
|
+
# tracing if it's enabled.
|
123
|
+
def hook_pending_request(request) #THREAD_LOCAL_ACCESS
|
124
|
+
wrapped_request, wrapped_response = wrap_request(request)
|
125
|
+
state = TingYun::Agent::TransactionState.tl_get
|
126
|
+
t0 = Time.now.to_f
|
127
|
+
node = TingYun::Agent::CrossAppTracing.start_trace(state, t0, wrapped_request)
|
128
|
+
|
129
|
+
unless request._ty_instrumented
|
130
|
+
install_header_callback( request, wrapped_response )
|
131
|
+
install_completion_callback( request, t0, node, wrapped_request, wrapped_response )
|
132
|
+
request._ty_instrumented = true
|
133
|
+
end
|
134
|
+
rescue => err
|
135
|
+
TingYun::Agent.logger.error("Untrapped exception", err)
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
# Create request and response adapter objects for the specified +request+
|
140
|
+
def wrap_request(request)
|
141
|
+
return TingYun::Http::CurbRequest.new(request),
|
142
|
+
TingYun::Http::CurbResponse.new(request)
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
# Install a callback that will record the response headers to enable
|
148
|
+
# CAT linking
|
149
|
+
def install_header_callback( request, wrapped_response )
|
150
|
+
original_callback = request.on_header
|
151
|
+
request._ty_original_on_header = original_callback
|
152
|
+
request._ty_header_str = ''
|
153
|
+
request.on_header do |header_data|
|
154
|
+
wrapped_response.append_header_data( header_data )
|
155
|
+
|
156
|
+
if original_callback
|
157
|
+
original_callback.call( header_data )
|
158
|
+
else
|
159
|
+
header_data.length
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
# Install a callback that will finish the trace.
|
165
|
+
def install_completion_callback( request, t0, segment, wrapped_request, wrapped_response )
|
166
|
+
original_callback = request.on_complete
|
167
|
+
request._ty_original_on_complete = original_callback
|
168
|
+
request.on_complete do |finished_request|
|
169
|
+
begin
|
170
|
+
TingYun::Agent::CrossAppTracing.finish_trace(TingYun::Agent::TransactionState.tl_get,t0, segment, wrapped_request, wrapped_response )
|
171
|
+
ensure
|
172
|
+
# Make sure the existing completion callback is run, and restore the
|
173
|
+
# on_complete callback to how it was before.
|
174
|
+
original_callback.call( finished_request ) if original_callback
|
175
|
+
remove_instrumentation_callbacks( request )
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def remove_instrumentation_callbacks( request )
|
181
|
+
request.on_complete(&request._ty_original_on_complete)
|
182
|
+
request.on_header(&request._ty_original_on_header)
|
183
|
+
request._ty_instrumented = false
|
184
|
+
end
|
185
|
+
|
186
|
+
end # class Curl::Multi
|
187
|
+
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
end
|