def print_table_by_keys(self, data, keys_to_headers, title = None, empty_msg = 'empty'): def _iter_dict(d, keys, max_lens): row_data = [] for j, key in enumerate(keys): val = str(conv_to_str(d.get(key), key)) row_data.append(val) max_lens[j] = max(max_lens[j], len(val)) return row_data if len(data) == 0: text_tables.print_colored_line(empty_msg, 'yellow', buffer = sys.stdout) return table = text_tables.TRexTextTable(title) headers = [e.get('header') for e in keys_to_headers] keys = [e.get('key') for e in keys_to_headers] max_lens = [len(h) for h in headers] table.header(headers) if type(data) is list: for one_record in data: row_data = _iter_dict(one_record, keys, max_lens) table.add_row(row_data) elif type(data) is dict: row_data = _iter_dict(data, keys, max_lens) table.add_row(row_data) # fix table look table.set_cols_align(["c"] * len(headers)) table.set_cols_width(max_lens) table.set_cols_dtype(['a'] * len(headers)) text_tables.print_table_with_header(table, table.title, buffer = sys.stdout)
def to_table(self, with_zeroes=False): data = self._get_stats_values() sec_count = len(self.sections) # init table stats_table = text_tables.TRexTextTable('Traffic stats') stats_table.set_cols_align(["r"] * (1 + sec_count) + ["l"]) stats_table.set_cols_width([self._max_desc_name_len] + [17] * sec_count + [self._max_desc_name_len]) stats_table.set_cols_dtype(['t'] * (2 + sec_count)) header = [''] + self.sections + [''] stats_table.header(header) for desc in self._desc: if desc['real']: vals = [data[section][desc['id']] for section in self.sections] if not (with_zeroes or desc['zero'] or any(vals)): continue if desc['info'] == 'error': vals = [red(v) if v else green(v) for v in vals] if desc['units']: vals = [format_num(v, suffix=desc['units']) for v in vals] stats_table.add_row([desc['name']] + vals + [desc['help']]) else: stats_table.add_row([desc['name']] + [''] * (1 + sec_count)) return stats_table
def counters_to_table(self): data = self.get_stats() ports = sorted(data.keys())[:5] port_count = len(ports) stat_rows = {} for col, port_id in enumerate(ports): for k, v in data[port_id]['stats'].items(): if k not in stat_rows: stat_rows[k] = [''] * port_count stat_rows[k][col] = v hist_rows = {} for col, port_id in enumerate(ports): for k, v in data[port_id]['hist'].items(): if type(v) in (dict, list): continue if k not in hist_rows: hist_rows[k] = [''] * port_count hist_rows[k][col] = v rows = [] for key in sorted(stat_rows.keys()): val = stat_rows[key] if any(val): rows.append([key] + val) rows.append(['--'] + [''] * port_count) for key in sorted(hist_rows.keys()): val = hist_rows[key] if any(val): rows.append([key] + val) for row in rows: self.longest_key = max(self.longest_key, len(row[0])) # init table stats_table = text_tables.TRexTextTable('Latency Counters') stats_table.set_cols_align(['l'] + ['r'] * port_count) stats_table.set_cols_width([self.longest_key] + [15] * port_count) stats_table.set_cols_dtype(['t'] * (1 + port_count)) header = ['Port ID:'] + ports stats_table.header(header) self._fit_to_panel(rows) if self.max_panel_size: lack_for_full = self.max_panel_size - len(rows) if lack_for_full > 0: for _ in range(lack_for_full): stats_table.add_row([''] * (port_count + 1)) for row in rows: stats_table.add_row(row) return stats_table
def to_table(self, with_zeroes=False, tgid=0, pid_input=DEFAULT_PROFILE_ID, is_sum=False): self._get_tg_names(pid_input) num_of_tgids = len(self.tg_names_dict[pid_input]['tg_names']) title = "" data = {} if tgid == 0: data = self._get_stats_values(pid_input=pid_input, is_sum=is_sum) if is_sum: title = 'Traffic stats summary.' else: title = 'Traffic stats of Profile ID : ' + pid_input + '. Number of template groups = ' + str( num_of_tgids) else: if not 1 <= tgid <= num_of_tgids: raise ASTFErrorBadTG('Invalid tgid in to_table') else: name = self.tg_names_dict[pid_input]['tg_names'][tgid - 1] title = 'Profile ID : ' + pid_input + '. Template Group Name: ' + name + '. Number of template groups = ' + str( num_of_tgids) data = self.get_traffic_tg_stats(tg_names=name, for_table=True, pid_input=pid_input) sec_count = len(self.sections) # init table stats_table = text_tables.TRexTextTable(title) stats_table.set_cols_align(["r"] * (1 + sec_count) + ["l"]) stats_table.set_cols_width([self._max_desc_name_len] + [17] * sec_count + [self._max_desc_name_len]) stats_table.set_cols_dtype(['t'] * (2 + sec_count)) header = [''] + self.sections + [''] stats_table.header(header) for desc in self._desc: if desc['real']: vals = [data[section][desc['id']] for section in self.sections] if not (with_zeroes or desc['zero'] or any(vals)): continue if desc['info'] == 'error': vals = [red(v) if v else green(v) for v in vals] if desc['units']: vals = [format_num(v, suffix=desc['units']) for v in vals] stats_table.add_row([desc['name']] + vals + [desc['help']]) else: stats_table.add_row([desc['name']] + [''] * (1 + sec_count)) return stats_table
def dump_stats(self): stats_table = text_tables.TRexTextTable('ns stats') stats_table.set_cols_align(["l", "c", 'l']) stats_table.set_cols_width( [self._max_desc_name_len, 17, self._max_desc_name_len]) stats_table.set_cols_dtype(['t', 't', 't']) stats_table.header(['name', 'value', 'help']) for key in self.values: help = self.items[key]['help'].replace('"', "") name = self.items[key]['name'].replace('"', "") val = self.values[key] stats_table.add_row([name, val, help]) text_tables.print_table_with_header(stats_table, untouched_header=stats_table.title, buffer=sys.stdout)
def histogram_to_table(self): data = self.get_stats() ports = sorted(data.keys())[:5] port_count = len(ports) rows = {} for col, port_id in enumerate(ports): below_10 = data[port_id]['hist']['cnt'] - data[port_id]['hist'][ 'high_cnt'] if below_10: if 0 not in rows: rows[0] = [''] * port_count rows[0][col] = below_10 for elem in data[port_id]['hist']['histogram']: if elem['key'] not in rows: rows[elem['key']] = [''] * port_count rows[elem['key']][col] = elem['val'] for key in rows.keys(): self.longest_key = max(self.longest_key, len('%s' % key)) # init table stats_table = text_tables.TRexTextTable('Latency Histogram') stats_table.set_cols_align(['l'] + ['r'] * port_count) stats_table.set_cols_width([self.longest_key] + [15] * port_count) stats_table.set_cols_dtype(['t'] * (1 + port_count)) header = ['Port ID:'] + ports stats_table.header(header) keys = list(reversed(sorted(rows.keys()))) self._fit_to_panel(keys) if self.max_panel_size: lack_for_full = self.max_panel_size - len(rows) if lack_for_full > 0: for _ in range(lack_for_full): stats_table.add_row([''] * (port_count + 1)) for k in keys: if k < 10: stats_table.add_row(['<10'] + rows[k]) else: stats_table.add_row([k] + rows[k]) return stats_table
def to_table(self): stats = OrderedDict([ ("TX pkts", self.get("opackets", True)), ("RX pkts", self.get("ipackets", True)), ("---", ""), ("TX bytes", self.get("obytes", True)), ("RX bytes", self.get("ibytes", True)), ("----", ""), ("TX errors", self.get("oerrors")), ("RX errors", self.get("ierrors")), ]) total_cols = 1 stats_table = text_tables.TRexTextTable("Port statistics") stats_table.set_cols_align(["l"] + ["r"] * total_cols) stats_table.set_cols_width([10] + [17] * total_cols) stats_table.set_cols_dtype(["t"] + ["t"] * total_cols) stats_table.add_rows([[k] + [v] for k, v in stats.items()], header=False) stats_table.header(["port", self.port_id]) return stats_table
def to_table(self): pg_ids = [ pg_id for pg_id in self.stats["latency"] if isinstance(pg_id, int) ] if not pg_ids: return text_tables.TRexTextTable("") stream_count = len(pg_ids) stats_table = text_tables.TRexTextTable("Latency statistics") stats_table.set_cols_align(["l"] + ["r"] * stream_count) stats_table.set_cols_width([13] + [14] * stream_count) stats_table.set_cols_dtype(["t"] + ["t"] * stream_count) header = ["PG ID"] + [key for key in pg_ids] stats_table.header(header) stats_data = OrderedDict([ ("TX pkts", []), ("RX pkts", []), ]) for pg_id in pg_ids: stats_data["TX pkts"].append( self.get(["flow_stats", pg_id, "tx_pkts", "total"], format=True)) stats_data["RX pkts"].append( self.get(["flow_stats", pg_id, "rx_pkts", "total"], format=True)) # Check if server is receiving latency packets. If so, then it has full # latency informations. Otherwise it knows only how many latency packets # were sent. # stats_data contains formatted text so data could be like "XXX K" so # we need to split value and suffix. if any( float(rx_pkts.split()[0]) > 0.0 for rx_pkts in stats_data["RX pkts"]): stats_data.update( OrderedDict([ ("---", [""] * stream_count), ("Jitter", []), ("Errors", []), ("----", [""] * stream_count), ("Max latency", []), ("Min latency", []), ("Avg latency", []), ])) for pg_id in pg_ids: stats_data["Avg latency"].append( self.get(["latency", pg_id, "latency", "average"], True, "us", False)) stats_data["Max latency"].append( self.get(["latency", pg_id, "latency", "total_max"], True, "us", False)) stats_data["Min latency"].append( self.get(["latency", pg_id, "latency", "total_min"], True, "us", False)) stats_data["Jitter"].append( self.get(["latency", pg_id, "latency", "jitter"], True)) errors = 0 seq_too_low = self.get( ["latency", pg_id, "err_cntrs", "seq_too_low"]) errors += seq_too_low seq_too_high = self.get( ["latency", pg_id, "err_cntrs", "seq_too_high"]) errors += seq_too_high stats_data["Errors"].append(errors) stats_table.add_rows([[k] + v for k, v in stats_data.items()], header=False) merged_histogram = {} for pg_id in pg_ids: merged_histogram.update( self.stats["latency"][pg_id]["latency"]["histogram"]) max_histogram_size = 17 histogram_size = min(max_histogram_size, len(merged_histogram)) stats_table.add_row(["-----"] + [" "] * stream_count) stats_table.add_row(["- Histogram -"] + [" "] * stream_count) stats_table.add_row([" [us] "] + [" "] * stream_count) for i in range(max_histogram_size - histogram_size): if i == 0 and not merged_histogram: stats_table.add_row([" No Data "] + [" "] * stream_count) else: stats_table.add_row([" "] * (stream_count + 1)) for key in list(reversed(sorted( merged_histogram.keys())))[:histogram_size]: hist_vals = [] for pg_id in pg_ids: hist_vals.append(self.stats["latency"][pg_id]["latency"] ["histogram"].get(key, " ")) stats_table.add_row([key] + hist_vals) stats_table.add_row(["- Counters -"] + [" "] * stream_count) err_cntrs_dict = OrderedDict() for pg_id in pg_ids: for err_cntr in sorted( self.stats["latency"][pg_id]["err_cntrs"].keys()): if err_cntr not in err_cntrs_dict: err_cntrs_dict[err_cntr] = [ self.stats["latency"][pg_id]["err_cntrs"][err_cntr] ] else: err_cntrs_dict[err_cntr].append( self.stats["latency"][pg_id]["err_cntrs"] [err_cntr]) for err_cntr, val_list in err_cntrs_dict.items(): stats_table.add_row([err_cntr] + val_list) else: stats_table.add_rows([[k] + v for k, v in stats_data.items()], header=False) return stats_table
def to_table_main(self): data = self.get_stats() ports = sorted(data.keys())[:5] port_count = len(ports) rows = [] def add_counter(name, *path): rows.append([name]) for port_id in ports: sub = data[port_id] for key in path: sub = sub[key] rows[-1].append(int(sub)) def add_section(name): rows.append([name] + [''] * port_count) add_counter('TX pkts', 'stats', 'm_tx_pkt_ok') add_counter('RX pkts', 'stats', 'm_pkt_ok') add_counter('Max latency', 'hist', 'max_usec') add_counter('Avg latency', 'hist', 's_avg') add_section('-- Window --') for index in range(self.latency_window_size): if index == 0: rows.append(['Last max']) else: rows.append(['Last-%d' % index]) if index < len(self.history_of_max): rows[-1] += [(val if val else '') for val in self.history_of_max[index][:5]] else: rows[-1] += [''] * port_count add_section('---') add_counter('Jitter', 'stats', 'm_jitter') add_section('----') error_counters = [ 'm_unsup_prot', 'm_no_magic', 'm_no_id', 'm_seq_error', 'm_length_error', 'm_no_ipv4_option', 'm_tx_pkt_err', 'm_l3_cs_err', 'm_l4_cs_err' ] rows.append(['Errors']) for port_id in ports: errors = 0 for error_counter in error_counters: errors += data[port_id]['stats'][error_counter] rows[-1].append(red(errors) if errors else green(errors)) for row in rows: self.longest_key = max(self.longest_key, len(row[0])) # init table stats_table = text_tables.TRexTextTable('Latency Statistics') stats_table.set_cols_align(['l'] + ['r'] * port_count) stats_table.set_cols_width([self.longest_key] + [15] * port_count) stats_table.set_cols_dtype(['t'] * (1 + port_count)) header = ['Port ID:'] + ports stats_table.header(header) self._fit_to_panel(rows) for row in rows: stats_table.add_row(row) return stats_table