From a531039592474412487199f1842142f5514531f8 Mon Sep 17 00:00:00 2001 From: Neetha John Date: Fri, 3 Apr 2020 03:58:47 -0700 Subject: [PATCH] [watermarkstat] Fix issue of fields overwritten before display (#862) Fix the bug where the unicast/multicast queue watermark display was incorrect - How I did it Calculate the header list dynamically for PG and queue display Display the correct queue numbers in the output instead of always starting the index from 0 Calculate the display position relative to the starting index Signed-off-by: Neetha John --- scripts/watermarkstat | 48 ++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/scripts/watermarkstat b/scripts/watermarkstat index b2a6c5f0ad..9b446248da 100644 --- a/scripts/watermarkstat +++ b/scripts/watermarkstat @@ -15,9 +15,6 @@ from natsort import natsorted from tabulate import tabulate -headerPg = ['Port', 'PG0', 'PG1', 'PG2', 'PG3', 'PG4', 'PG5', 'PG6', 'PG7'] -headerUc = ['Port', 'UC0', 'UC1', 'UC2', 'UC3', 'UC4', 'UC5', 'UC6', 'UC7'] -headerMc = ['Port', 'MC8', 'MC9', 'MC10', 'MC11', 'MC12', 'MC13', 'MC14', 'MC15'] headerBufferPool = ['Pool', 'Bytes'] @@ -140,22 +137,22 @@ class Watermarkstat(object): "obj_map" : self.port_pg_map, "idx_func": self.get_pg_index, "wm_name" : "SAI_INGRESS_PRIORITY_GROUP_STAT_XOFF_ROOM_WATERMARK_BYTES", - "header" : headerPg}, + "header_prefix": "PG"}, "pg_shared" : {"message" : "Ingress shared pool occupancy per PG:", "obj_map" : self.port_pg_map, "idx_func": self.get_pg_index, "wm_name" : "SAI_INGRESS_PRIORITY_GROUP_STAT_SHARED_WATERMARK_BYTES", - "header" : headerPg}, + "header_prefix": "PG"}, "q_shared_uni" : {"message" : "Egress shared pool occupancy per unicast queue:", "obj_map" : self.port_uc_queues_map, "idx_func": self.get_queue_index, "wm_name" : "SAI_QUEUE_STAT_SHARED_WATERMARK_BYTES", - "header" : headerUc}, + "header_prefix": "UC"}, "q_shared_multi": {"message" : "Egress shared pool occupancy per multicast queue:", "obj_map" : self.port_mc_queues_map, "idx_func": self.get_queue_index, "wm_name" : "SAI_QUEUE_STAT_SHARED_WATERMARK_BYTES", - "header" : headerMc}, + "header_prefix": "MC"}, "buffer_pool" : {"message": "Shared pool maximum occupancy:", "wm_name": "SAI_BUFFER_POOL_STAT_WATERMARK_BYTES", "header" : headerBufferPool} @@ -177,28 +174,48 @@ class Watermarkstat(object): return pg_index + def build_header(self, wm_type): + if wm_type is None: + print >> sys.stderr, "Header info is not available!" + sys.exit(1) + + self.header_list = ['Port'] + header_map = wm_type["obj_map"] + single_key = header_map.keys()[0] + header_len = len(header_map[single_key]) + min_idx = float("inf") + + for name, counter_oid in header_map[single_key].items(): + curr_idx = int(wm_type["idx_func"](counter_oid)) + min_idx = min(min_idx, curr_idx) + + self.min_idx = int(min_idx) + self.header_list += ["{}{}".format(wm_type["header_prefix"], idx) for idx in range(self.min_idx, self.min_idx + header_len)] + def get_counters(self, table_prefix, port_obj, idx_func, watermark): """ Get the counters from specific table. """ - fields = ["0"] * 8 + # header list contains the port name followed by the queues/pgs. fields is used to populate the queue/pg values + fields = ["0"]* (len(self.header_list) - 1) for name, obj_id in port_obj.items(): full_table_id = table_prefix + obj_id - pos = int(idx_func(obj_id)) % len(fields) + idx = int(idx_func(obj_id)) + pos = idx - self.min_idx counter_data = self.counters_db.get(self.counters_db.COUNTERS_DB, full_table_id, watermark) if counter_data is None: fields[pos] = STATUS_NA elif fields[pos] != STATUS_NA: fields[pos] = str(int(counter_data)) - cntr = tuple(fields) - return cntr + return fields def print_all_stat(self, table_prefix, key): table = [] type = self.watermark_types[key] if key == 'buffer_pool': + self.header_list = type['header'] # Get stats for each buffer pool for buf_pool, bp_oid in natsorted(self.buffer_pool_name_to_oid_map.items()): key = table_prefix + bp_oid @@ -207,15 +224,18 @@ class Watermarkstat(object): data = STATUS_NA table.append((buf_pool, data)) else: + self.build_header(type) # Get stat for each port for port in natsorted(self.counter_port_name_map): + row_data = list() data = self.get_counters(table_prefix, type["obj_map"][port], type["idx_func"], type["wm_name"]) - table.append((port, data[0], data[1], data[2], data[3], - data[4], data[5], data[6], data[7])) + row_data.append(port) + row_data.extend(data) + table.append(tuple(row_data)) print(type["message"]) - print tabulate(table, type["header"], tablefmt='simple', stralign='right') + print tabulate(table, self.header_list, tablefmt='simple', stralign='right') def send_clear_notification(self, data): msg = json.dumps(data, separators=(',', ':'))