diff --git a/scripts/portstat b/scripts/portstat index 7f31aa73d5..285676f3c3 100755 --- a/scripts/portstat +++ b/scripts/portstat @@ -22,7 +22,6 @@ from collections import namedtuple, OrderedDict from natsort import natsorted from tabulate import tabulate - PORT_RATE = 40 NStats = namedtuple("NStats", "rx_ok, rx_err, rx_drop, rx_ovr, tx_ok,\ @@ -33,6 +32,7 @@ header_all = ['IFACE', 'STATE', 'RX_OK', 'RX_BPS', 'RX_PPS', 'RX_UTIL', 'RX_ERR' 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'] +BUCKET_NUM = 10 counter_bucket_dict = { 'SAI_PORT_STAT_IF_IN_UCAST_PKTS': 0, 'SAI_PORT_STAT_IF_IN_NON_UCAST_PKTS': 0, @@ -58,6 +58,7 @@ PORT_OPER_STATUS_FIELD = "oper_status" PORT_ADMIN_STATUS_FIELD = "admin_status" PORT_STATUS_VALUE_UP = 'UP' PORT_STATUS_VALUE_DOWN = 'DOWN' +PORT_SPEED_FIELD = "speed" PORT_STATE_UP = 'U' PORT_STATE_DOWN = 'D' @@ -69,6 +70,10 @@ class Portstat(object): self.db.connect(self.db.COUNTERS_DB) self.db.connect(self.db.APPL_DB) + def get_uptime(self): + with open('/proc/uptime') as fp: + return float(fp.read().split(' ')[0]) + def get_cnstat(self): """ Get the counters info from database. @@ -99,6 +104,19 @@ class Portstat(object): cnstat_dict[port] = get_counters(counter_port_name_map[port]) return cnstat_dict + def get_port_speed(self, port_name): + """ + Get the port speed + """ + # Get speed from APPL_DB + full_table_id = PORT_STATUS_TABLE_PREFIX + port_name + speed = self.db.get(self.db.APPL_DB, full_table_id, PORT_SPEED_FIELD) + if speed is None: + speed = PORT_RATE + else: + speed = int(speed)/1000 + return speed + def get_port_state(self, port_name): """ Get the port state @@ -136,40 +154,7 @@ class Portstat(object): return json.dumps(output, indent=4, sort_keys=True) - def cnstat_print(self, cnstat_dict, use_json, print_all): - """ - Print the cnstat. - """ - table = [] - - for key, data in cnstat_dict.iteritems(): - if key == 'time': - continue - - if print_all: - 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, STATUS_NA, STATUS_NA, STATUS_NA, data.tx_err, - data.tx_drop, data.tx_ovr)) - else: - 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, STATUS_NA, STATUS_NA, data.tx_err, - data.tx_drop, data.tx_ovr)) - - - if use_json: - print self.table_as_json(table, print_all) - - else: - if print_all: - print tabulate(table, header_all, tablefmt='simple', stralign='right') - else: - print tabulate(table, header, tablefmt='simple', stralign='right') - - def cnstat_diff_print(self, cnstat_new_dict, cnstat_old_dict, use_json, print_all): + def cnstat_diff_print(self, cnstat_new_dict, cnstat_old_dict, use_json=False, print_all=False): """ Print the difference between two cnstat results. """ @@ -209,7 +194,7 @@ class Portstat(object): rate = int(ns_diff(newstr, oldstr).replace(',',''))/delta return "{:.2f}".format(rate)+'/s' - def ns_util(newstr, oldstr, delta): + def ns_util(newstr, oldstr, delta, port_rate=PORT_RATE): """ Calculate the util. """ @@ -217,82 +202,54 @@ class Portstat(object): return STATUS_NA else: rate = int(ns_diff(newstr, oldstr).replace(',',''))/delta - util = rate/(PORT_RATE*1024*1024*1024/8.0)*100 + util = rate/(port_rate*1024*1024*1024/8.0)*100 return "{:.2f}%".format(util) table = [] for key, cntr in cnstat_new_dict.iteritems(): if key == 'time': - time_gap = cnstat_new_dict.get('time') - cnstat_old_dict.get('time') - time_gap = time_gap.total_seconds() + if 'time' in cnstat_old_dict: + time_gap = cnstat_new_dict.get('time') - cnstat_old_dict.get('time') + time_gap = time_gap.total_seconds() + else: + time_gap = self.get_uptime() continue - old_cntr = None if key in cnstat_old_dict: old_cntr = cnstat_old_dict.get(key) - + else: + old_cntr = NStats._make([0] * BUCKET_NUM) + port_speed = self.get_port_speed(key) if print_all: - if old_cntr is not None: - 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), - ns_util(cntr.rx_byt, old_cntr.rx_byt, time_gap), - ns_diff(cntr.rx_err, old_cntr.rx_err), - ns_diff(cntr.rx_drop, old_cntr.rx_drop), - ns_diff(cntr.rx_ovr, old_cntr.rx_ovr), - ns_diff(cntr.tx_ok, old_cntr.tx_ok), - ns_brate(cntr.tx_byt, old_cntr.tx_byt, time_gap), - ns_prate(cntr.tx_ok, old_cntr.tx_ok, time_gap), - ns_util(cntr.tx_byt, old_cntr.tx_byt, time_gap), - ns_diff(cntr.tx_err, old_cntr.tx_err), - 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_state(key), - cntr.rx_ok, - STATUS_NA, - STATUS_NA, - STATUS_NA, - cntr.rx_err, - cntr.rx_drop, - cntr.rx_ovr, - cntr.tx_ok, - STATUS_NA, - STATUS_NA, - STATUS_NA, - cntr.tx_err, - cntr.tx_drop, - cntr.tx_err)) + 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), + ns_util(cntr.rx_byt, old_cntr.rx_byt, time_gap, port_speed), + ns_diff(cntr.rx_err, old_cntr.rx_err), + ns_diff(cntr.rx_drop, old_cntr.rx_drop), + ns_diff(cntr.rx_ovr, old_cntr.rx_ovr), + ns_diff(cntr.tx_ok, old_cntr.tx_ok), + ns_brate(cntr.tx_byt, old_cntr.tx_byt, time_gap), + ns_prate(cntr.tx_ok, old_cntr.tx_ok, time_gap), + ns_util(cntr.tx_byt, old_cntr.tx_byt, time_gap, port_speed), + ns_diff(cntr.tx_err, old_cntr.tx_err), + ns_diff(cntr.tx_drop, old_cntr.tx_drop), + ns_diff(cntr.tx_ovr, old_cntr.tx_ovr))) else: - if old_cntr is not None: - 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), - ns_diff(cntr.rx_err, old_cntr.rx_err), - ns_diff(cntr.rx_drop, old_cntr.rx_drop), - ns_diff(cntr.rx_ovr, old_cntr.rx_ovr), - ns_diff(cntr.tx_ok, old_cntr.tx_ok), - ns_brate(cntr.tx_byt, old_cntr.tx_byt, time_gap), - ns_util(cntr.tx_byt, old_cntr.tx_byt, time_gap), - ns_diff(cntr.tx_err, old_cntr.tx_err), - 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_state(key), - cntr.rx_ok, - STATUS_NA, - STATUS_NA, - cntr.rx_err, - cntr.rx_drop, - cntr.rx_ovr, - cntr.tx_ok, - STATUS_NA, - STATUS_NA, - cntr.tx_err, - cntr.tx_drop, - cntr.tx_err)) + 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, port_speed), + ns_diff(cntr.rx_err, old_cntr.rx_err), + ns_diff(cntr.rx_drop, old_cntr.rx_drop), + ns_diff(cntr.rx_ovr, old_cntr.rx_ovr), + ns_diff(cntr.tx_ok, old_cntr.tx_ok), + ns_brate(cntr.tx_byt, old_cntr.tx_byt, time_gap), + ns_util(cntr.tx_byt, old_cntr.tx_byt, time_gap, port_speed), + ns_diff(cntr.tx_err, old_cntr.tx_err), + ns_diff(cntr.tx_drop, old_cntr.tx_drop), + ns_diff(cntr.tx_ovr, old_cntr.tx_ovr))) if use_json: print self.table_as_json(table, print_all) @@ -410,7 +367,7 @@ Examples: print "\nFile '%s' does not exist" % cnstat_fqn_file print "Did you run 'portstat -c -t %s' to record the counters via tag %s?\n" % (tag_name, tag_name) else: - portstat.cnstat_print(cnstat_dict, use_json, print_all) + portstat.cnstat_diff_print(cnstat_dict, {}, use_json, print_all) else: #wait for the specified time and then gather the new stats and output the difference. time.sleep(wait_time_in_seconds)