Skip to content

Instantly share code, notes, and snippets.

@lwoodson
Created April 17, 2015 21:56
Show Gist options
  • Save lwoodson/ec0bd1e6d2235b48fdb1 to your computer and use it in GitHub Desktop.
Save lwoodson/ec0bd1e6d2235b48fdb1 to your computer and use it in GitHub Desktop.
Instrument HTTP calls made with Net::HTTP
HTTP_LOG_PATH = File.expand_path("~/http.log")
FileUtils.rm_f(HTTP_LOG_PATH)
module NetInstrumentation
def self.included(base)
puts "Writing HTTP out to ~/http.log"
base.send(:alias_method, :__original_request, :request)
base.send(:alias_method, :request, :__logged_request)
end
def __logged_request(*args, &block)
request = args.first
request_data = JSON.parse(request.to_json)
request_data[:uri] = request.uri
request_data[:path] = request.path
request_data[:body] = request.body
return __original_request(*args, &block).tap do |response|
response_data = JSON.parse(response.to_json)
response_data[:code] = response.code
response_data[:message] = response.message
response_data[:body] = response.body
data = {request: request_data, response: response_data}.to_json
__logger.info(data)
end
end
def __logger
@__logger ||= Logger.new(HTTP_LOG_PATH)
end
end
Net::HTTP.send(:include, NetInstrumentation)
def http_log
File.readlines(HTTP_LOG_PATH).map do |line|
JSON.parse(line) rescue nil
end.compact
end
@lwoodson
Copy link
Author

If you load 'net_instrumentation.rb' from a console, any HTTP calls made with Net::HTTP will be logged to ~/http.log. Each call is represented by a blob of JSON, 1 per line. The JSON object contains a request and response attribute with appropriate data.

There is also an http_log method in the global namespace available in the console. You can invoke it to get an array of the call blobs as hashes. This will allow you to do things like

http_log.select{|call| call[:response][:code] != 200}

and otherwise easily introspect the contents of the log.

@lwoodson
Copy link
Author

This is a very hacky way to be able to see details of HTTP (API) calls going out from a Ruby app from a console. The basic use would be...

> bundle exec rails console
2.1.2 :001 > load File.expand_path("~/net_instrumentation.rb")
Writing HTTP out to ~/http.log
 => true

The invoke your code that would result in the HTTP calls going out and then interact with the http log entries...

2.1.2 :002 > http_log.first['response']['code']
 => "200"

@randito
Copy link

randito commented Apr 18, 2015

Line 17 wants to make my eyes bleed. return magic.tap do |wtf| hahaha

@lwoodson
Copy link
Author

@randito I'll have you know my shitty code saved 1000 puppy lives today, lol!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment