From 90726e5187a9053c6eb7caf90ebec1d38d4372ea Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Tue, 8 Mar 2011 14:18:11 -0800 Subject: preliminary Rack app to track last_data_recv Seems to basically work --- lib/raindrops/last_data_recv.rb | 100 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 lib/raindrops/last_data_recv.rb (limited to 'lib/raindrops/last_data_recv.rb') diff --git a/lib/raindrops/last_data_recv.rb b/lib/raindrops/last_data_recv.rb new file mode 100644 index 0000000..3ec056e --- /dev/null +++ b/lib/raindrops/last_data_recv.rb @@ -0,0 +1,100 @@ +# -*- encoding: binary -*- +require "raindrops" + +# This is highly experimental! +# +# A self-contained Rack application for aggregating in the +# +tcpi_last_data_recv+ field in +struct tcp_info+ if +# /usr/include/linux/tcp.h. This is only useful for Linux 2.6 and later. +# This primarily supports Unicorn and derived servers, but may also be +# used with any Ruby web server using the core TCPServer class in Ruby. +# +# Hitting the Rack endpoint configured for this application will return +# a an ASCII histogram response body with the following headers: +# +# - X-Count - number of requests received +# +# The following headers are only present if X-Count is greater than one. +# +# - X-Min - lowest last_data_recv time recorded (in milliseconds) +# - X-Max - highest last_data_recv time recorded (in milliseconds) +# - X-Mean - mean last_data_recv time recorded (rounded, in milliseconds) +# - X-Std-Dev - standard deviation of last_data_recv times +# - X-Outliers-Low - number of low outliers (hopefully many!) +# - X-Outliers-High - number of high outliers (hopefully zero!) +# +# == To use with Unicorn and derived servers (preload_app=false): +# +# Put the following in our Unicorn config file (not config.ru): +# +# require "raindrops/last_data_recv" +# +# Then follow the instructions below for config.ru: +# +# == To use with any Rack server using TCPServer +# +# Setup a route for Raindrops::LastDataRecv in your Rackup config file +# (typically config.ru): +# +# require "raindrops" +# map "/raindrops/last_data_recv" do +# run Raindrops::LastDataRecv.new +# end +# map "/" do +# use SomeMiddleware +# use MoreMiddleware +# # ... +# run YourAppHere.new +# end +# +# == To use with any other Ruby web server that uses TCPServer +# +# Put the following in any piece of Ruby code loaded after the server has +# bound its TCP listeners: +# +# ObjectSpace.each_object(TCPServer) do |s| +# s.extend Raindrops::Aggregate::LastDataRecv +# end +# +# Thread.new do +# Raindrops::Aggregate::LastDataRecv.default_aggregate.master_loop +# end +# +# Then follow the above instructions for config.ru +# +class Raindrops::LastDataRecv + # :stopdoc: + + # trigger autoloads + if defined?(Unicorn) + agg = Raindrops::Aggregate::LastDataRecv.default_aggregate + AGGREGATE_THREAD = Thread.new { agg.master_loop } + end + # :startdoc + + def initialize(opts = {}) + Raindrops::Aggregate::LastDataRecv.cornify! if defined?(Unicorn) + @aggregate = + opts[:aggregate] || Raindrops::Aggregate::LastDataRecv.default_aggregate + end + + def call(_) + a = @aggregate + count = a.count + headers = { + "Content-Type" => "text/plain", + "X-Count" => count.to_s, + } + if count > 1 + headers["X-Min"] = a.min.to_s + headers["X-Max"] = a.max.to_s + headers["X-Mean"] = a.mean.round.to_s + headers["X-Std-Dev"] = a.std_dev.round.to_s + headers["X-Outliers-Low"] = a.outliers_low.to_s + headers["X-Outliers-High"] = a.outliers_high.to_s + end + body = a.to_s + headers["Content-Length"] = body.size.to_s + [ 200, headers, [ body ] ] + end +end -- cgit v1.2.3-24-ge0c7