haproxy 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in haproxy.gemspec
4
+ gemspec
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,21 @@
1
+ # -*- mode: ruby; encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "haproxy/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "haproxy"
7
+ s.version = Haproxy::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Leandro López (inkel)"]
10
+ s.email = ["inkel.ar@gmail.com"]
11
+ s.homepage = "http://rubygems.org/gems/haproxy"
12
+ s.summary = %q{HAProxy interface for reading statistics or managing servers (requires HAProxy 1.4+)}
13
+ s.description = %q{This gem is intended for use as a HAProxy interface when you need to read statistics or if you like to manage proxies thru Ruby}
14
+
15
+ s.rubyforge_project = "haproxy"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
@@ -0,0 +1,21 @@
1
+ libdir = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
3
+
4
+ require 'uri'
5
+ Dir["#{libdir}/haproxy/*.rb"].each do |file|
6
+ require file
7
+ end
8
+
9
+ module HAProxy
10
+
11
+ def self.read_stats(from)
12
+ uri = URI.parse(from)
13
+
14
+ if uri.is_a?(URI::Generic) and File.socket?(uri.path)
15
+ HAProxy::SocketReader.new(uri.path)
16
+ else
17
+ raise NotImplementedError, "Currently only sockets are implemented"
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,32 @@
1
+ module HAProxy
2
+ class CSVParser
3
+
4
+ # Uses CSV header from HAProxy 1.5, which is backwards compatible
5
+ 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)
6
+ LIMIT = COLUMNS.length
7
+
8
+ def self.parse(line)
9
+ line.strip!
10
+ unless line.start_with? "#"
11
+ data = line.split(',')
12
+ pxname = data.shift
13
+
14
+ stats = { :pxname => pxname }
15
+
16
+ data.each_with_index do |value, i|
17
+ if i < LIMIT
18
+ stats[COLUMNS[i + 1]] = value
19
+ else
20
+ stats[:extra] = Array.new if stats[:extra].nil?
21
+ stats[:extra] << value
22
+ end
23
+ end
24
+
25
+ stats
26
+ else
27
+ raise ArgumentError, "Line is a comment"
28
+ end
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,93 @@
1
+ require 'socket'
2
+ require 'haproxy/stats_reader'
3
+ require 'haproxy/csv_parser'
4
+
5
+ module HAProxy
6
+ class SocketReader < HAProxy::StatsReader
7
+
8
+ def initialize(path)
9
+ @path = path
10
+ end
11
+
12
+ def info
13
+ returning({}) do |info|
14
+ send_cmd "show info" do |line|
15
+ key, value = line.split(': ')
16
+ info[key.downcase.gsub('-', '_').to_sym] = value
17
+ end
18
+ end
19
+ end
20
+
21
+ def errors
22
+ returning("") do |errors|
23
+ send_cmd "show errors" do |line|
24
+ errors << line
25
+ end
26
+ end
27
+ end
28
+
29
+ def sessions
30
+ returning([]) do |sess|
31
+ send_cmd "show sess" do |line|
32
+ sess << line
33
+ end
34
+ end
35
+ end
36
+
37
+ TYPES = {
38
+ :frontend => 1,
39
+ :backend => 2,
40
+ :server => 4
41
+ }
42
+
43
+ def stats(types=[:all], options={})
44
+ params = {
45
+ :proxy => :all,
46
+ :server => :all
47
+ }.merge(options)
48
+
49
+ params[:proxy] = "-1" if params[:proxy].eql?(:all)
50
+ params[:server] = "-1" if params[:server].eql?(:all)
51
+
52
+ types = [types] unless types.is_a?(Array)
53
+
54
+ params[:type] = case
55
+ when types.eql?([:all])
56
+ "-1"
57
+ else
58
+ types.map{ |type| TYPES[type] }.inject(:+)
59
+ end
60
+
61
+ cmd = "show stat #{params[:proxy]} #{params[:type]} #{params[:server]}"
62
+
63
+ returning([]) do |stats|
64
+ send_cmd(cmd) do |line|
65
+ stats << CSVParser.parse(line) unless line.start_with?('#')
66
+ end
67
+ end
68
+ end
69
+
70
+ def frontends
71
+ stats :frontend, :proxy => :all, :server => :all
72
+ end
73
+
74
+ def backends
75
+ stats :frontend, :proxy => :all, :server => :all
76
+ end
77
+
78
+ def servers
79
+ stats :server, :proxy => :all, :server => :all
80
+ end
81
+
82
+ protected
83
+
84
+ def send_cmd(cmd, &block)
85
+ socket = UNIXSocket.new(@path)
86
+ socket.puts(cmd)
87
+ socket.each do |line|
88
+ yield(line.strip)
89
+ end
90
+ end
91
+
92
+ end
93
+ end
@@ -0,0 +1,51 @@
1
+ libdir = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
3
+
4
+ module HAProxy
5
+
6
+ class StatsReader
7
+
8
+ def info
9
+ raise NotImplementedError
10
+ end
11
+
12
+ def errors
13
+ raise NotImplementedError
14
+ end
15
+
16
+ def sessions
17
+ raise NotImplementedError
18
+ end
19
+
20
+ def stats
21
+ raise NotImplementedError
22
+ end
23
+
24
+ def frontends
25
+ raise NotImplementedError
26
+ end
27
+
28
+ def backends
29
+ raise NotImplementedError
30
+ end
31
+
32
+ def servers
33
+ raise NotImplementedError
34
+ end
35
+
36
+ protected
37
+
38
+ # Borrowed from Rails 3
39
+ def returning(value)
40
+ yield(value)
41
+ value
42
+ end
43
+
44
+ private
45
+
46
+ def initialize
47
+ end
48
+
49
+ end
50
+
51
+ end
@@ -0,0 +1,3 @@
1
+ module Haproxy
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: haproxy
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 1
9
+ version: 0.0.1
10
+ platform: ruby
11
+ authors:
12
+ - "Leandro L\xC3\xB3pez (inkel)"
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-11-29 00:00:00 -03:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: This gem is intended for use as a HAProxy interface when you need to read statistics or if you like to manage proxies thru Ruby
22
+ email:
23
+ - inkel.ar@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - .gitignore
32
+ - Gemfile
33
+ - Rakefile
34
+ - haproxy.gemspec
35
+ - lib/haproxy.rb
36
+ - lib/haproxy/csv_parser.rb
37
+ - lib/haproxy/socket_reader.rb
38
+ - lib/haproxy/stats_reader.rb
39
+ - lib/haproxy/version.rb
40
+ has_rdoc: true
41
+ homepage: http://rubygems.org/gems/haproxy
42
+ licenses: []
43
+
44
+ post_install_message:
45
+ rdoc_options: []
46
+
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ requirements: []
66
+
67
+ rubyforge_project: haproxy
68
+ rubygems_version: 1.3.7
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: HAProxy interface for reading statistics or managing servers (requires HAProxy 1.4+)
72
+ test_files: []
73
+