Track Request Time With the Faraday

I’m frequently find myself in need to measure request time of remote request from my application to an API or service. Previously, i used simple block of ruby code with start_time and end_time. Finally i decided to find out more robust method of doing so. I’m using faraday gem for remote requests, because it’s easy extendable by middlewares and great overall. You can take a look at the project with collection of middlewares for faraday on github. This project contains Instrumentation middleware that we will use for tracking time of our request.

Before we start, here is an image of Dr. Faraday from LOST:

By the way github handle of faraday author is @lostisland. Coincidence? I don’t think so :)

To the work! Let’s look inside the instrumentation middleware:

instrumentation.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module FaradayMiddleware
  class Instrumentation < Faraday::Middleware
    dependency 'active_support/notifications'

    def initialize(app, options = {})
      super(app)
      @name = options.fetch(:name, 'request.faraday')
    end

    def call(env)
      ActiveSupport::Notifications.instrument(@name, env) do
        @app.call(env)
      end
    end
  end
end

Pretty straightforward, we just instrument event 'request.faraday'. If you are not familiar with the ActiveSupport::Notifications mechanism you can read about it here.

We should add this middleware to our faraday connection object:

faraday_connection_example.rb
1
2
3
4
5
6
7
  def connection
    Faraday.new(url: "http://google.com") do |faraday|
      faraday.use FaradayMiddleware::Instrumentation
      faraday.adapter  Faraday.default_adapter
      faraday.response :logger
    end
  end

Let’s subscribe to the request.faraday events with the ActiveSupport::Notifications. You can execute any code inside your subscribe block, save information and time to the file or database for example. I will use rails logger in my example:

config/initializers/notifications.rb
1
2
3
4
5
6
ActiveSupport::Notifications.subscribe('request.faraday') do |name, starts, ends, _, env|
  url = env[:url]
  http_method = env[:method].to_s.upcase
  duration = ends - starts
  Rails.logger.info "#{url.host}, #{http_method}, #{url.request_uri}, takes #{duration} seconds"
end

That’s all, you are set and ready, whenever your application will send any request with the faraday connection, it will print request time information to your log file.

Copyright © 2014 - Mikhail Nikalyukin - Powered by Octopress