Last active
June 4, 2018 09:38
-
-
Save TvL2386/2873cfecd7d2a3c71710b61cbe04c436 to your computer and use it in GitHub Desktop.
Ruby haproxy statistics script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'net/http' | |
require 'csv' | |
require 'json' | |
class HaproxyStats | |
NAMES = { | |
pxname: 'Proxy Name', | |
svname: 'Service name', | |
qcur: 'Current queue', | |
qmax: 'Maximum queue', | |
scur: 'Current sessions', | |
smax: 'Maximum sessions', | |
slim: 'Session limit', | |
stot: 'Sessions total', | |
bin: 'Bytes In', | |
bout: 'Bytes Out', | |
dreq: 'Denied requests', | |
dresp: 'Denied responses', | |
ereq: 'Request errors', | |
econ: 'Error connections', | |
eresp: 'Error responses', | |
wretr: 'Connections retries', | |
wredis: 'Redispatches', | |
status: 'Status', | |
weight: 'Weight', | |
act: 'Active servers', | |
bck: 'Backup servers', | |
chkfail: 'Failed checks', | |
chkdown: 'Downed', | |
lastchg: 'Since last down', | |
downtime: 'Downtime', | |
qlimit: 'Queue limit', | |
pid: 'PID', | |
iid: 'Unique ID', | |
sid: 'Server ID', | |
rate: 'Session rate', | |
rate_lim: 'Session rate limit', | |
rate_max: 'Max. session rate', | |
check_status: 'Check status', | |
check_code: 'Check code', | |
check_duration: 'Check duration', | |
hrsp_1xx: 'HTTP 1xx', | |
hrsp_2xx: 'HTTP 2xx', | |
hrsp_3xx: 'HTTP 3xx', | |
hrsp_4xx: 'HTTP 4xx', | |
hrsp_5xx: 'HTTP 5xx', | |
hrsp_other: 'HTTP Other', | |
req_rate: 'HTTP request rate', | |
req_rate_max: 'Max HTTP request rate', | |
req_tot: 'Total HTTP requests' | |
} | |
UNITS = { | |
qcur: 'Count', | |
qmax: 'Count', | |
scur: 'Count', | |
smax: 'Count', | |
slim: 'Count', | |
stot: 'Count', | |
bin: 'BytesBandwidth', | |
bout: 'BytesBandwidth', | |
dreq: 'Count', | |
dresp: 'Count', | |
ereq: 'Count', | |
econ: 'Count', | |
eresp: 'Count', | |
wretr: 'Count', | |
wredis: 'Count', | |
status: 'Count', | |
weight: 'Custom', | |
act: 'Count', | |
bck: 'Count', | |
chkfail: 'Count', | |
chkdown: 'Count', | |
lastchg: 'TimeSeconds', | |
downtime: 'TimeSeconds', | |
qlimit: 'Count', | |
pid: 'Custom', | |
iid: 'Custom', | |
sid: 'Custom', | |
rate: 'Count', | |
rate_lim: 'Count', | |
rate_max: 'Count', | |
check_status: 'Custom', | |
check_code: 'Custom', | |
check_duration: 'TimeSeconds', | |
hrsp_1xx: 'Count', | |
hrsp_2xx: 'Count', | |
hrsp_3xx: 'Count', | |
hrsp_4xx: 'Count', | |
hrsp_5xx: 'Count', | |
hrsp_other: 'Count', | |
req_rate: 'Count', | |
req_rate_max: 'Count', | |
req_tot: 'Count' | |
} | |
TEMPLATES = { | |
standard: %w(qcur smax scur smax slim stot bin bout) | |
} | |
def initialize(url, name, template=nil) | |
@url = url | |
@name = name | |
@template = template || :standard | |
@processed = false | |
@results = [] | |
end | |
def process | |
return nil if @processed | |
uri = URI.parse @url | |
http = Net::HTTP.new(uri.host, uri.port) | |
# http.set_debug_output $stderr | |
http.use_ssl = (uri.scheme == 'https') | |
request = Net::HTTP::Get.new(uri.request_uri) | |
response = http.request(request) | |
if response.code == '200' | |
# remove the comment from the first header | |
@content = response.body.gsub(/^#\s/, '') | |
CSV.parse(@content, headers: true) do |row| | |
row.each do |key, value| | |
next if value.nil? | |
next if row['pxname'] !~ /#{@name}/ | |
if interesting_keys.include?(key) | |
channel = [] | |
channel << row['svname'] | |
channel << NAMES[key.to_sym] | |
channel.delete(nil) | |
result = { | |
'channel' => channel.join(' '), | |
'value' => value, | |
'unit' => UNITS[key.to_sym], | |
} | |
@results << { 'result' => result } | |
end | |
end | |
end | |
end | |
@processed = true | |
end | |
def to_json | |
obj = { 'prtg' => @results } | |
JSON.pretty_generate(obj) | |
end | |
private | |
def interesting_keys | |
TEMPLATES[@template] | |
end | |
end | |
abort("Usage: #{$0} <url> <name>") unless ARGV.length == 2 | |
hs = HaproxyStats.new(*ARGV) | |
hs.process | |
puts hs.to_json |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment