haproxy 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/Rakefile +2 -0
- data/haproxy.gemspec +21 -0
- data/lib/haproxy.rb +21 -0
- data/lib/haproxy/csv_parser.rb +32 -0
- data/lib/haproxy/socket_reader.rb +93 -0
- data/lib/haproxy/stats_reader.rb +51 -0
- data/lib/haproxy/version.rb +3 -0
- metadata +73 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
data/haproxy.gemspec
ADDED
@@ -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
|
data/lib/haproxy.rb
ADDED
@@ -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
|
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
|
+
|