#!/usr/bin/env python2 import argparse import json import prettytable import time import sys import signal import os TBPS = (1 * 1000 * 1000 * 1000 * 1000) GBPS = (1 * 1000 * 1000 * 1000) MBPS = (1 * 1000 * 1000) KBPS = (1 * 1000) G_JSON_PATH = '/var/run/mrzcpd/mrmonit.daemon' G_APP_JSON_PATH = '/var/run/mrzcpd/mrmonit.app.%s' TITLE_VECTOR = ['PhyRXFrame','PhyRXBits','PhyRXMissed','PhyRXError', 'PhyRXNoBUF','PhyTXFrame','PhyTXBits','PhyTXError', 'UsrRXDrops', 'UsrTXDrops'] TITLE_MAP = { 'PhyRXFrame' : 'ipackets', 'PhyRXBits' : 'ibytes', 'PhyRXMissed' : 'imissed', 'PhyRXError' : 'ierrors', 'PhyRXNoBUF' : 'rxnombuf', 'PhyTXFrame' : 'opackets', 'PhyTXBits' : 'obytes', 'PhyTXError' : 'oerrors', 'UsrRXDrops' : 'userrxdrop', 'UsrTXDrops' : 'usertxdrop' } def locate_vector_by_symbol(vector, symbol): return [s for s in vector if s['symbol'] == symbol] def list_all_phydev(json_fp): return [ s['symbol'] for s in json_fp['device']] def phydev_value_read(json_fp, str_device, str_item): phydevs = locate_vector_by_symbol(json_fp['device'], str_device) return phydevs[0]['stats']['accumulative'][str_item] def phydev_speed_read(json_fp, str_device, str_item): phydevs = locate_vector_by_symbol(json_fp['device'], str_device) return phydevs[0]['stats']['speed'][str_item] def app_stat_read(json_fp, item): return json_fp["appstat"][item] def app_json_load(appsym): with open(G_APP_JSON_PATH % appsym) as json_fp: return json.load(json_fp) def trans_to_human_readable(value): if value > TBPS: return value * 1.0 / TBPS, 'T' if value > GBPS: return value * 1.0 / GBPS, 'G' if value > MBPS: return value * 1.0 / MBPS, 'M' if value > KBPS: return value * 1.0 / KBPS, 'K' return value * 1.0, ' ' def dump_physical_devices(json_fp, phydev_user_list): print("------------------------------------------------------------------------------------------------------------------------"); print(" Network Ports Statistics "); print("------------------------------------------------------------------------------------------------------------------------"); for devsym in phydev_user_list: print("Port %s" % devsym) print("RX: packets%20lu | bytes:%20lu | dropped: %10lu | fps:%s | bps: %s" % \ (phydev_value_read(json_fp, devsym, 'ipackets'), phydev_value_read(json_fp, devsym, 'ibytes'), phydev_value_read(json_fp, devsym, 'imissed'), "%7.2f%c" % trans_to_human_readable(phydev_speed_read(json_fp, devsym, 'ipackets')), "%7.2f%c" % trans_to_human_readable(phydev_speed_read(json_fp, devsym, 'ibytes')))) print("TX: packets%20lu | bytes:%20lu | dropped: %10lu | fps:%s | bps: %s" % (phydev_value_read(json_fp, devsym, 'opackets'), phydev_value_read(json_fp, devsym, 'obytes'), phydev_value_read(json_fp, devsym, 'usertxdrop'), "%7.2f%c" % trans_to_human_readable(phydev_speed_read(json_fp, devsym, 'opackets')), "%7.2f%c" % trans_to_human_readable(phydev_speed_read(json_fp, devsym, 'obytes')))) return def dump_app_status(json_fp): print("------------------------------------------------------------------------------------------------------------------------") print(" Worker(Client Process) Statistics ") print("------------------------------------------------------------------------------------------------------------------------") nr_thread = len(app_stat_read(json_fp, 'packet_recv_count')) for thread_id in range(nr_thread): print("WORKER %2d | packets %20lu | bytes: %20lu | dropped: %12lu | runtime %7.2f" % \ (thread_id, app_stat_read(json_fp, 'packet_recv_count')[thread_id], app_stat_read(json_fp, 'packet_recv_length')[thread_id], app_stat_read(json_fp, 'packet_recv_drop')[thread_id] + app_stat_read(json_fp, 'packet_send_drop')[thread_id], 0)) return def dump_tail(): print("------------------------------------------------------------------------------------------------------------------------"); def setup_argv_parser(phydev_list): parser = argparse.ArgumentParser(description='Marsio ZeroCopy Tools -- DLOGREADER', version = 'Marsio ZeroCopy Tools Suite 4.1') parser.add_argument('-t', '--time', help = 'interval, seconds to wait between updates', type=int, default = 1) parser.add_argument('-l', '--loop', help = 'print loop, exit when recv a signal', action='store_true', default = 0) parser.add_argument('--clear-screen', help = 'clear screen at start of loop', action='store_true', default = 1) parser.add_argument('-a', '--app', help = 'application symbol', type=str, default = 'sapp') return parser.parse_args() def phydev_json_load(): with open(G_JSON_PATH) as json_fp: return json.load(json_fp) def sigint_handler(handler, frame): sys.exit(0) def main(): signal.signal(signal.SIGINT, sigint_handler) try: json_fp = phydev_json_load() phydev_list = list_all_phydev(json_fp) r_option = setup_argv_parser(phydev_list) while True: if r_option.clear_screen: os.system('clear') json_fp = phydev_json_load() dump_physical_devices(json_fp, phydev_list) app_json_fp = app_json_load(r_option.app) dump_app_status(app_json_fp) dump_tail() if not r_option.loop: break time.sleep(r_option.time) except KeyboardInterrupt: pass except ValueError as err: print(("%s, perhaps mrzcpd program is not running.") % str(err)) except IOError as err: print(("%s, perhaps mrzcpd program is not running.") % str(err)) return 0 if __name__ == '__main__': main()