class Librato::Rack
Middleware for rack applications. Installs tracking hearbeat for metric submission and tracks performance metrics.
@example A basic rack app
require 'rack' require 'librato-rack' app = Rack::Builder.app do use Librato::Rack run lambda { |env| [200, {"Content-Type" => 'text/html'}, ["Hello!"]] } end
@example Using a custom config object
config = Librato::Rack::Configuration.new config.user = 'myuser@mysite.com' config.token = 'mytoken' …more configuration use Librato::Rack, :config => config run MyApp
Constants
- RECORD_RACK_BODY
- RECORD_RACK_METHOD_BODY
- RECORD_RACK_STATUS_BODY
- VERSION
Attributes
config[R]
tracker[R]
Public Class Methods
new(app, options={})
click to toggle source
# File lib/librato/rack.rb, line 60 def initialize(app, options={}) @app = app @config = options.fetch(:config, Configuration.new) @tracker = @config.tracker || Tracker.new(@config) Librato.register_tracker(@tracker) # create global reference build_record_request_metrics_method build_record_header_metrics_method build_record_exception_method end
Public Instance Methods
call(env)
click to toggle source
# File lib/librato/rack.rb, line 71 def call(env) check_log_output(env) unless @log_target @tracker.check_worker record_header_metrics(env) response, duration = process_request(env) record_request_metrics(response.first, env["REQUEST_METHOD"], duration) response end
Private Instance Methods
build_record_exception_method()
click to toggle source
# File lib/librato/rack.rb, line 171 def build_record_exception_method if tracker.suite_enabled?(:rack) define_singleton_method(:record_exception) do |exception| return if config.disable_rack_metrics tracker.increment 'rack.request.exceptions' end else define_singleton_method(:record_exception) do |exception| # no-op end end end
build_record_header_metrics_method()
click to toggle source
Dynamically construct :record_header_metrics method based on configured metric suites
# File lib/librato/rack.rb, line 146 def build_record_header_metrics_method if tracker.suite_enabled?(:rack) define_singleton_method(:record_header_metrics) do |env| queue_start = env['HTTP_X_REQUEST_START'] || env['HTTP_X_QUEUE_START'] if queue_start queue_start = queue_start.to_s.sub('t=', '').sub('.', '') case queue_start.length when 16 # microseconds wait = ((Time.now.to_f * 1000000).to_i - queue_start.to_i) / 1000.0 wait = 0 if wait < 0 # make up for potential time drift between the routing server and the application server tracker.timing 'rack.request.queue.time', wait, percentile: 95 when 13 # milliseconds wait = (Time.now.to_f * 1000).to_i - queue_start.to_i wait = 0 if wait < 0 # make up for potential time drift between the routing server and the application server tracker.timing 'rack.request.queue.time', wait, percentile: 95 end end end else define_singleton_method(:record_header_metrics) do |env| # no-op end end end
build_record_request_metrics_method()
click to toggle source
Dynamically construct :record_request_metrics method based on configured metric suites
# File lib/librato/rack.rb, line 117 def build_record_request_metrics_method body = "def record_request_metrics(status, http_method, duration)\n" body << "return if config.disable_rack_metrics\n" unless config.instance_of?(Librato::Rack::Configuration::SuitesNone) body << "tracker.group 'rack.request' do |group|\n" if tracker.suite_enabled?(:rack) body << RECORD_RACK_BODY end if tracker.suite_enabled?(:rack_status) body << RECORD_RACK_STATUS_BODY end if tracker.suite_enabled?(:rack_method) body << RECORD_RACK_METHOD_BODY end body << "end\n" end body << "end\n" instance_eval(body) end
check_log_output(env)
click to toggle source
this generally will only get called on the first request it figures out the environment-appropriate logging outlet and notifies config and tracker about it
# File lib/librato/rack.rb, line 85 def check_log_output(env) return if @log_target if in_heroku_env? tracker.on_heroku = true default = ::Logger.new($stdout) else default = env['rack.errors'] || $stderr end @tracker.update_log_target(config.log_target ||= default) @log_target = config.log_target end
in_heroku_env?()
click to toggle source
# File lib/librato/rack.rb, line 97 def in_heroku_env? # don't have any custom http vars anymore, check if hostname is UUID Socket.gethostname =~ /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/i end
process_request(env)
click to toggle source
# File lib/librato/rack.rb, line 102 def process_request(env) time = Time.now begin response = @app.call(env) rescue Exception => e record_exception(e) raise end duration = (Time.now - time) * 1000.0 [response, duration] end