-
Notifications
You must be signed in to change notification settings - Fork 601
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
20 changed files
with
394 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# This file is distributed under New Relic's license terms. | ||
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. | ||
# frozen_string_literal: true | ||
|
||
require_relative 'abstract' | ||
require 'resolv' | ||
|
||
module NewRelic | ||
module Agent | ||
module HTTPClients | ||
class AsyncHTTPResponse < AbstractResponse | ||
def get_status_code | ||
get_status_code_using(:status) | ||
end | ||
|
||
def [](key) | ||
to_hash[key.downcase]&.first | ||
end | ||
|
||
def to_hash | ||
@wrapped_response.headers.to_h | ||
end | ||
end | ||
|
||
class AsyncHTTPRequest < AbstractRequest | ||
def initialize(connection, method, url, headers) | ||
@connection = connection | ||
@method = method | ||
@url = ::NewRelic::Agent::HTTPClients::URIUtil.parse_and_normalize_url(url) | ||
@headers = headers | ||
end | ||
|
||
ASYNC_HTTP = 'Async::HTTP' | ||
LHOST = 'host' | ||
UHOST = 'Host' | ||
COLON = ':' | ||
|
||
def type | ||
ASYNC_HTTP | ||
end | ||
|
||
def host_from_header | ||
if hostname = (self[LHOST] || self[UHOST]) | ||
hostname.split(COLON).first | ||
end | ||
end | ||
|
||
def host | ||
host_from_header || uri.host.to_s | ||
end | ||
|
||
def [](key) | ||
return headers[key] unless headers.is_a?(Array) | ||
|
||
headers.each do |header| | ||
return header[1] if header[0].casecmp?(key) | ||
end | ||
nil | ||
end | ||
|
||
def []=(key, value) | ||
if headers.is_a?(Array) | ||
headers << [key, value] | ||
else | ||
headers[key] = value | ||
end | ||
end | ||
|
||
def uri | ||
@url | ||
end | ||
|
||
def headers | ||
@headers | ||
end | ||
|
||
def method | ||
@method | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# This file is distributed under New Relic's license terms. | ||
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. | ||
# frozen_string_literal: true | ||
|
||
require_relative 'async_http/instrumentation' | ||
require_relative 'async_http/chain' | ||
require_relative 'async_http/prepend' | ||
|
||
DependencyDetection.defer do | ||
named :async_http | ||
|
||
depends_on do | ||
defined?(Async::HTTP) && Gem::Version.new(Async::HTTP::VERSION) >= Gem::Version.new('0.59.0') | ||
end | ||
|
||
executes do | ||
NewRelic::Agent.logger.info('Installing async_http instrumentation') | ||
|
||
require 'async/http/internet' | ||
if use_prepend? | ||
prepend_instrument Async::HTTP::Internet, NewRelic::Agent::Instrumentation::AsyncHttp::Prepend | ||
else | ||
chain_instrument NewRelic::Agent::Instrumentation::AsyncHttp::Chain | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# This file is distributed under New Relic's license terms. | ||
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. | ||
# frozen_string_literal: true | ||
|
||
require_relative 'instrumentation' | ||
|
||
module NewRelic::Agent::Instrumentation | ||
module AsyncHttp::Chain | ||
def self.instrument! | ||
::Async::HTTP::Internet.class_eval do | ||
include NewRelic::Agent::Instrumentation::AsyncHttp | ||
|
||
alias_method(:call_without_new_relic, :call) | ||
|
||
def call(method, url, headers = nil, body = nil) | ||
call_with_new_relic(method, url, headers, body) do |hdr| | ||
call_without_new_relic(method, url, hdr, body) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
37 changes: 37 additions & 0 deletions
37
lib/new_relic/agent/instrumentation/async_http/instrumentation.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# This file is distributed under New Relic's license terms. | ||
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. | ||
# frozen_string_literal: true | ||
|
||
require 'new_relic/agent/http_clients/async_http_wrappers' | ||
|
||
module NewRelic::Agent::Instrumentation | ||
module AsyncHttp | ||
def call_with_new_relic(method, url, headers = nil, body = nil) | ||
headers ||= {} # if it is nil, we need to make it a hash so we can insert headers | ||
wrapped_request = NewRelic::Agent::HTTPClients::AsyncHTTPRequest.new(self, method, url, headers) | ||
|
||
segment = NewRelic::Agent::Tracer.start_external_request_segment( | ||
library: wrapped_request.type, | ||
uri: wrapped_request.uri, | ||
procedure: wrapped_request.method | ||
) | ||
|
||
begin | ||
response = nil | ||
segment.add_request_headers(wrapped_request) | ||
|
||
NewRelic::Agent.disable_all_tracing do | ||
response = NewRelic::Agent::Tracer.capture_segment_error(segment) do | ||
yield(headers) | ||
end | ||
end | ||
|
||
wrapped_response = NewRelic::Agent::HTTPClients::AsyncHTTPResponse.new(response) | ||
segment.process_response_headers(wrapped_response) | ||
response | ||
ensure | ||
segment&.finish | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# This file is distributed under New Relic's license terms. | ||
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. | ||
# frozen_string_literal: true | ||
|
||
require_relative 'instrumentation' | ||
|
||
module NewRelic::Agent::Instrumentation | ||
module AsyncHttp::Prepend | ||
include NewRelic::Agent::Instrumentation::AsyncHttp | ||
|
||
def call(method, url, headers = nil, body = nil) | ||
call_with_new_relic(method, url, headers, body) { |hdr| super(method, url, hdr, body) } | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,7 @@ | |
|
||
subs = %w[send_file | ||
send_data | ||
send_stream | ||
redirect_to | ||
halted_callback | ||
unpermitted_parameters] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# This file is distributed under New Relic's license terms. | ||
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details. | ||
# frozen_string_literal: true | ||
|
||
instrumentation_methods :chain, :prepend | ||
|
||
ASYNC_HTTP_VERSIONS = [ | ||
[nil, 2.5], | ||
['0.59.0', 2.5] | ||
] | ||
|
||
def gem_list(async_http_version = nil) | ||
<<~GEM_LIST | ||
gem 'async-http'#{async_http_version} | ||
gem 'rack' | ||
GEM_LIST | ||
end | ||
|
||
create_gemfiles(ASYNC_HTTP_VERSIONS) |
Oops, something went wrong.