hoss-agent 1.0.9
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 +7 -0
- data/.github/ISSUE_TEMPLATE/Bug_report.md +40 -0
- data/.github/ISSUE_TEMPLATE/Feature_request.md +17 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +60 -0
- data/.gitignore +27 -0
- data/.rspec +2 -0
- data/Dockerfile +43 -0
- data/Gemfile +105 -0
- data/LICENSE +201 -0
- data/hoss-agent.gemspec +42 -0
- data/lib/hoss-agent.rb +210 -0
- data/lib/hoss.rb +21 -0
- data/lib/hoss/agent.rb +235 -0
- data/lib/hoss/central_config.rb +184 -0
- data/lib/hoss/central_config/cache_control.rb +51 -0
- data/lib/hoss/child_durations.rb +64 -0
- data/lib/hoss/config.rb +315 -0
- data/lib/hoss/config/bytes.rb +42 -0
- data/lib/hoss/config/duration.rb +40 -0
- data/lib/hoss/config/options.rb +154 -0
- data/lib/hoss/config/regexp_list.rb +30 -0
- data/lib/hoss/config/wildcard_pattern_list.rb +54 -0
- data/lib/hoss/context.rb +64 -0
- data/lib/hoss/context/request.rb +28 -0
- data/lib/hoss/context/request/socket.rb +36 -0
- data/lib/hoss/context/request/url.rb +59 -0
- data/lib/hoss/context/response.rb +47 -0
- data/lib/hoss/context/user.rb +59 -0
- data/lib/hoss/context_builder.rb +112 -0
- data/lib/hoss/deprecations.rb +39 -0
- data/lib/hoss/error.rb +49 -0
- data/lib/hoss/error/exception.rb +70 -0
- data/lib/hoss/error/log.rb +41 -0
- data/lib/hoss/error_builder.rb +90 -0
- data/lib/hoss/event.rb +131 -0
- data/lib/hoss/instrumenter.rb +107 -0
- data/lib/hoss/internal_error.rb +23 -0
- data/lib/hoss/logging.rb +70 -0
- data/lib/hoss/metadata.rb +36 -0
- data/lib/hoss/metadata/process_info.rb +35 -0
- data/lib/hoss/metadata/service_info.rb +76 -0
- data/lib/hoss/metadata/system_info.rb +47 -0
- data/lib/hoss/metadata/system_info/container_info.rb +136 -0
- data/lib/hoss/naively_hashable.rb +38 -0
- data/lib/hoss/rails.rb +68 -0
- data/lib/hoss/railtie.rb +42 -0
- data/lib/hoss/report.rb +9 -0
- data/lib/hoss/sinatra.rb +53 -0
- data/lib/hoss/spies.rb +104 -0
- data/lib/hoss/spies/faraday.rb +106 -0
- data/lib/hoss/spies/http.rb +86 -0
- data/lib/hoss/spies/net_http.rb +101 -0
- data/lib/hoss/stacktrace.rb +33 -0
- data/lib/hoss/stacktrace/frame.rb +66 -0
- data/lib/hoss/stacktrace_builder.rb +124 -0
- data/lib/hoss/transport/base.rb +191 -0
- data/lib/hoss/transport/connection.rb +55 -0
- data/lib/hoss/transport/connection/http.rb +139 -0
- data/lib/hoss/transport/connection/proxy_pipe.rb +94 -0
- data/lib/hoss/transport/filters.rb +60 -0
- data/lib/hoss/transport/filters/hash_sanitizer.rb +77 -0
- data/lib/hoss/transport/filters/secrets_filter.rb +48 -0
- data/lib/hoss/transport/headers.rb +74 -0
- data/lib/hoss/transport/serializers.rb +113 -0
- data/lib/hoss/transport/serializers/context_serializer.rb +112 -0
- data/lib/hoss/transport/serializers/error_serializer.rb +92 -0
- data/lib/hoss/transport/serializers/event_serializer.rb +73 -0
- data/lib/hoss/transport/serializers/metadata_serializer.rb +92 -0
- data/lib/hoss/transport/serializers/report_serializer.rb +33 -0
- data/lib/hoss/transport/user_agent.rb +48 -0
- data/lib/hoss/transport/worker.rb +330 -0
- data/lib/hoss/util.rb +54 -0
- data/lib/hoss/util/inflector.rb +110 -0
- data/lib/hoss/util/lru_cache.rb +65 -0
- data/lib/hoss/util/throttle.rb +52 -0
- data/lib/hoss/version.rb +22 -0
- metadata +147 -0
data/lib/hoss/report.rb
ADDED
data/lib/hoss/sinatra.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
6
|
+
# not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
# frozen_string_literal: true
|
19
|
+
|
20
|
+
module Hoss
|
21
|
+
# Module for starting the Hoss agent and hooking into Sinatra.
|
22
|
+
module Sinatra
|
23
|
+
extend self
|
24
|
+
# Start the Hoss agent and hook into Sinatra.
|
25
|
+
#
|
26
|
+
# @param app [Sinatra::Base] A Sinatra app.
|
27
|
+
# @param config [Config, Hash] An instance of Config or a Hash config.
|
28
|
+
# @return [true, nil] true if the agent was started, nil otherwise.
|
29
|
+
def start(app, config = {})
|
30
|
+
config = Config.new(config) unless config.is_a?(Config)
|
31
|
+
configure_app(app, config)
|
32
|
+
|
33
|
+
Hoss.start(config)
|
34
|
+
Hoss.running?
|
35
|
+
rescue StandardError => e
|
36
|
+
config.logger.error format('Failed to start: %s', e.message)
|
37
|
+
config.logger.debug "Backtrace:\n" + e.backtrace.join("\n")
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def configure_app(app, config)
|
43
|
+
config.service_name ||= format_name(app.to_s)
|
44
|
+
config.framework_name ||= 'Sinatra'
|
45
|
+
config.framework_version ||= ::Sinatra::VERSION
|
46
|
+
config.__root_path ||= Dir.pwd
|
47
|
+
end
|
48
|
+
|
49
|
+
def format_name(str)
|
50
|
+
str&.gsub('::', '_')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/hoss/spies.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
6
|
+
# not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
# frozen_string_literal: true
|
19
|
+
|
20
|
+
require 'hoss/util/inflector'
|
21
|
+
|
22
|
+
module Hoss
|
23
|
+
# @api private
|
24
|
+
module Spies
|
25
|
+
# @api private
|
26
|
+
class Registration
|
27
|
+
extend Forwardable
|
28
|
+
|
29
|
+
def initialize(const_name, require_paths, spy)
|
30
|
+
@const_name = const_name
|
31
|
+
@require_paths = Array(require_paths)
|
32
|
+
@spy = spy
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_reader :const_name, :require_paths
|
36
|
+
|
37
|
+
def_delegator :@spy, :install
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.require_hooks
|
41
|
+
@require_hooks ||= {}
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.installed
|
45
|
+
@installed ||= {}
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.register(*args)
|
49
|
+
registration = Registration.new(*args)
|
50
|
+
|
51
|
+
if safe_defined?(registration.const_name)
|
52
|
+
registration.install
|
53
|
+
installed[registration.const_name] = registration
|
54
|
+
else
|
55
|
+
register_require_hook registration
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.register_require_hook(registration)
|
60
|
+
registration.require_paths.each do |path|
|
61
|
+
require_hooks[path] = registration
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.hook_into(name)
|
66
|
+
return unless (registration = require_hooks[name])
|
67
|
+
return unless safe_defined?(registration.const_name)
|
68
|
+
|
69
|
+
installed[registration.const_name] = registration
|
70
|
+
registration.install
|
71
|
+
|
72
|
+
registration.require_paths.each do |path|
|
73
|
+
require_hooks.delete path
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.safe_defined?(const_name)
|
78
|
+
Util::Inflector.safe_constantize(const_name)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
unless ENV['HOSS_SKIP_REQUIRE_PATCH'] == '1'
|
84
|
+
# @api private
|
85
|
+
module Kernel
|
86
|
+
private
|
87
|
+
|
88
|
+
alias require_without_apm require
|
89
|
+
|
90
|
+
def require(path)
|
91
|
+
res = require_without_apm(path)
|
92
|
+
|
93
|
+
begin
|
94
|
+
Hoss::Spies.hook_into(path)
|
95
|
+
rescue ::Exception => e
|
96
|
+
puts "Failed hooking into '#{path}'. Please report this at " \
|
97
|
+
'github.com/elastic/apm-agent-ruby'
|
98
|
+
puts e.backtrace.join("\n")
|
99
|
+
end
|
100
|
+
|
101
|
+
res
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
6
|
+
# not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
# frozen_string_literal: true
|
19
|
+
|
20
|
+
module Hoss
|
21
|
+
# @api private
|
22
|
+
module Spies
|
23
|
+
# @api private
|
24
|
+
class FaradaySpy
|
25
|
+
TYPE = 'ext'
|
26
|
+
SUBTYPE = 'faraday'
|
27
|
+
|
28
|
+
def self.without_net_http
|
29
|
+
return yield unless defined?(NetHTTPSpy)
|
30
|
+
|
31
|
+
Hoss::Spies::NetHTTPSpy.disable_in do
|
32
|
+
yield
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
37
|
+
def install
|
38
|
+
::Faraday::Connection.class_eval do
|
39
|
+
alias run_request_without_apm run_request
|
40
|
+
|
41
|
+
def run_request(method, url, body, headers, &block)
|
42
|
+
begin
|
43
|
+
Hoss.with_event do |event|
|
44
|
+
Hoss::Spies::FaradaySpy.without_net_http do
|
45
|
+
begin
|
46
|
+
uri = URI(build_url(url))
|
47
|
+
result = run_request_without_apm(method, url, body, headers) do |req|
|
48
|
+
if block_given?
|
49
|
+
yield req
|
50
|
+
new_path = req.path
|
51
|
+
new_query = URI.encode_www_form(req.params)
|
52
|
+
if uri.path != new_path || uri.query != new_query
|
53
|
+
test_uri = uri
|
54
|
+
test_uri.query = nil
|
55
|
+
begin
|
56
|
+
test_uri.path = new_path
|
57
|
+
rescue Exception => e
|
58
|
+
end
|
59
|
+
# The original url can be set to path if Faraday.get used
|
60
|
+
if test_uri.to_s != uri.to_s
|
61
|
+
uri.path = new_path
|
62
|
+
end
|
63
|
+
uri.query = new_query
|
64
|
+
end
|
65
|
+
end
|
66
|
+
event.request.method = method.to_s.upcase
|
67
|
+
event.request.url = uri.to_s
|
68
|
+
event.request.received_at = DateTime.now.strftime('%Q').to_i
|
69
|
+
event.request.headers['host'] = uri.hostname
|
70
|
+
req.headers.each {|n,v| event.request.headers[n] = v}
|
71
|
+
event.request.url = uri.to_s
|
72
|
+
event.request.body = req.body
|
73
|
+
end
|
74
|
+
|
75
|
+
if result
|
76
|
+
event.response = Hoss::Event::Response.new
|
77
|
+
event.response.received_at = DateTime.now.strftime('%Q').to_i
|
78
|
+
event.response.status_code = result.status.to_i
|
79
|
+
result.headers.each {|n,v| event.response.headers[n] = v}
|
80
|
+
event.response.body = result.body
|
81
|
+
end
|
82
|
+
|
83
|
+
result
|
84
|
+
rescue Exception => e
|
85
|
+
if e.respond_to?(:wrapped_exception) && e.wrapped_exception.is_a?(Net::OpenTimeout)
|
86
|
+
event.error = Hoss::Event::Error.new(Hoss::Event::Error::ConnectionTimeout)
|
87
|
+
else
|
88
|
+
event.error = Hoss::Event::Error.new(Hoss::Event::Error::ConnectionError)
|
89
|
+
end
|
90
|
+
event.error.received_at = DateTime.now.strftime('%Q').to_i
|
91
|
+
raise
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
rescue
|
96
|
+
run_request_without_apm(method, url, body, headers, &block)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
102
|
+
end
|
103
|
+
|
104
|
+
register 'Faraday', 'faraday', FaradaySpy.new
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
6
|
+
# not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
# frozen_string_literal: true
|
19
|
+
|
20
|
+
module Hoss
|
21
|
+
# @api private
|
22
|
+
module Spies
|
23
|
+
# @api private
|
24
|
+
class HTTPSpy
|
25
|
+
TYPE = 'ext'
|
26
|
+
SUBTYPE = 'http_rb'
|
27
|
+
|
28
|
+
def self.copy_request_body(body)
|
29
|
+
case body.source
|
30
|
+
when String
|
31
|
+
body.source
|
32
|
+
when nil
|
33
|
+
nil
|
34
|
+
else
|
35
|
+
""
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def install
|
40
|
+
::HTTP::Client.class_eval do
|
41
|
+
alias perform_without_apm perform
|
42
|
+
|
43
|
+
def perform(req, options)
|
44
|
+
if req.headers['HOSS-SKIP-INSTRUMENTATION'] == 'true'
|
45
|
+
return perform_without_apm(req, options)
|
46
|
+
end
|
47
|
+
|
48
|
+
begin
|
49
|
+
Hoss.with_event do |event|
|
50
|
+
event.request.headers['host'] = req.uri.host
|
51
|
+
req.headers.each {|n,v| event.request.headers[n] = v}
|
52
|
+
event.request.method = req.verb.to_s.upcase
|
53
|
+
event.request.url = req.uri.to_s
|
54
|
+
event.request.body = Hoss::Spies::HTTPSpy::copy_request_body(req.body)
|
55
|
+
event.request.received_at = DateTime.now.strftime('%Q').to_i
|
56
|
+
begin
|
57
|
+
result = perform_without_apm(req, options)
|
58
|
+
if result
|
59
|
+
event.response = Hoss::Event::Response.new
|
60
|
+
event.response.received_at = DateTime.now.strftime('%Q').to_i
|
61
|
+
event.response.status_code = result.code.to_i
|
62
|
+
result.headers.each {|n,v| event.response.headers[n] = v}
|
63
|
+
event.response.body = result.body.to_s
|
64
|
+
end
|
65
|
+
result
|
66
|
+
rescue HTTP::TimeoutError => e
|
67
|
+
event.error = Hoss::Event::Error.new(Hoss::Event::Error::ConnectionTimeout)
|
68
|
+
event.error.received_at = DateTime.now.strftime('%Q').to_i
|
69
|
+
raise
|
70
|
+
rescue Exception => e
|
71
|
+
event.error = Hoss::Event::Error.new(Hoss::Event::Error::ConnectionError)
|
72
|
+
event.error.received_at = DateTime.now.strftime('%Q').to_i
|
73
|
+
raise
|
74
|
+
end
|
75
|
+
end
|
76
|
+
rescue
|
77
|
+
return perform_without_apm(req, options)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
register 'HTTP', 'http', HTTPSpy.new
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# Licensed to Elasticsearch B.V. under one or more contributor
|
2
|
+
# license agreements. See the NOTICE file distributed with
|
3
|
+
# this work for additional information regarding copyright
|
4
|
+
# ownership. Elasticsearch B.V. licenses this file to you under
|
5
|
+
# the Apache License, Version 2.0 (the "License"); you may
|
6
|
+
# not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing,
|
12
|
+
# software distributed under the License is distributed on an
|
13
|
+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
14
|
+
# KIND, either express or implied. See the License for the
|
15
|
+
# specific language governing permissions and limitations
|
16
|
+
# under the License.
|
17
|
+
|
18
|
+
# frozen_string_literal: true
|
19
|
+
|
20
|
+
module Hoss
|
21
|
+
# @api private
|
22
|
+
module Spies
|
23
|
+
# @api private
|
24
|
+
class NetHTTPSpy
|
25
|
+
KEY = :__hoss_net_http_disabled
|
26
|
+
# TYPE = 'ext'
|
27
|
+
# SUBTYPE = 'net_http'
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def disabled=(disabled)
|
31
|
+
Thread.current[KEY] = disabled
|
32
|
+
end
|
33
|
+
|
34
|
+
def disabled?
|
35
|
+
Thread.current[KEY] ||= false
|
36
|
+
end
|
37
|
+
|
38
|
+
def disable_in
|
39
|
+
self.disabled = true
|
40
|
+
|
41
|
+
begin
|
42
|
+
yield
|
43
|
+
ensure
|
44
|
+
self.disabled = false
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
50
|
+
def install
|
51
|
+
Net::HTTP.class_eval do
|
52
|
+
alias request_without_apm request
|
53
|
+
|
54
|
+
def request(req, body = nil, &block)
|
55
|
+
if req['HOSS-SKIP-INSTRUMENTATION'] == 'true' || Hoss::Spies::NetHTTPSpy.disabled?
|
56
|
+
return request_without_apm(req, body, &block)
|
57
|
+
end
|
58
|
+
|
59
|
+
begin
|
60
|
+
host = req['host']&.split(':')&.first || address
|
61
|
+
method = req.method.to_s.upcase
|
62
|
+
path, query = req.path.split('?')
|
63
|
+
|
64
|
+
url = use_ssl? ? +'https://' : +'http://'
|
65
|
+
url << host
|
66
|
+
url << ":#{port}" if port
|
67
|
+
url << path
|
68
|
+
url << "?#{query}" if query
|
69
|
+
uri = URI(url)
|
70
|
+
|
71
|
+
Hoss.with_event do |event|
|
72
|
+
# Record request
|
73
|
+
event.request.headers['host'] = uri.hostname
|
74
|
+
req.each_header {|n,v| event.request.headers[n] = v}
|
75
|
+
event.request.method = method
|
76
|
+
event.request.url = uri.to_s
|
77
|
+
event.request.body = req.body
|
78
|
+
event.request.received_at = DateTime.now.strftime('%Q').to_i
|
79
|
+
|
80
|
+
result = request_without_apm(req, body, &block)
|
81
|
+
if result
|
82
|
+
event.response = Hoss::Event::Response.new
|
83
|
+
event.response.received_at = DateTime.now.strftime('%Q').to_i
|
84
|
+
event.response.status_code = result.code.to_i
|
85
|
+
result.each_header {|n,v| event.response.headers[n] = v}
|
86
|
+
event.response.body = result.body
|
87
|
+
end
|
88
|
+
result
|
89
|
+
end
|
90
|
+
rescue
|
91
|
+
return request_without_apm(req, body, &block)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
97
|
+
end
|
98
|
+
|
99
|
+
register 'Net::HTTP', 'net/http', NetHTTPSpy.new
|
100
|
+
end
|
101
|
+
end
|