Enable syntax check for haproxy.py

Change-Id: I05f4ab978ccb14c2fefb4bd9153790b63e73c530
This commit is contained in:
Swann Croiset 2016-02-11 16:50:43 +01:00
parent 587ce0fd31
commit 3f727dfe1b
2 changed files with 81 additions and 68 deletions

View File

@ -4,7 +4,8 @@
# Substantial additions by Mirantis
# Description: This is a collectd plugin which runs under the Python plugin to
# collect metrics from haproxy.
# Plugin structure and logging func taken from https://github.com/phrawzty/rabbitmq-collectd-plugin
# Plugin structure and logging func taken from
# https://github.com/phrawzty/rabbitmq-collectd-plugin
# Copyright (c) 2011 Michael Leinartas
#
@ -29,43 +30,43 @@
import collectd
import socket
import csv
import socket
NAMES_MAPPING = {}
NAME = 'haproxy'
RECV_SIZE = 1024
METRIC_TYPES = {
'bin': ('bytes_in', 'gauge'),
'bout': ('bytes_out', 'gauge'),
'chkfail': ('failed_checks', 'gauge'),
'CurrConns': ('connections', 'gauge'),
'CurrSslConns': ('ssl_connections', 'gauge'),
'downtime': ('downtime', 'gauge'),
'dresp': ('denied_responses', 'gauge'),
'dreq': ('denied_requests', 'gauge'),
'econ': ('error_connection', 'gauge'),
'ereq': ('error_requests', 'gauge'),
'eresp': ('error_responses', 'gauge'),
'hrsp_1xx': ('response_1xx', 'gauge'),
'hrsp_2xx': ('response_2xx', 'gauge'),
'hrsp_3xx': ('response_3xx', 'gauge'),
'hrsp_4xx': ('response_4xx', 'gauge'),
'hrsp_5xx': ('response_5xx', 'gauge'),
'hrsp_other': ('response_other', 'gauge'),
'PipesUsed': ('pipes_used', 'gauge'),
'PipesFree': ('pipes_free', 'gauge'),
'qcur': ('queue_current', 'gauge'),
'Tasks': ('tasks', 'gauge'),
'Run_queue': ('run_queue', 'gauge'),
'stot': ('session_total', 'gauge'),
'scur': ('session_current', 'gauge'),
'wredis': ('redistributed', 'gauge'),
'wretr': ('retries', 'gauge'),
'status': ('status', 'gauge'),
'Uptime_sec': ('uptime', 'gauge'),
'up': ('up', 'gauge'),
'down': ('down', 'gauge'),
'bin': ('bytes_in', 'gauge'),
'bout': ('bytes_out', 'gauge'),
'chkfail': ('failed_checks', 'gauge'),
'CurrConns': ('connections', 'gauge'),
'CurrSslConns': ('ssl_connections', 'gauge'),
'downtime': ('downtime', 'gauge'),
'dresp': ('denied_responses', 'gauge'),
'dreq': ('denied_requests', 'gauge'),
'econ': ('error_connection', 'gauge'),
'ereq': ('error_requests', 'gauge'),
'eresp': ('error_responses', 'gauge'),
'hrsp_1xx': ('response_1xx', 'gauge'),
'hrsp_2xx': ('response_2xx', 'gauge'),
'hrsp_3xx': ('response_3xx', 'gauge'),
'hrsp_4xx': ('response_4xx', 'gauge'),
'hrsp_5xx': ('response_5xx', 'gauge'),
'hrsp_other': ('response_other', 'gauge'),
'PipesUsed': ('pipes_used', 'gauge'),
'PipesFree': ('pipes_free', 'gauge'),
'qcur': ('queue_current', 'gauge'),
'Tasks': ('tasks', 'gauge'),
'Run_queue': ('run_queue', 'gauge'),
'stot': ('session_total', 'gauge'),
'scur': ('session_current', 'gauge'),
'wredis': ('redistributed', 'gauge'),
'wretr': ('retries', 'gauge'),
'status': ('status', 'gauge'),
'Uptime_sec': ('uptime', 'gauge'),
'up': ('up', 'gauge'),
'down': ('down', 'gauge'),
}
STATUS_MAP = {
@ -77,20 +78,22 @@ FRONTEND_TYPE = '0'
BACKEND_TYPE = '1'
BACKEND_SERVER_TYPE = '2'
METRIC_AGGREGATED = ['bin', 'bout', 'qcur','scur','eresp',
'hrsp_1xx','hrsp_2xx', 'hrsp_3xx', 'hrsp_4xx', 'hrsp_5xx',
'hrsp_other', 'wretr']
METRIC_AGGREGATED = ['bin', 'bout', 'qcur', 'scur', 'eresp',
'hrsp_1xx', 'hrsp_2xx', 'hrsp_3xx', 'hrsp_4xx',
'hrsp_5xx', 'hrsp_other', 'wretr']
METRIC_DELIM = '.' # for the frontend/backend stats
METRIC_DELIM = '.' # for the frontend/backend stats
DEFAULT_SOCKET = '/var/lib/haproxy/stats'
DEFAULT_PROXY_MONITORS = [ 'server', 'frontend', 'backend', 'backend_server' ]
HAPROXY_SOCKET = '/var/lib/haproxy/stats'
DEFAULT_PROXY_MONITORS = ['server', 'frontend', 'backend', 'backend_server']
VERBOSE_LOGGING = False
PROXY_MONITORS = []
PROXY_IGNORE = []
class HAProxySocket(object):
def __init__(self, socket_file=DEFAULT_SOCKET):
def __init__(self, socket_file=HAPROXY_SOCKET):
self.socket_file = socket_file
def connect(self):
@ -99,9 +102,11 @@ class HAProxySocket(object):
return s
def communicate(self, command):
''' Send a single command to the socket and return a single response (raw string) '''
'''Send a command to the socket and return a response (raw string).'''
s = self.connect()
if not command.endswith('\n'): command += '\n'
if not command.endswith('\n'):
command += '\n'
s.send(command)
result = ''
buf = ''
@ -117,21 +122,22 @@ class HAProxySocket(object):
output = self.communicate('show info')
for line in output.splitlines():
try:
key,val = line.split(':')
except ValueError, e:
key, val = line.split(':')
except ValueError:
continue
result[key.strip()] = val.strip()
return result
def get_server_stats(self):
output = self.communicate('show stat')
#sanitize and make a list of lines
# sanitize and make a list of lines
output = output.lstrip('# ').strip()
output = [ l.strip(',') for l in output.splitlines() ]
output = [l.strip(',') for l in output.splitlines()]
csvreader = csv.DictReader(output)
result = [ d.copy() for d in csvreader ]
result = [d.copy() for d in csvreader]
return result
def get_stats():
stats = dict()
haproxy = HAProxySocket(HAPROXY_SOCKET)
@ -139,15 +145,16 @@ def get_stats():
try:
server_info = haproxy.get_server_info()
server_stats = haproxy.get_server_stats()
except socket.error, e:
logger('warn', "status err Unable to connect to HAProxy socket at %s" % HAPROXY_SOCKET)
except socket.error:
logger('warn',
"Unable to connect to HAProxy socket at %s" % HAPROXY_SOCKET)
return stats
if 'server' in PROXY_MONITORS:
for key,val in server_info.items():
for key, val in server_info.items():
try:
stats[key] = int(val)
except (TypeError, ValueError), e:
except (TypeError, ValueError):
pass
for statdict in server_stats:
@ -170,8 +177,12 @@ def get_stats():
if statdict['type'] == BACKEND_SERVER_TYPE:
# Count the number of servers per backend and per status
for status_val in STATUS_MAP.keys():
# Initialize all possible metric keys to zero
metricname = METRIC_DELIM.join(['backend', pxname, 'servers', status_val.lower()])
# Initialize all possible metric keys to zero
metricname = METRIC_DELIM.join(['backend',
pxname,
'servers',
status_val.lower()]
)
if metricname not in stats:
stats[metricname] = 0
if statdict['status'] == status_val:
@ -179,7 +190,9 @@ def get_stats():
continue
for key, val in statdict.items():
metricname = METRIC_DELIM.join([statdict['svname'].lower(), pxname, key])
metricname = METRIC_DELIM.join([statdict['svname'].lower(),
pxname, key]
)
try:
if key == 'status' and statdict['type'] == BACKEND_TYPE:
if val in STATUS_MAP:
@ -188,20 +201,19 @@ def get_stats():
continue
stats[metricname] = int(val)
if key in METRIC_AGGREGATED:
agg_metricname = METRIC_DELIM.join([statdict['svname'].lower(), key])
agg_metricname = METRIC_DELIM.join(
[statdict['svname'].lower(), key]
)
if agg_metricname not in stats:
stats[agg_metricname] = 0
stats[agg_metricname] += int(val)
except (TypeError, ValueError), e:
except (TypeError, ValueError):
pass
return stats
def configure_callback(conf):
global PROXY_MONITORS, PROXY_IGNORE, HAPROXY_SOCKET, VERBOSE_LOGGING
PROXY_MONITORS = [ ]
PROXY_IGNORE = [ ]
HAPROXY_SOCKET = DEFAULT_SOCKET
VERBOSE_LOGGING = False
for node in conf.children:
if node.key == "ProxyMonitor":
@ -219,7 +231,8 @@ def configure_callback(conf):
if not PROXY_MONITORS:
PROXY_MONITORS += DEFAULT_PROXY_MONITORS
PROXY_MONITORS = [ p.lower() for p in PROXY_MONITORS ]
PROXY_MONITORS = [p.lower() for p in PROXY_MONITORS]
def read_callback():
logger('verb', "beginning read_callback")
@ -229,26 +242,27 @@ def read_callback():
logger('warn', "%s: No data received" % NAME)
return
for key,value in info.items():
for key, value in info.items():
key_prefix = ''
key_root = key
if not value in METRIC_TYPES:
if value not in METRIC_TYPES:
try:
key_prefix, key_root = key.rsplit(METRIC_DELIM,1)
except ValueError, e:
key_prefix, key_root = key.rsplit(METRIC_DELIM, 1)
except ValueError:
pass
if not key_root in METRIC_TYPES:
if key_root not in METRIC_TYPES:
continue
key_root, val_type = METRIC_TYPES[key_root]
key_name = METRIC_DELIM.join([ n for n in [key_prefix, key_root] if n ])
key_name = METRIC_DELIM.join([n for n in [key_prefix, key_root] if n])
val = collectd.Values(plugin=NAME, type=val_type)
val.type_instance = key_name
val.values = [ value ]
val.values = [value]
# w/a for https://github.com/collectd/collectd/issues/716
val.meta = {'0': True}
val.dispatch()
def logger(t, msg):
if t == 'err':
collectd.error('%s: %s' % (NAME, msg))

View File

@ -52,7 +52,6 @@ commands =
[flake8]
ignore = H105,H201,E241,H401
exclude = haproxy.py
show-source = True
[testenv:collectd_python]