Skip to content

Instantly share code, notes, and snippets.

@TvL2386
Last active June 4, 2018 09:38
Show Gist options
  • Save TvL2386/2873cfecd7d2a3c71710b61cbe04c436 to your computer and use it in GitHub Desktop.
Save TvL2386/2873cfecd7d2a3c71710b61cbe04c436 to your computer and use it in GitHub Desktop.
Ruby haproxy statistics script
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