class HttpLogger

Usage:

require 'http_logger'

Setup logger

HttpLogger.logger = Logger.new('/tmp/all.log')
HttpLogger.log_headers = true

Do request

res = Net::HTTP.start(url.host, url.port) { |http|
  http.request(req)
}
...

View the log

cat /tmp/all.log

Constants

HTTP_METHODS_WITH_BODY

Attributes

collapse_body_limit[RW]
colorize[RW]
ignore[RW]
level[RW]
log_headers[RW]
log_request_body[RW]
log_response_body[RW]
logger[RW]

Public Class Methods

deprecate_config(option) click to toggle source
# File lib/http_logger.rb, line 52
def self.deprecate_config(option)
  warn "Net::HTTP.#{option} is deprecated. Use HttpLogger.#{option} instead."
end
instance() click to toggle source
# File lib/http_logger.rb, line 48
def self.instance
  @instance ||= HttpLogger.new
end
perform(*args, &block) click to toggle source
# File lib/http_logger.rb, line 44
def self.perform(*args, &block)
  instance.perform(*args, &block)
end

Public Instance Methods

perform(http, request, request_body) { || ... } click to toggle source
# File lib/http_logger.rb, line 56
def perform(http, request, request_body)
  start_time = Time.now
  response = yield
ensure
  if require_logging?(http, request)
    log_request_url(http, request, start_time)
    log_request_body(request)
    log_request_headers(request)
    if defined?(response) && response
      log_response_code(response)
      log_response_headers(response)
      log_response_body(response.body)
    end
  end
end

Protected Instance Methods

collapse_body_limit() click to toggle source
# File lib/http_logger.rb, line 188
def collapse_body_limit
  self.class.collapse_body_limit
end
fakeweb?(http, request) click to toggle source
# File lib/http_logger.rb, line 134
def fakeweb?(http, request)
  return false unless defined?(::WebMock)
  uri = request_uri_as_string(http, request)
  method = request.method.downcase.to_sym
  signature = WebMock::RequestSignature.new(method, uri)
  ::WebMock.registered_request?(signature)
end
format_log_entry(message, dump = nil) click to toggle source
# File lib/http_logger.rb, line 173
def format_log_entry(message, dump = nil)
  if self.class.colorize
    message_color, dump_color = "4;32;1", "0;1"
    log_entry = "  \e[#{message_color}m#{message}\e[0m   "
    log_entry << "\e[#{dump_color}m%#{String === dump ? 's' : 'p'}\e[0m" % dump if dump
    log_entry
  else
    "%s  %s" % [message, dump]
  end
end
ignored?(http, request) click to toggle source
# File lib/http_logger.rb, line 127
def ignored?(http, request)
  url = request_url(http, request)
  HttpLogger.ignore.any? do |pattern|
    url =~ pattern
  end
end
log(message, dump) click to toggle source
# File lib/http_logger.rb, line 169
def log(message, dump)
  self.logger.send(self.class.level, format_log_entry(message, dump))
end
log_request_body(request) click to toggle source
# File lib/http_logger.rb, line 91
def log_request_body(request)
  if self.class.log_request_body
    if HTTP_METHODS_WITH_BODY.include?(request.method)
      if (body = request.body) && !body.empty?
        log("Request body", truncate_body(body))
      end
    end
  end
end
log_request_headers(request) click to toggle source
# File lib/http_logger.rb, line 83
def log_request_headers(request)
  if self.class.log_headers
    request.each_capitalized { |k,v| log("HTTP request header", "#{k}: #{v}") }
  end
end
log_request_url(http, request, start_time) click to toggle source
# File lib/http_logger.rb, line 74
def log_request_url(http, request, start_time)
  ofset = Time.now - start_time
  log("HTTP #{request.method} (%0.2fms)" % (ofset * 1000), request_url(http, request))
end
log_response_body(body) click to toggle source
# File lib/http_logger.rb, line 111
def log_response_body(body)
  if HttpLogger.log_response_body
    if body.is_a?(Net::ReadAdapter)
      log("Response body", "<impossible to log>")
    else
      if body && !body.empty?
        log("Response body", truncate_body(body))
      end
    end
  end
end
log_response_code(response) click to toggle source
# File lib/http_logger.rb, line 101
def log_response_code(response)
  log("Response status", "#{response.class} (#{response.code})")
end
log_response_headers(response) click to toggle source
# File lib/http_logger.rb, line 105
def log_response_headers(response)
  if HttpLogger.log_headers
    response.each_capitalized { |k,v| log("HTTP response header", "#{k}: #{v}") }
  end
end
logger() click to toggle source
# File lib/http_logger.rb, line 184
def logger
  self.class.logger
end
request_uri_as_string(net_http, request) click to toggle source
# File lib/http_logger.rb, line 142
def request_uri_as_string(net_http, request)
  protocol = net_http.use_ssl? ? "https" : "http"

  path = request.path
  path = URI.parse(request.path).request_uri if request.path =~ /^http/

  if request["authorization"] =~ /^Basic /
    userinfo = FakeWeb::Utility.decode_userinfo_from_header(request["authorization"])
    userinfo = FakeWeb::Utility.encode_unsafe_chars_in_userinfo(userinfo) + "@"
  else
    userinfo = ""
  end

  "#{protocol}://#{userinfo}#{net_http.address}:#{net_http.port}#{path}"
end
request_url(http, request) click to toggle source
# File lib/http_logger.rb, line 79
def request_url(http, request)
  URI::DEFAULT_PARSER.unescape("http#{"s" if http.use_ssl?}://#{http.address}:#{http.port}#{request.path}")
end
require_logging?(http, request) click to toggle source
# File lib/http_logger.rb, line 123
def require_logging?(http, request)
  self.logger && !ignored?(http, request) && (http.started? || fakeweb?(http, request))
end
truncate_body(body) click to toggle source
# File lib/http_logger.rb, line 158
def truncate_body(body)
  if collapse_body_limit && collapse_body_limit > 0 && body && body.size >= collapse_body_limit
    body_piece_size = collapse_body_limit / 2
    body[0..body_piece_size] +
      "\n\n<some data truncated>\n\n" +
      body[(body.size - body_piece_size)..body.size]
  else
    body
  end
end