Created
July 16, 2021 21:47
-
-
Save lilymara-onesignal/3d0e6ff0a5ad951a686fa1b11d22ebfa to your computer and use it in GitHub Desktop.
Tracing Net::HTTP in ruby
This file contains hidden or 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
# Taken from Jon Anderson (FireHydrant) on Honeycomb slack | |
# https://honeycombpollinators.slack.com/archives/CJR134U2F/p1626469086124100 | |
# frozen_string_literal: true | |
require "net/http" | |
module Net | |
class HTTP | |
alias_method :original_request, :request | |
def request(req, body = nil, &block) | |
return original_request(req, body, &block) if should_call_untraced_original?(req) | |
Honeycomb.start_span(name: "http_client") do |span| | |
_hc_annotate_request(req, span) rescue nil | |
response = original_request(req, body, &block) | |
_hc_annotate_response(response, span) rescue nil | |
response | |
end | |
end | |
private | |
# This is brittle and I hate it but I can't think of a better way to not | |
# double up faraday spans with net/http as the adapter. | |
def should_call_untraced_original?(req) | |
current_span = Honeycomb.current_span | |
event = current_span && current_span.instance_variable_get(:@event) | |
event && event.data["meta.package"] == "faraday" || invalid_host?(req) | |
rescue | |
true | |
end | |
# This is some weird magic that we may be able to remove once we no longer | |
# send spans to Datadog. We were seeing Net::HTTP requests with no host | |
# but still going somewhere, but only when running in combined tracer mode. | |
def invalid_host?(req) | |
host = req.respond_to?(:uri) ? req.uri&.host : @host | |
host.to_s.empty? | |
end | |
def _hc_annotate_request(req, span) | |
span.add_field("meta.package", "net/http") | |
span.add_field("meta.type", "http_client") | |
span.add_field("request.method", req.method.to_s.upcase) | |
span.add_field("request.content_type", req["content-type"]) | |
span.add_field("request.accept", req["accept"]) | |
if req.respond_to?(:uri) && req.uri | |
span.add_field("request.host", req.uri.host) | |
span.add_field("request.port", req.uri.port.to_s) | |
span.add_field("request.path", req.uri.path) | |
span.add_field("request.scheme", req.uri.scheme) | |
else | |
span.add_field("request.host", @request) | |
span.add_field("request.port", @port) | |
end | |
end | |
def _hc_annotate_response(response, span) | |
return if response.nil? | |
span.add_field("response.status_code", response.code.to_i) | |
span.add_field("response.content_type", response["content-type"]) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment