module Labkit::HTTPClientPublisher

Prepend to HTTPClient class to publish an ActiveSupport::Notifcation whenever a HTTP request is triggered.

Similar to Net::HTTP, this HTTP client redirects all calls to HTTPClient#do_get_block. HTTPClient is prepended with HTTPClientPublisher. Although HTTPClient supports request filter (a kind of middleware), its support is strictly limited. The request and response passed into the filter don't contain connection information. The response doesn't even contain any link to the request object. It's impossible to fit this filter mechanism into our subscribing model.

For more information; github.com/nahi/httpclient/blob/d3091b095a1b29f65f4531a70a8e581e75be035e/lib/httpclient.rb#L1233

Public Class Methods

labkit_prepend!() click to toggle source
# File lib/labkit/httpclient_publisher.rb, line 21
def self.labkit_prepend!
  @prepend_mutex.synchronize do
    return if !defined?(HTTPClient) || @prepended

    HTTPClient.prepend(self)
    @prepended = true
  end
end

Public Instance Methods

do_get_block(req, proxy, conn, &block) click to toggle source
Calls superclass method
# File lib/labkit/httpclient_publisher.rb, line 30
def do_get_block(req, proxy, conn, &block)
  start_time = ::Labkit::System.monotonic_time
  ActiveSupport::Notifications.instrument ::Labkit::EXTERNAL_HTTP_NOTIFICATION_TOPIC, create_request_payload(req, proxy) do |payload|
    response =
      begin
        super
      ensure
        payload[:duration] = (::Labkit::System.monotonic_time - start_time).to_f
      end
    payload[:code] = response.status_code.to_s
    response
  end
end

Private Instance Methods

create_request_payload(request, proxy) click to toggle source
# File lib/labkit/httpclient_publisher.rb, line 46
def create_request_payload(request, proxy)
  http_header = request.http_header
  payload = {
    method: http_header.request_method,
    host: http_header.request_uri.host,
    path: http_header.request_uri.path,
    port: http_header.request_uri.port,
    scheme: http_header.request_uri.scheme,
    query: http_header.request_uri.query,
    fragment: http_header.request_uri.fragment,
  }

  unless proxy.nil?
    payload[:proxy_host] = proxy.host
    payload[:proxy_port] = proxy.port
  end

  payload
end