#!/usr/bin/python3 import argparse import datetime import os import subprocess ########################################################################### # BEGIN FUNCTIONS ########################################################################### def parse_haproxy_stats(line): haproxy_dict = {} line_as_dict = line.rstrip(",\n").split(",") index = 0 for item in line_as_dict: field_name = field_name_list[index] haproxy_dict[field_name] = item index = index + 1 return haproxy_dict def refresh_cache_file(): CMD = 'echo "show stat" | socat /run/haproxy/monitoring.sock stdio > ' + stat_file + ".tmp" # noqa: N806 RESULT = subprocess.check_output(CMD, shell=True) # noqa: N806, F841 os.rename(stat_file + ".tmp", stat_file) # noqa: PTH104 ########################################################################### # END FUNCTIONS - BEGIN PARSER ########################################################################### # begin parser parser = argparse.ArgumentParser( description="return a specific stat for a specific pxname and svname, it uses a cache file that is automatically refreshed if it is older than 1 minute" ) parser.add_argument( "--pxname", help="this is the name of the backend, frontend or server exactly as it appears in the configuration", type=str, required=True, ) parser.add_argument( "--svname", help="the type of the service, either FRONTEND, BACKEND or the name of the server", type=str, required=True, ) parser.add_argument("--stat", help="the stat wanted", type=str, required=True) args = parser.parse_args() ########################################################################### # END PARSER - BEGIN PROGRAM ########################################################################### stat_file = "/dev/shm/haproxy_stat.txt" localtime = datetime.datetime.now() maxage = datetime.timedelta(seconds=60) if os.path.isfile(stat_file): # noqa: PTH113 last_modified_date = datetime.datetime.fromtimestamp(os.path.getmtime(stat_file)) # noqa: PTH204 if localtime - last_modified_date > maxage: # the cache file is too old, let's refresh it refresh_cache_file() else: # the cache file doesn't exists, so we need to create it refresh_cache_file() # transform the stat file into a dict, line by line with open(stat_file) as stat: # noqa: PTH123 stat_by_line = stat.readlines() # the first element of the dict contains the name of the fields field_name_list = stat_by_line[0].rstrip(",\n").lstrip("# ").split(",") # we don't care about the first element now, remove it from the dict del stat_by_line[0] # the last element of the dict is an empty line, remove it too del stat_by_line[-1] # define the final object that we will query for the stats STATS_AS_LIST = [] # populate the final object for line in stat_by_line: STATS_AS_LIST.append(parse_haproxy_stats(line)) # Search for the final object with pxname and svname CORRECT_LINE = next( (query for query in STATS_AS_LIST if query["pxname"] == args.pxname and query["svname"] == args.svname), None ) # Print the stat if a matching element is found, otherwise print "non-existent" print(CORRECT_LINE[args.stat] if CORRECT_LINE else "non-existent")