Skip to content

Commit

Permalink
Initial commit v0.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
inkel committed Nov 29, 2010
1 parent 9f1f42d commit 304d9b7
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
@@ -0,0 +1,3 @@
pkg/*
*.gem
.bundle
4 changes: 4 additions & 0 deletions Gemfile
@@ -0,0 +1,4 @@
source "http://rubygems.org"

# Specify your gem's dependencies in haproxy.gemspec
gemspec
2 changes: 2 additions & 0 deletions Rakefile
@@ -0,0 +1,2 @@
require 'bundler'
Bundler::GemHelper.install_tasks
21 changes: 21 additions & 0 deletions lib/haproxy.rb
@@ -0,0 +1,21 @@
libdir = File.dirname(__FILE__)
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)

require 'uri'
Dir["#{libdir}/haproxy/*.rb"].each do |file|
require file
end

module HAProxy

def self.read_stats(from)
uri = URI.parse(from)

if uri.is_a?(URI::Generic) and File.socket?(uri.path)
HAProxy::SocketReader.new(uri.path)
else
raise NotImplementedError, "Currently only sockets are implemented"
end
end

end
32 changes: 32 additions & 0 deletions lib/haproxy/csv_parser.rb
@@ -0,0 +1,32 @@
module HAProxy
class CSVParser

# Uses CSV header from HAProxy 1.5, which is backwards compatible
COLUMNS = "pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt".split(",").map(&:to_sym)
LIMIT = COLUMNS.length

def self.parse(line)
line.strip!
unless line.start_with? "#"
data = line.split(',')
pxname = data.shift

stats = { :pxname => pxname }

data.each_with_index do |value, i|
if i < LIMIT
stats[COLUMNS[i + 1]] = value
else
stats[:extra] = Array.new if stats[:extra].nil?
stats[:extra] << value
end
end

stats
else
raise ArgumentError, "Line is a comment"
end
end
end

end
93 changes: 93 additions & 0 deletions lib/haproxy/socket_reader.rb
@@ -0,0 +1,93 @@
require 'socket'
require 'haproxy/stats_reader'
require 'haproxy/csv_parser'

module HAProxy
class SocketReader < HAProxy::StatsReader

def initialize(path)
@path = path
end

def info
returning({}) do |info|
send_cmd "show info" do |line|
key, value = line.split(': ')
info[key.downcase.gsub('-', '_').to_sym] = value
end
end
end

def errors
returning("") do |errors|
send_cmd "show errors" do |line|
errors << line
end
end
end

def sessions
returning([]) do |sess|
send_cmd "show sess" do |line|
sess << line
end
end
end

TYPES = {
:frontend => 1,
:backend => 2,
:server => 4
}

def stats(types=[:all], options={})
params = {
:proxy => :all,
:server => :all
}.merge(options)

params[:proxy] = "-1" if params[:proxy].eql?(:all)
params[:server] = "-1" if params[:server].eql?(:all)

types = [types] unless types.is_a?(Array)

params[:type] = case
when types.eql?([:all])
"-1"
else
types.map{ |type| TYPES[type] }.inject(:+)
end

cmd = "show stat #{params[:proxy]} #{params[:type]} #{params[:server]}"

returning([]) do |stats|
send_cmd(cmd) do |line|
stats << CSVParser.parse(line) unless line.start_with?('#')
end
end
end

def frontends
stats :frontend, :proxy => :all, :server => :all
end

def backends
stats :frontend, :proxy => :all, :server => :all
end

def servers
stats :server, :proxy => :all, :server => :all
end

protected

def send_cmd(cmd, &block)
socket = UNIXSocket.new(@path)
socket.puts(cmd)
socket.each do |line|
yield(line.strip)
end
end

end
end
51 changes: 51 additions & 0 deletions lib/haproxy/stats_reader.rb
@@ -0,0 +1,51 @@
libdir = File.dirname(__FILE__)
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)

module HAProxy

class StatsReader

def info
raise NotImplementedError
end

def errors
raise NotImplementedError
end

def sessions
raise NotImplementedError
end

def stats
raise NotImplementedError
end

def frontends
raise NotImplementedError
end

def backends
raise NotImplementedError
end

def servers
raise NotImplementedError
end

protected

# Borrowed from Rails 3
def returning(value)
yield(value)
value
end

private

def initialize
end

end

end
3 changes: 3 additions & 0 deletions lib/haproxy/version.rb
@@ -0,0 +1,3 @@
module Haproxy
VERSION = "0.0.1"
end

0 comments on commit 304d9b7

Please sign in to comment.