diff --git a/scripts/portstat b/scripts/portstat index c63a7fe234..63b7a89be2 100755 --- a/scripts/portstat +++ b/scripts/portstat @@ -27,10 +27,10 @@ PORT_RATE = 40 NStats = namedtuple("NStats", "rx_ok, rx_err, rx_drop, rx_ovr, tx_ok,\ tx_err, tx_drop, tx_ovr, rx_byt, tx_byt") -header_all = ['Iface', 'ADMIN', 'OPER', 'RX_OK', 'RX_BPS', 'RX_PPS', 'RX_UTIL', 'RX_ERR', 'RX_DRP', 'RX_OVR', +header_all = ['IFACE', 'STATE', 'RX_OK', 'RX_BPS', 'RX_PPS', 'RX_UTIL', 'RX_ERR', 'RX_DRP', 'RX_OVR', 'TX_OK', 'TX_BPS', 'Tx_PPS', 'TX_UTIL', 'TX_ERR', 'TX_DRP', 'TX_OVR'] -header = ['Iface', 'ADMIN', 'OPER', 'RX_OK', 'RX_BPS', 'RX_UTIL', 'RX_ERR', 'RX_DRP', 'RX_OVR', +header = ['IFACE', 'STATE', 'RX_OK', 'RX_BPS', 'RX_UTIL', 'RX_ERR', 'RX_DRP', 'RX_OVR', 'TX_OK', 'TX_BPS', 'TX_UTIL', 'TX_ERR', 'TX_DRP', 'TX_OVR'] counter_bucket_dict = { @@ -48,11 +48,20 @@ counter_bucket_dict = { 'SAI_PORT_STAT_IF_OUT_OCTETS': 9 } +STATUS_NA = 'N/A' + COUNTER_TABLE_PREFIX = "COUNTERS:" COUNTERS_PORT_NAME_MAP = "COUNTERS_PORT_NAME_MAP" + PORT_STATUS_TABLE_PREFIX = "PORT_TABLE:" PORT_OPER_STATUS_FIELD = "oper_status" PORT_ADMIN_STATUS_FIELD = "admin_status" +PORT_STATUS_VALUE_UP = 'UP' +PORT_STATUS_VALUE_DOWN = 'DOWN' + +PORT_STATE_UP = 'U' +PROT_STATE_DOWN = 'D' +PORT_STATE_DISABLED = 'X' class Portstat(object): def __init__(self): @@ -73,8 +82,8 @@ class Portstat(object): full_table_id = COUNTER_TABLE_PREFIX + table_id counter_data = self.db.get(self.db.COUNTERS_DB, full_table_id, counter_name) if counter_data is None: - fields[pos] = "N/A" - elif fields[pos] != "N/A": + fields[pos] = STATUS_NA + elif fields[pos] != STATUS_NA: fields[pos] = str(int(fields[pos]) + int(counter_data)) cntr = NStats._make(fields) return cntr @@ -90,16 +99,23 @@ class Portstat(object): cnstat_dict[port] = get_counters(counter_port_name_map[port]) return cnstat_dict - def get_port_status(self, port_name, status_type): + def get_port_state(self, port_name): """ - Get the port status + Get the port state """ full_table_id = PORT_STATUS_TABLE_PREFIX + port_name - status = self.db.get(self.db.APPL_DB, full_table_id, status_type) - if status is None: - return "N/A" + admin_state = self.db.get(self.db.APPL_DB, full_table_id, PORT_ADMIN_STATUS_FIELD) + oper_state = self.db.get(self.db.APPL_DB, full_table_id, PORT_OPER_STATUS_FIELD) + if admin_state is None or oper_state is None: + return STATUS_NA + elif admin_state.upper() == PORT_STATUS_VALUE_DOWN: + return PORT_STATE_DISABLED + elif admin_state.upper() == PORT_STATUS_VALUE_UP and oper_state.upper() == PORT_STATUS_VALUE_UP: + return PORT_STATE_UP + elif admin_state.upper() == PORT_STATUS_VALUE_UP and oper_state.upper() == PORT_STATUS_VALUE_DOWN: + return PORT_STATE_DOWN else: - return status + return STATUS_NA def table_as_json(self, table, print_all): """ @@ -107,50 +123,16 @@ class Portstat(object): """ output = {} + # Build a dictionary where the if_name is the key and the value is + # a dictionary that holds MTU, TX_DRP, etc if print_all: for line in table: if_name = line[0] - - # Build a dictionary where the if_name is the key and the value is - # a dictionary that holds MTU, TX_DRP, etc - output[if_name] = { - header_all[1] : line[1], - header_all[2] : line[2], - header_all[3] : line[3], - header_all[4] : line[4], - header_all[5] : line[5], - header_all[6] : line[6], - header_all[7] : line[7], - header_all[8] : line[8], - header_all[9] : line[9], - header_all[10] : line[10], - header_all[11] : line[11], - header_all[12] : line[12], - header_all[13] : line[13], - header_all[14] : line[14], - header_all[15] : line[15] - } + output[if_name] = {header_all[i]: line[i] for i in range(1, len(header_all))} else: for line in table: if_name = line[0] - - # Build a dictionary where the if_name is the key and the value is - # a dictionary that holds MTU, TX_DRP, etc - output[if_name] = { - header[1] : line[1], - header[2] : line[2], - header[3] : line[3], - header[4] : line[4], - header[5] : line[5], - header[6] : line[6], - header[7] : line[7], - header[8] : line[8], - header[9] : line[9], - header[10] : line[10], - header[11] : line[11], - header[12] : line[12], - header[13] : line[13] - } + output[if_name] = {header[i]: line[i] for i in range(1, len(header))} return json.dumps(output, indent=4, sort_keys=True) @@ -165,16 +147,16 @@ class Portstat(object): continue if print_all: - table.append((key, self.get_port_status(key, PORT_ADMIN_STATUS_FIELD), self.get_port_status(key, PORT_OPER_STATUS_FIELD), - data.rx_ok, "N/A", "N/A", "N/A", data.rx_err, + table.append((key, self.get_port_state(key), + data.rx_ok, STATUS_NA, STATUS_NA, STATUS_NA, data.rx_err, data.rx_drop, data.rx_ovr, - data.tx_ok, "N/A", "N/A", "N/A", data.tx_err, + data.tx_ok, STATUS_NA, STATUS_NA, STATUS_NA, data.tx_err, data.tx_drop, data.tx_ovr)) else: - table.append((key, self.get_port_status(key, PORT_ADMIN_STATUS_FIELD), self.get_port_status(key, PORT_OPER_STATUS_FIELD), - data.rx_ok, "N/A", "N/A", data.rx_err, + table.append((key, self.get_port_state(key), + data.rx_ok, STATUS_NA, STATUS_NA, data.rx_err, data.rx_drop, data.rx_ovr, - data.tx_ok, "N/A", "N/A", data.tx_err, + data.tx_ok, STATUS_NA, STATUS_NA, data.tx_err, data.tx_drop, data.tx_ovr)) @@ -195,8 +177,8 @@ class Portstat(object): """ Calculate the diff. """ - if newstr == "N/A" or oldstr == "N/A": - return "N/A" + if newstr == STATUS_NA or oldstr == STATUS_NA: + return STATUS_NA else: new, old = int(newstr), int(oldstr) return '{:,}'.format(new - old) @@ -205,8 +187,8 @@ class Portstat(object): """ Calculate the byte rate. """ - if newstr == "N/A" or oldstr == "N/A": - return "N/A" + if newstr == STATUS_NA or oldstr == STATUS_NA: + return STATUS_NA else: rate = int(ns_diff(newstr, oldstr).replace(',',''))/delta if rate > 1024*1024*10: @@ -221,8 +203,8 @@ class Portstat(object): """ Calculate the packet rate. """ - if newstr == "N/A" or oldstr == "N/A": - return "N/A" + if newstr == STATUS_NA or oldstr == STATUS_NA: + return STATUS_NA else: rate = int(ns_diff(newstr, oldstr).replace(',',''))/delta return "{:.2f}".format(rate)+'/s' @@ -231,8 +213,8 @@ class Portstat(object): """ Calculate the util. """ - if newstr == "N/A" or oldstr == "N/A": - return "N/A" + if newstr == STATUS_NA or oldstr == STATUS_NA: + return STATUS_NA else: rate = int(ns_diff(newstr, oldstr).replace(',',''))/delta util = rate/(PORT_RATE*1024*1024*1024/8.0)*100 @@ -251,7 +233,7 @@ class Portstat(object): if print_all: if old_cntr is not None: - table.append((key, self.get_port_status(key, PORT_ADMIN_STATUS_FIELD), self.get_port_status(key, PORT_OPER_STATUS_FIELD), + table.append((key, self.get_port_state(key), ns_diff(cntr.rx_ok, old_cntr.rx_ok), ns_brate(cntr.rx_byt, old_cntr.rx_byt, time_gap), ns_prate(cntr.rx_ok, old_cntr.rx_ok, time_gap), @@ -267,24 +249,24 @@ class Portstat(object): ns_diff(cntr.tx_drop, old_cntr.tx_drop), ns_diff(cntr.tx_ovr, old_cntr.tx_ovr))) else: - table.append((key, self.get_port_status(key, PORT_ADMIN_STATUS_FIELD), self.get_port_status(key, PORT_OPER_STATUS_FIELD), + table.append((key, self.get_port_state(key), cntr.rx_ok, - "N/A", - "N/A", - "N/A", + STATUS_NA, + STATUS_NA, + STATUS_NA, cntr.rx_err, cntr.rx_drop, cntr.rx_ovr, cntr.tx_ok, - "N/A", - "N/A", - "N/A", + STATUS_NA, + STATUS_NA, + STATUS_NA, cntr.tx_err, cntr.tx_drop, cntr.tx_err)) else: if old_cntr is not None: - table.append((key, self.get_port_status(key, PORT_ADMIN_STATUS_FIELD), self.get_port_status(key, PORT_OPER_STATUS_FIELD), + table.append((key, self.get_port_state(key), ns_diff(cntr.rx_ok, old_cntr.rx_ok), ns_brate(cntr.rx_byt, old_cntr.rx_byt, time_gap), ns_util(cntr.rx_byt, old_cntr.rx_byt, time_gap), @@ -298,16 +280,16 @@ class Portstat(object): ns_diff(cntr.tx_drop, old_cntr.tx_drop), ns_diff(cntr.tx_ovr, old_cntr.tx_ovr))) else: - table.append((key, self.get_port_status(key, PORT_ADMIN_STATUS_FIELD), self.get_port_status(key, PORT_OPER_STATUS_FIELD), + table.append((key, self.get_port_state(key), cntr.rx_ok, - "N/A", - "N/A", + STATUS_NA, + STATUS_NA, cntr.rx_err, cntr.rx_drop, cntr.rx_ovr, cntr.tx_ok, - "N/A", - "N/A", + STATUS_NA, + STATUS_NA, cntr.tx_err, cntr.tx_drop, cntr.tx_err)) @@ -322,10 +304,11 @@ class Portstat(object): def main(): - parser = argparse.ArgumentParser(description='Wrapper for netstat', + parser = argparse.ArgumentParser(description='Display the ports state and counters', version='1.0.0', formatter_class=argparse.RawTextHelpFormatter, epilog=""" +Port state: (U)-Up (D)-Down (X)-Disabled Examples: portstat -c -t test portstat -t test