From 4b30bf8b5e428bdc531d7b454bf26f1a366e7790 Mon Sep 17 00:00:00 2001 From: technoweenie Date: Sat, 5 Jan 2013 10:41:02 -0700 Subject: [PATCH] add instrumentation middleware. original work by @mislav https://github.com/pengwynn/faraday_middleware/commit/23d5e614eea4f48dd5 a0eee68eb8b3d5e65b5275 --- lib/faraday/request.rb | 3 +- lib/faraday/request/instrumentation.rb | 38 +++++++++++++ test/middleware/instrumentation_test.rb | 75 +++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 lib/faraday/request/instrumentation.rb create mode 100644 test/middleware/instrumentation_test.rb diff --git a/lib/faraday/request.rb b/lib/faraday/request.rb index 73ce8982d..8ee399941 100644 --- a/lib/faraday/request.rb +++ b/lib/faraday/request.rb @@ -18,7 +18,8 @@ class Request < Struct.new(:method, :path, :params, :headers, :body, :options) :retry => [:Retry, 'retry'], :authorization => [:Authorization, 'authorization'], :basic_auth => [:BasicAuthentication, 'basic_authentication'], - :token_auth => [:TokenAuthentication, 'token_authentication'] + :token_auth => [:TokenAuthentication, 'token_authentication'], + :instrumentation => [:Instrumentation, 'instrumentation'] def self.create(request_method) new(request_method).tap do |request| diff --git a/lib/faraday/request/instrumentation.rb b/lib/faraday/request/instrumentation.rb new file mode 100644 index 000000000..f07dcdd97 --- /dev/null +++ b/lib/faraday/request/instrumentation.rb @@ -0,0 +1,38 @@ +module Faraday + class Request::Instrumentation < Faraday::Middleware + class Options < Faraday::Options.new(:name, :instrumenter) + def name + self[:name] ||= 'request.faraday' + end + + def instrumenter + self[:instrumenter] ||= ActiveSupport::Notifications + end + end + + # Public: Instruments requests using Active Support. + # + # Measures time spent only for synchronous requests. + # + # Examples + # + # ActiveSupport::Notifications.subscribe('request.faraday') do |name, starts, ends, _, env| + # url = env[:url] + # http_method = env[:method].to_s.upcase + # duration = ends - starts + # $stderr.puts '[%s] %s %s (%.3f s)' % [url.host, http_method, url.request_uri, duration] + # end + def initialize(app, options = nil) + super(app) + @name, @instrumenter = Options.from(options).values + end + + def call(env) + @instrumenter.instrument(@name, env) do + @app.call(env) + end + end + end +end + + diff --git a/test/middleware/instrumentation_test.rb b/test/middleware/instrumentation_test.rb new file mode 100644 index 000000000..e0833a3e5 --- /dev/null +++ b/test/middleware/instrumentation_test.rb @@ -0,0 +1,75 @@ +require File.expand_path("../../helper", __FILE__) + +module Middleware + class InstrumentationTest < Faraday::TestCase + def setup + @instrumenter = FakeInstrumenter.new + end + + def test_default_name + assert_equal 'request.faraday', options.name + end + + def test_default_instrumenter + begin + instrumenter = options.instrumenter + rescue NameError => err + assert_equal :ActiveSupport, err.name + else + assert_equal ActiveSupport::Notifications, instrumenter + end + end + + def test_name + assert_equal 'booya', options(:name => 'booya').name + end + + def test_instrumenter + assert_equal :boom, options(:instrumenter => :boom).instrumenter + end + + def test_instrumentation + assert_equal 0, @instrumenter.instrumentations.size + + faraday = conn :name => 'booya' + res = faraday.get '/' + assert_equal 'ok', res.body + + assert_equal 1, @instrumenter.instrumentations.size + name, env = @instrumenter.instrumentations.first + assert_equal 'booya', name + assert_equal '/', env[:url].path + end + + class FakeInstrumenter + attr_reader :instrumentations + + def initialize + @instrumentations = [] + end + + def instrument(name, env) + @instrumentations << [name, env] + yield + end + end + + def options(hash = nil) + Faraday::Request::Instrumentation::Options.from hash + end + + def conn(hash = nil) + hash ||= {} + hash[:instrumenter] = @instrumenter + + Faraday.new do |f| + f.request :instrumentation, hash + f.adapter :test do |stub| + stub.get '/' do + [200, {}, 'ok'] + end + end + end + end + end +end