Skip to content

Instantly share code, notes, and snippets.

@lilymara-onesignal
Created July 16, 2021 21:47
Show Gist options
  • Save lilymara-onesignal/3d0e6ff0a5ad951a686fa1b11d22ebfa to your computer and use it in GitHub Desktop.
Save lilymara-onesignal/3d0e6ff0a5ad951a686fa1b11d22ebfa to your computer and use it in GitHub Desktop.
Tracing Net::HTTP in ruby
# 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