Skip to content
Browse files

Middleware that sets an X-Runtime header

Times how long it takes for the application to respond to the request
and sets that to the X-Runtime header of the response.

Also allows the user to provide a suffix, so that different things can
be timed, eg, the just the app, or the app plug middleware stack.

    use Rack::Runtime, "All"

    # use more middleware's here

    use Rack::Runtime, "App"

    run Application

will set "X-Runtime-All" and "X-Runtime-App" headers on the response.

Signed-off-by: Joshua Peek <josh@joshpeek.com>
  • Loading branch information...
1 parent 27a068e commit 5fc43fea5df88faabc1025b883636d9e2ffbcbbf @paul paul committed with josh Jul 25, 2009
Showing with 54 additions and 0 deletions.
  1. +31 −0 lib/rack/contrib/runtime.rb
  2. +23 −0 test/spec_rack_runtime.rb
View
31 lib/rack/contrib/runtime.rb
@@ -0,0 +1,31 @@
+
+module Rack
+ # Sets an "X-Runtime" response header, indicating the response
+ # time of the request, in seconds
+ #
+ # You can put it right before the application to see the processing
+ # time, or before all the other middlewares to include time for them,
+ # too.
+ class Runtime
+ def initialize(app, name = nil)
+ @app = app
+ @header_name = "X-Runtime"
+ @header_name << "-#{name}" if name
+ end
+
+ def call(env)
+ start_time = Time.now
+ status, headers, body = @app.call(env)
+ request_time = Time.now - start_time
+
+ if !headers.has_key?(@header_name)
+ headers[@header_name] = "%0.6f" % request_time
+ end
+
+ [status, headers, body]
+ end
+ end
+end
+
+
+
View
23 test/spec_rack_runtime.rb
@@ -0,0 +1,23 @@
+require 'test/spec'
+require 'rack/mock'
+require 'rack/contrib/runtime'
+
+context "Rack::Runtime" do
+ specify "sets X-Runtime is none is set" do
+ app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
+ response = Rack::Runtime.new(app).call({})
+ response[1]['X-Runtime'].should =~ /[\d\.]+/
+ end
+
+ specify "does not set the X-Runtime if it is already set" do
+ app = lambda { |env| [200, {'Content-Type' => 'text/plain', "X-Runtime" => "foobar"}, "Hello, World!"] }
+ response = Rack::Runtime.new(app).call({})
+ response[1]['X-Runtime'].should == "foobar"
+ end
+
+ specify "should allow a suffix to be set" do
+ app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, World!"] }
+ response = Rack::Runtime.new(app, "Test").call({})
+ response[1]['X-Runtime-Test'].should =~ /[\d\.]+/
+ end
+end

0 comments on commit 5fc43fe

Please sign in to comment.
Something went wrong with that request. Please try again.