def build_stats_message(): global SEQ msg = {'id': CONF.amphora_agent.amphora_id, 'seq': SEQ, "listeners": {}, 'ver': MSG_VER} SEQ += 1 stat_sock_files = list_sock_stat_files() for listener_id, stat_sock_file in stat_sock_files.items(): listener_dict = {'pools': {}, 'status': 'DOWN', 'stats': { 'tx': 0, 'rx': 0, 'conns': 0, 'totconns': 0, 'ereq': 0}} msg['listeners'][listener_id] = listener_dict if util.is_listener_running(listener_id): (stats, pool_status) = get_stats(stat_sock_file) listener_dict = msg['listeners'][listener_id] for row in stats: if row['svname'] == 'FRONTEND': listener_dict['stats']['tx'] = int(row['bout']) listener_dict['stats']['rx'] = int(row['bin']) listener_dict['stats']['conns'] = int(row['scur']) listener_dict['stats']['totconns'] = int(row['stot']) listener_dict['stats']['ereq'] = int(row['ereq']) listener_dict['status'] = row['status'] for oid, pool in pool_status.items(): if oid != listener_id: pool_id = oid pools = listener_dict['pools'] pools[pool_id] = {"status": pool['status'], "members": pool['members']} # UDP listener part udp_listener_ids = util.get_udp_listeners() if udp_listener_ids: listeners_stats = keepalivedlvs_query.get_udp_listeners_stats() if listeners_stats: for listener_id, listener_stats in listeners_stats.items(): pool_status = keepalivedlvs_query.get_udp_listener_pool_status( listener_id) udp_listener_dict = dict() udp_listener_dict['status'] = listener_stats['status'] udp_listener_dict['stats'] = { 'tx': listener_stats['stats']['bout'], 'rx': listener_stats['stats']['bin'], 'conns': listener_stats['stats']['scur'], 'totconns': listener_stats['stats']['stot'], 'ereq': listener_stats['stats']['ereq'] } udp_listener_dict['pools'] = {} if pool_status: udp_listener_dict['pools'] = { pool_status['lvs']['uuid']: { "status": pool_status['lvs']['status'], "members": pool_status['lvs']['members']}} msg['listeners'][listener_id] = udp_listener_dict return msg
def compile_amphora_details(self, extend_udp_driver=None): haproxy_listener_list = sorted(util.get_listeners()) extend_body = {} udp_listener_list = [] if extend_udp_driver: udp_listener_list = util.get_udp_listeners() extend_data = self._get_extend_body_from_udp_driver( extend_udp_driver) udp_count = self._count_udp_listener_processes(extend_udp_driver, udp_listener_list) extend_body['udp_listener_process_count'] = udp_count extend_body.update(extend_data) meminfo = self._get_meminfo() cpu = self._cpu() st = os.statvfs('/') body = {'hostname': socket.gethostname(), 'haproxy_version': self._get_version_of_installed_package('haproxy'), 'api_version': api_server.VERSION, 'networks': self._get_networks(), 'active': True, 'haproxy_count': self._count_haproxy_processes(haproxy_listener_list), 'cpu': { 'total': cpu['total'], 'user': cpu['user'], 'system': cpu['system'], 'soft_irq': cpu['softirq'], }, 'memory': { 'total': meminfo['MemTotal'], 'free': meminfo['MemFree'], 'buffers': meminfo['Buffers'], 'cached': meminfo['Cached'], 'swap_used': meminfo['SwapCached'], 'shared': meminfo['Shmem'], 'slab': meminfo['Slab'], }, 'disk': { 'used': (st.f_blocks - st.f_bfree) * st.f_frsize, 'available': st.f_bavail * st.f_frsize}, 'load': self._load(), 'topology': consts.TOPOLOGY_SINGLE, 'topology_status': consts.TOPOLOGY_STATUS_OK, 'listeners': sorted(list( set(haproxy_listener_list + udp_listener_list))) if udp_listener_list else haproxy_listener_list, 'packages': {}} if extend_body: body.update(extend_body) return webob.Response(json=body)
def get_all_udp_listeners_status(self): """Gets the status of all UDP listeners Gets the status of all UDP listeners on the amphora. """ listeners = list() for udp_listener in util.get_udp_listeners(): status = self._check_udp_listener_status(udp_listener) listeners.append({ 'status': status, 'uuid': udp_listener, 'type': 'UDP', }) return listeners
def get_all_udp_listeners_status(self): """Gets the status of all UDP listeners Gets the status of all UDP listeners on the amphora. """ listeners = list() for udp_listener in util.get_udp_listeners(): status = self._check_udp_listener_status(udp_listener) listeners.append({ 'status': status, 'uuid': udp_listener, 'type': 'UDP', }) return listeners
def get_udp_listeners_stats(): udp_listener_ids = util.get_udp_listeners() need_check_listener_ids = [ listener_id for listener_id in udp_listener_ids if util.is_udp_listener_running(listener_id) ] ipport_mapping = dict() listener_stats_res = dict() for check_listener_id in need_check_listener_ids: # resource_ipport_mapping = {'Listener': {'id': listener-id, # 'ipport': ipport}, # 'Pool': {'id': pool-id}, # 'Members': [{'id': member-id-1, # 'ipport': ipport}, # {'id': member-id-2, # 'ipport': ipport}], # 'HealthMonitor': {'id': healthmonitor-id}} (resource_ipport_mapping, ns_name) = get_udp_listener_resource_ipports_nsname(check_listener_id) # Since we found the keepalived running, acknowledge the listener # in the heartbeat. If this listener has a pool and members, # the stats will be updated later in the code flow. listener_stats_res.update({ check_listener_id: { 'stats': { 'bout': 0, 'bin': 0, 'scur': 0, 'stot': 0, 'ereq': 0 }, 'status': constants.OPEN } }) # If we can not read the lvs configuration from file, that means # the pool of this listener may own zero enabled member, but the # keepalived process is running. So we need to skip it. if not resource_ipport_mapping: continue ipport_mapping.update({check_listener_id: resource_ipport_mapping}) # So here, if we can not get any ipport_mapping, # we do nothing, just return if not ipport_mapping: return listener_stats_res # contains bout, bin, scur, stot, ereq, status # bout(OutBytes), bin(InBytes), stot(Conns) from cmd ipvsadm -Ln --stats # scur(ActiveConn) from cmd ipvsadm -Ln # status, can see configuration in any cmd, treat it as OPEN # ereq is still 0, as UDP case does not support it. scur_res = get_ipvsadm_info(constants.AMPHORA_NAMESPACE) stats_res = get_ipvsadm_info(constants.AMPHORA_NAMESPACE, is_stats_cmd=True) for listener_id, ipport in ipport_mapping.items(): listener_ipport = ipport['Listener']['ipport'] # This would be in Error, wait for the next loop to sync for the # listener at this moment. Also this is for skip the case no enabled # member in UDP listener, so we don't check it for failover. if listener_ipport not in scur_res or listener_ipport not in stats_res: continue scur, bout, bin, stot, ereq = 0, 0, 0, 0, 0 # As all results contain this listener, so its status should be OPEN status = constants.OPEN # Get scur for m in scur_res[listener_ipport]['Members']: for item in m: if item[0] == 'ActiveConn': scur += int(item[1]) # Get bout, bin, stot for item in stats_res[listener_ipport]['Listener']: if item[0] == 'Conns': stot = int(item[1]) elif item[0] == 'OutBytes': bout = int(item[1]) elif item[0] == 'InBytes': bin = int(item[1]) listener_stats_res.update({ listener_id: { 'stats': { 'bout': bout, 'bin': bin, 'scur': scur, 'stot': stot, 'ereq': ereq }, 'status': status } }) return listener_stats_res
def build_stats_message(): # Example version 2 message without UDP: # { # "id": "<amphora_id>", # "seq": 67, # "listeners": { # "<listener_id>": { # "status": "OPEN", # "stats": { # "tx": 0, # "rx": 0, # "conns": 0, # "totconns": 0, # "ereq": 0 # } # } # }, # "pools": { # "<pool_id>:<listener_id>": { # "status": "UP", # "members": { # "<member_id>": "no check" # } # } # }, # "ver": 2 # } global SEQ msg = { 'id': CONF.amphora_agent.amphora_id, 'seq': SEQ, 'listeners': {}, 'pools': {}, 'ver': MSG_VER } SEQ += 1 stat_sock_files = list_sock_stat_files() # TODO(rm_work) There should only be one of these in the new config system for lb_id, stat_sock_file in stat_sock_files.items(): if util.is_lb_running(lb_id): (stats, pool_status) = get_stats(stat_sock_file) for row in stats: if row['svname'] == 'FRONTEND': listener_id = row['pxname'] msg['listeners'][listener_id] = { 'status': row['status'], 'stats': { 'tx': int(row['bout']), 'rx': int(row['bin']), 'conns': int(row['scur']), 'totconns': int(row['stot']), 'ereq': int(row['ereq']) } } for pool_id, pool in pool_status.items(): msg['pools'][pool_id] = { "status": pool['status'], "members": pool['members'] } # UDP listener part udp_listener_ids = util.get_udp_listeners() if udp_listener_ids: listeners_stats = keepalivedlvs_query.get_udp_listeners_stats() if listeners_stats: for listener_id, listener_stats in listeners_stats.items(): pool_status = keepalivedlvs_query.get_udp_listener_pool_status( listener_id) udp_listener_dict = dict() udp_listener_dict['status'] = listener_stats['status'] udp_listener_dict['stats'] = { 'tx': listener_stats['stats']['bout'], 'rx': listener_stats['stats']['bin'], 'conns': listener_stats['stats']['scur'], 'totconns': listener_stats['stats']['stot'], 'ereq': listener_stats['stats']['ereq'] } if pool_status: pool_id = pool_status['lvs']['uuid'] msg['pools'][pool_id] = { "status": pool_status['lvs']['status'], "members": pool_status['lvs']['members'] } msg['listeners'][listener_id] = udp_listener_dict return msg
def build_stats_message(): global SEQ msg = {'id': CONF.amphora_agent.amphora_id, 'seq': SEQ, "listeners": {}} SEQ += 1 stat_sock_files = list_sock_stat_files() for listener_id, stat_sock_file in stat_sock_files.items(): listener_dict = { 'pools': {}, 'status': 'DOWN', 'stats': { 'tx': 0, 'rx': 0, 'conns': 0, 'totconns': 0, 'ereq': 0 } } msg['listeners'][listener_id] = listener_dict if util.is_listener_running(listener_id): (stats, pool_status) = get_stats(stat_sock_file) listener_dict = msg['listeners'][listener_id] for row in stats: if row['svname'] == 'FRONTEND': listener_dict['stats']['tx'] = int(row['bout']) listener_dict['stats']['rx'] = int(row['bin']) listener_dict['stats']['conns'] = int(row['scur']) listener_dict['stats']['totconns'] = int(row['stot']) listener_dict['stats']['ereq'] = int(row['ereq']) listener_dict['status'] = row['status'] for oid, pool in pool_status.items(): if oid != listener_id: pool_id = oid pools = listener_dict['pools'] pools[pool_id] = { "status": pool['status'], "members": pool['members'] } # UDP listener part udp_listener_ids = util.get_udp_listeners() if udp_listener_ids: listeners_stats = keepalivedlvs_query.get_udp_listeners_stats() if listeners_stats: for listener_id, listener_stats in listeners_stats.items(): pool_status = keepalivedlvs_query.get_udp_listener_pool_status( listener_id) udp_listener_dict = dict() udp_listener_dict['status'] = listener_stats['status'] udp_listener_dict['stats'] = { 'tx': listener_stats['stats']['bout'], 'rx': listener_stats['stats']['bin'], 'conns': listener_stats['stats']['scur'], 'totconns': listener_stats['stats']['stot'], 'ereq': listener_stats['stats']['ereq'] } if pool_status: udp_listener_dict['pools'] = { pool_status['lvs']['uuid']: { "status": pool_status['lvs']['status'], "members": pool_status['lvs']['members'] } } msg['listeners'][listener_id] = udp_listener_dict return msg
def get_udp_listeners_stats(): udp_listener_ids = util.get_udp_listeners() need_check_listener_ids = [ listener_id for listener_id in udp_listener_ids if util.is_udp_listener_running(listener_id)] ipport_mapping = dict() listener_stats_res = dict() for check_listener_id in need_check_listener_ids: # resource_ipport_mapping = {'Listener': {'id': listener-id, # 'ipport': ipport}, # 'Pool': {'id': pool-id}, # 'Members': [{'id': member-id-1, # 'ipport': ipport}, # {'id': member-id-2, # 'ipport': ipport}], # 'HealthMonitor': {'id': healthmonitor-id}} (resource_ipport_mapping, ns_name) = get_udp_listener_resource_ipports_nsname(check_listener_id) # Since we found the keepalived running, acknowledge the listener # in the heartbeat. If this listener has a pool and members, # the stats will be updated later in the code flow. listener_stats_res.update({ check_listener_id: { 'stats': { 'bout': 0, 'bin': 0, 'scur': 0, 'stot': 0, 'ereq': 0}, 'status': constants.OPEN}}) # If we can not read the lvs configuration from file, that means # the pool of this listener may own zero enabled member, but the # keepalived process is running. So we need to skip it. if not resource_ipport_mapping: continue ipport_mapping.update({check_listener_id: resource_ipport_mapping}) # So here, if we can not get any ipport_mapping, # we do nothing, just return if not ipport_mapping: return listener_stats_res # contains bout, bin, scur, stot, ereq, status # bout(OutBytes), bin(InBytes), stot(Conns) from cmd ipvsadm -Ln --stats # scur(ActiveConn) from cmd ipvsadm -Ln # status, can see configuration in any cmd, treat it as OPEN # ereq is still 0, as UDP case does not support it. scur_res = get_ipvsadm_info(constants.AMPHORA_NAMESPACE) stats_res = get_ipvsadm_info(constants.AMPHORA_NAMESPACE, is_stats_cmd=True) for listener_id, ipport in ipport_mapping.items(): listener_ipport = ipport['Listener']['ipport'] # This would be in Error, wait for the next loop to sync for the # listener at this moment. Also this is for skip the case no enabled # member in UDP listener, so we don't check it for failover. if listener_ipport not in scur_res or listener_ipport not in stats_res: continue scur, bout, bin, stot, ereq = 0, 0, 0, 0, 0 # As all results contain this listener, so its status should be OPEN status = constants.OPEN # Get scur for m in scur_res[listener_ipport]['Members']: for item in m: if item[0] == 'ActiveConn': scur += int(item[1]) # Get bout, bin, stot for item in stats_res[listener_ipport]['Listener']: if item[0] == 'Conns': stot = int(item[1]) elif item[0] == 'OutBytes': bout = int(item[1]) elif item[0] == 'InBytes': bin = int(item[1]) listener_stats_res.update({ listener_id: { 'stats': { 'bout': bout, 'bin': bin, 'scur': scur, 'stot': stot, 'ereq': ereq}, 'status': status}}) return listener_stats_res
def build_stats_message(): """Build a stats message based on retrieved listener statistics. Example version 3 message without UDP (note that values are deltas, not absolutes):: {"id": "<amphora_id>", "seq": 67, "listeners": { "<listener_id>": { "status": "OPEN", "stats": { "tx": 0, "rx": 0, "conns": 0, "totconns": 0, "ereq": 0 } } }, "pools": { "<pool_id>:<listener_id>": { "status": "UP", "members": { "<member_id>": "no check" } } }, "ver": 3 } """ global SEQ msg = { 'id': CONF.amphora_agent.amphora_id, 'seq': SEQ, 'listeners': {}, 'pools': {}, 'ver': MSG_VER } SEQ += 1 stat_sock_files = list_sock_stat_files() # TODO(rm_work) There should only be one of these in the new config system for lb_id, stat_sock_file in stat_sock_files.items(): if util.is_lb_running(lb_id): (stats, pool_status) = get_stats(stat_sock_file) for row in stats: if row['svname'] == 'FRONTEND': listener_id = row['pxname'] delta_values = calculate_stats_deltas(listener_id, row) msg['listeners'][listener_id] = { 'status': row['status'], 'stats': { 'tx': delta_values['bout'], 'rx': delta_values['bin'], 'conns': int(row['scur']), 'totconns': delta_values['stot'], 'ereq': delta_values['ereq'] } } for pool_id, pool in pool_status.items(): msg['pools'][pool_id] = { "status": pool['status'], "members": pool['members'] } # UDP listener part udp_listener_ids = util.get_udp_listeners() if udp_listener_ids: listeners_stats = keepalivedlvs_query.get_udp_listeners_stats() if listeners_stats: for listener_id, listener_stats in listeners_stats.items(): delta_values = calculate_stats_deltas(listener_id, listener_stats['stats']) pool_status = keepalivedlvs_query.get_udp_listener_pool_status( listener_id) udp_listener_dict = dict() udp_listener_dict['status'] = listener_stats['status'] udp_listener_dict['stats'] = { 'tx': delta_values['bout'], 'rx': delta_values['bin'], 'conns': listener_stats['stats']['scur'], 'totconns': delta_values['stot'], 'ereq': delta_values['ereq'] } if pool_status: pool_id = pool_status['lvs']['uuid'] msg['pools'][pool_id] = { "status": pool_status['lvs']['status'], "members": pool_status['lvs']['members'] } msg['listeners'][listener_id] = udp_listener_dict persist_counters() return msg