Skip to content
Merged

Pfcstat #1097

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 80 additions & 24 deletions scripts/pfcstat
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

#####################################################################
#
# pfcstat is a tool for summarizing Priority-based Flow Control (PFC) statistics.
# pfcstat is a tool for summarizing Priority-based Flow Control (PFC) statistics.
#
#####################################################################

import swsssdk
import sys
import argparse
import cPickle as pickle
Expand All @@ -20,6 +19,24 @@ from collections import namedtuple, OrderedDict
from natsort import natsorted
from tabulate import tabulate

from sonic_py_common.multi_asic import get_external_ports
from utilities_common import multi_asic as multi_asic_util
from utilities_common import constants

# mock the redis for unit test purposes #
try:
if os.environ["UTILITIES_UNIT_TESTING"] == "2":
modules_path = os.path.join(os.path.dirname(__file__), "..")
tests_path = os.path.join(modules_path, "sonic-utilities-tests")
sys.path.insert(0, modules_path)
sys.path.insert(0, tests_path)
import mock_tables.dbconnector
if os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] == "multi_asic":
import mock_tables.mock_multi_asic
mock_tables.dbconnector.load_namespace_config()

except KeyError:
pass

PStats = namedtuple("PStats", "pfc0, pfc1, pfc2, pfc3, pfc4, pfc5, pfc6, pfc7")
header_Rx = ['Port Rx', 'PFC0', 'PFC1', 'PFC2', 'PFC3', 'PFC4', 'PFC5', 'PFC6', 'PFC7']
Expand Down Expand Up @@ -54,11 +71,14 @@ COUNTER_TABLE_PREFIX = "COUNTERS:"
COUNTERS_PORT_NAME_MAP = "COUNTERS_PORT_NAME_MAP"

class Pfcstat(object):
def __init__(self):
self.db = swsssdk.SonicV2Connector(host='127.0.0.1')
self.db.connect(self.db.COUNTERS_DB)

def get_cnstat(self, rx):
def __init__(self, namespace, display):
self.multi_asic = multi_asic_util.MultiAsic(display, namespace)
self.db = None
self.config_db = None
self.cnstat_dict = OrderedDict()

@multi_asic_util.run_on_multi_asic
def collect_cnstat(self, rx):
"""
Get the counters info from database.
"""
Expand All @@ -73,7 +93,9 @@ class Pfcstat(object):
bucket_dict = counter_bucket_tx_dict
for counter_name, pos in bucket_dict.iteritems():
full_table_id = COUNTER_TABLE_PREFIX + table_id
counter_data = self.db.get(self.db.COUNTERS_DB, full_table_id, counter_name)
counter_data = self.db.get(
self.db.COUNTERS_DB, full_table_id, counter_name
)
if counter_data is None:
fields[pos] = STATUS_NA
else:
Expand All @@ -82,15 +104,34 @@ class Pfcstat(object):
return cntr

# Get the info from database
counter_port_name_map = self.db.get_all(self.db.COUNTERS_DB, COUNTERS_PORT_NAME_MAP)
counter_port_name_map = self.db.get_all(
self.db.COUNTERS_DB, COUNTERS_PORT_NAME_MAP
)
if counter_port_name_map is None:
return
display_ports_set = set(counter_port_name_map.keys())
if self.multi_asic.display_option == constants.DISPLAY_EXTERNAL:
display_ports_set = get_external_ports(
display_ports_set, self.multi_asic.current_namespace
)
# Build a dictionary of the stats
cnstat_dict = OrderedDict()
cnstat_dict['time'] = datetime.datetime.now()
if counter_port_name_map is None:
return cnstat_dict
for port in natsorted(counter_port_name_map):
cnstat_dict[port] = get_counters(counter_port_name_map[port])
return cnstat_dict
if counter_port_name_map is not None:
for port in natsorted(counter_port_name_map):
if port in display_ports_set:
cnstat_dict[port] = get_counters(
counter_port_name_map[port]
)
self.cnstat_dict.update(cnstat_dict)

def get_cnstat(self, rx):
"""
Get the counters info from database.
"""
self.cnstat_dict.clear()
self.collect_cnstat(rx)
return self.cnstat_dict

def cnstat_print(self, cnstat_dict, rx):
"""
Expand Down Expand Up @@ -166,10 +207,22 @@ Examples:
pfcstat
pfcstat -c
pfcstat -d
pfcstat -n asic1
pfcstat -s all -n asic0
""")

parser.add_argument('-c', '--clear', action='store_true', help='Clear previous stats and save new ones')
parser.add_argument('-d', '--delete', action='store_true', help='Delete saved stats')
parser.add_argument( '-c', '--clear', action='store_true',
help='Clear previous stats and save new ones'
)
parser.add_argument(
'-d', '--delete', action='store_true', help='Delete saved stats'
)
parser.add_argument('-s', '--show', default=constants.DISPLAY_EXTERNAL,
help='Display all interfaces or only external interfaces'
)
parser.add_argument('-n', '--namespace', default=None,
help='Display interfaces for specific namespace'
)
args = parser.parse_args()

save_fresh_stats = args.clear
Expand All @@ -178,15 +231,20 @@ Examples:
uid = str(os.getuid())
cnstat_file = uid

cnstat_dir = "/tmp/pfcstat-" + uid
cnstat_fqn_file_rx = cnstat_dir + "/" + cnstat_file + "rx"
cnstat_fqn_file_tx = cnstat_dir + "/" + cnstat_file + "tx"
cnstat_dir = os.path.join(os.sep, "tmp", "pfcstat-{}".format(uid))
cnstat_fqn_file_rx = os.path.join(cnstat_dir, "{}rx".format(cnstat_file))
cnstat_fqn_file_tx = os.path.join(cnstat_dir, "{}tx".format(cnstat_file))

# if '-c' option is provided get stats from all (frontend and backend) ports
if save_fresh_stats:
args.namespace = None
args.show = constants.DISPLAY_ALL

pfcstat = Pfcstat()
pfcstat = Pfcstat(args.namespace, args.show)

if delete_all_stats:
for file in os.listdir(cnstat_dir):
os.remove(cnstat_dir + "/" + file)
os.remove(os.path.join(cnstat_dir, file))

try:
os.rmdir(cnstat_dir)
Expand Down Expand Up @@ -228,7 +286,6 @@ Examples:
"""
Print the counters of pfc rx counter
"""
cnstat_cached_dict = OrderedDict()
if os.path.isfile(cnstat_fqn_file_rx):
try:
cnstat_cached_dict = pickle.load(open(cnstat_fqn_file_rx, 'r'))
Expand All @@ -239,11 +296,10 @@ Examples:
else:
pfcstat.cnstat_print(cnstat_dict_rx, True)

print
print("")
"""
Print the counters of pfc tx counter
"""
cnstat_cached_dict = OrderedDict()
if os.path.isfile(cnstat_fqn_file_tx):
try:
cnstat_cached_dict = pickle.load(open(cnstat_fqn_file_tx, 'r'))
Expand Down
7 changes: 5 additions & 2 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -920,11 +920,14 @@ def pfc():

# 'counters' subcommand ("show interfaces pfccounters")
@pfc.command()
@multi_asic_util.multi_asic_click_options
@click.option('--verbose', is_flag=True, help="Enable verbose output")
def counters(verbose):
def counters(namespace, display, verbose):
"""Show pfc counters"""

cmd = "pfcstat"
cmd = "pfcstat -s {}".format(display)
if namespace is not None:
cmd += " -n {}".format(namespace)

run_command(cmd, display_cmd=verbose)

Expand Down
85 changes: 78 additions & 7 deletions sonic-utilities-tests/mock_tables/asic0/counters_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,27 +123,98 @@
"SAI_PORT_STAT_IF_IN_ERRORS": "10",
"SAI_PORT_STAT_IF_IN_DISCARDS": "100",
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "80",
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "20"
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "20",
"SAI_PORT_STAT_PFC_0_RX_PKTS": "20",
"SAI_PORT_STAT_PFC_1_RX_PKTS": "21",
"SAI_PORT_STAT_PFC_2_RX_PKTS": "22",
"SAI_PORT_STAT_PFC_3_RX_PKTS": "23",
"SAI_PORT_STAT_PFC_4_RX_PKTS": "24",
"SAI_PORT_STAT_PFC_5_RX_PKTS": "25",
"SAI_PORT_STAT_PFC_6_RX_PKTS": "26",
"SAI_PORT_STAT_PFC_7_RX_PKTS": "27",
"SAI_PORT_STAT_PFC_0_TX_PKTS": "400",
"SAI_PORT_STAT_PFC_1_TX_PKTS": "201",
"SAI_PORT_STAT_PFC_2_TX_PKTS": "202",
"SAI_PORT_STAT_PFC_3_TX_PKTS": "203",
"SAI_PORT_STAT_PFC_4_TX_PKTS": "204",
"SAI_PORT_STAT_PFC_5_TX_PKTS": "205",
"SAI_PORT_STAT_PFC_6_TX_PKTS": "206",
"SAI_PORT_STAT_PFC_7_TX_PKTS": "207"
},
"COUNTERS:oid:0x1000000000004": {
"SAI_PORT_STAT_IF_IN_ERRORS": "0",
"SAI_PORT_STAT_IF_IN_DISCARDS": "1000",
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "800",
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "100"
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "100",
"SAI_PORT_STAT_PFC_0_RX_PKTS": "40",
"SAI_PORT_STAT_PFC_1_RX_PKTS": "41",
"SAI_PORT_STAT_PFC_2_RX_PKTS": "42",
"SAI_PORT_STAT_PFC_3_RX_PKTS": "43",
"SAI_PORT_STAT_PFC_4_RX_PKTS": "44",
"SAI_PORT_STAT_PFC_5_RX_PKTS": "45",
"SAI_PORT_STAT_PFC_6_RX_PKTS": "46",
"SAI_PORT_STAT_PFC_7_RX_PKTS": "47",
"SAI_PORT_STAT_PFC_0_TX_PKTS": "400",
"SAI_PORT_STAT_PFC_1_TX_PKTS": "401",
"SAI_PORT_STAT_PFC_2_TX_PKTS": "402",
"SAI_PORT_STAT_PFC_3_TX_PKTS": "403",
"SAI_PORT_STAT_PFC_4_TX_PKTS": "404",
"SAI_PORT_STAT_PFC_5_TX_PKTS": "405",
"SAI_PORT_STAT_PFC_6_TX_PKTS": "406",
"SAI_PORT_STAT_PFC_7_TX_PKTS": "407"
},
"COUNTERS:oid:0x1000000000006": {
"SAI_PORT_STAT_IF_IN_ERRORS": "100",
"SAI_PORT_STAT_IF_IN_DISCARDS": "10",
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "10",
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "0"
"SAI_PORT_STAT_IF_IN_ERRORS": "0",
"SAI_PORT_STAT_IF_IN_DISCARDS": "1000",
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "800",
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "100",
"SAI_PORT_STAT_PFC_0_RX_PKTS": "60",
"SAI_PORT_STAT_PFC_1_RX_PKTS": "61",
"SAI_PORT_STAT_PFC_2_RX_PKTS": "62",
"SAI_PORT_STAT_PFC_3_RX_PKTS": "63",
"SAI_PORT_STAT_PFC_4_RX_PKTS": "64",
"SAI_PORT_STAT_PFC_5_RX_PKTS": "65",
"SAI_PORT_STAT_PFC_6_RX_PKTS": "66",
"SAI_PORT_STAT_PFC_7_RX_PKTS": "67",
"SAI_PORT_STAT_PFC_0_TX_PKTS": "600",
"SAI_PORT_STAT_PFC_1_TX_PKTS": "601",
"SAI_PORT_STAT_PFC_2_TX_PKTS": "602",
"SAI_PORT_STAT_PFC_3_TX_PKTS": "603",
"SAI_PORT_STAT_PFC_4_TX_PKTS": "604",
"SAI_PORT_STAT_PFC_5_TX_PKTS": "605",
"SAI_PORT_STAT_PFC_6_TX_PKTS": "606",
"SAI_PORT_STAT_PFC_7_TX_PKTS": "607"
},
"COUNTERS:oid:0x1000000000008": {
"SAI_PORT_STAT_IF_IN_ERRORS": "0",
"SAI_PORT_STAT_IF_IN_DISCARDS": "1000",
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "800",
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "100",
"SAI_PORT_STAT_PFC_0_RX_PKTS": "80",
"SAI_PORT_STAT_PFC_1_RX_PKTS": "81",
"SAI_PORT_STAT_PFC_2_RX_PKTS": "82",
"SAI_PORT_STAT_PFC_3_RX_PKTS": "83",
"SAI_PORT_STAT_PFC_4_RX_PKTS": "84",
"SAI_PORT_STAT_PFC_5_RX_PKTS": "85",
"SAI_PORT_STAT_PFC_6_RX_PKTS": "86",
"SAI_PORT_STAT_PFC_7_RX_PKTS": "87",
"SAI_PORT_STAT_PFC_0_TX_PKTS": "800",
"SAI_PORT_STAT_PFC_1_TX_PKTS": "801",
"SAI_PORT_STAT_PFC_2_TX_PKTS": "802",
"SAI_PORT_STAT_PFC_3_TX_PKTS": "803",
"SAI_PORT_STAT_PFC_4_TX_PKTS": "804",
"SAI_PORT_STAT_PFC_5_TX_PKTS": "805",
"SAI_PORT_STAT_PFC_6_TX_PKTS": "806",
"SAI_PORT_STAT_PFC_7_TX_PKTS": "807"
},
"COUNTERS:oid:0x21000000000000": {
"SAI_SWITCH_STAT_IN_DROP_REASON_RANGE_BASE": "1000"
},
"COUNTERS_PORT_NAME_MAP": {
"Ethernet0": "oid:0x1000000000002",
"Ethernet4": "oid:0x1000000000004",
"Ethernet8": "oid:0x1000000000006"
"Ethernet-BP0": "oid:0x1000000000006",
"Ethernet-BP4": "oid:0x1000000000008"
},
"COUNTERS_LAG_NAME_MAP": {
"PortChannel0001": "oid:0x60000000005a1",
Expand Down
54 changes: 51 additions & 3 deletions sonic-utilities-tests/mock_tables/counters_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,67 @@
"SAI_PORT_STAT_IF_IN_ERRORS": "10",
"SAI_PORT_STAT_IF_IN_DISCARDS": "100",
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "80",
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "20"
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "20",
"SAI_PORT_STAT_PFC_0_RX_PKTS": "0",
"SAI_PORT_STAT_PFC_1_RX_PKTS": "0",
"SAI_PORT_STAT_PFC_2_RX_PKTS": "0",
"SAI_PORT_STAT_PFC_3_RX_PKTS": "0",
"SAI_PORT_STAT_PFC_4_RX_PKTS": "0",
"SAI_PORT_STAT_PFC_5_RX_PKTS": "0",
"SAI_PORT_STAT_PFC_6_RX_PKTS": "0",
"SAI_PORT_STAT_PFC_7_RX_PKTS": "0",
"SAI_PORT_STAT_PFC_0_TX_PKTS": "0",
"SAI_PORT_STAT_PFC_1_TX_PKTS": "0",
"SAI_PORT_STAT_PFC_2_TX_PKTS": "0",
"SAI_PORT_STAT_PFC_3_TX_PKTS": "0",
"SAI_PORT_STAT_PFC_4_TX_PKTS": "0",
"SAI_PORT_STAT_PFC_5_TX_PKTS": "0",
"SAI_PORT_STAT_PFC_6_TX_PKTS": "0",
"SAI_PORT_STAT_PFC_7_TX_PKTS": "0"
},
"COUNTERS:oid:0x1000000000004": {
"SAI_PORT_STAT_IF_IN_ERRORS": "0",
"SAI_PORT_STAT_IF_IN_DISCARDS": "1000",
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "800",
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "100"
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "100",
"SAI_PORT_STAT_PFC_0_RX_PKTS": "40",
"SAI_PORT_STAT_PFC_1_RX_PKTS": "41",
"SAI_PORT_STAT_PFC_2_RX_PKTS": "42",
"SAI_PORT_STAT_PFC_3_RX_PKTS": "43",
"SAI_PORT_STAT_PFC_4_RX_PKTS": "44",
"SAI_PORT_STAT_PFC_5_RX_PKTS": "45",
"SAI_PORT_STAT_PFC_6_RX_PKTS": "46",
"SAI_PORT_STAT_PFC_7_RX_PKTS": "47",
"SAI_PORT_STAT_PFC_0_TX_PKTS": "400",
"SAI_PORT_STAT_PFC_1_TX_PKTS": "401",
"SAI_PORT_STAT_PFC_2_TX_PKTS": "402",
"SAI_PORT_STAT_PFC_3_TX_PKTS": "403",
"SAI_PORT_STAT_PFC_4_TX_PKTS": "404",
"SAI_PORT_STAT_PFC_5_TX_PKTS": "405",
"SAI_PORT_STAT_PFC_6_TX_PKTS": "406",
"SAI_PORT_STAT_PFC_7_TX_PKTS": "407"
},
"COUNTERS:oid:0x1000000000006": {
"SAI_PORT_STAT_IF_IN_ERRORS": "100",
"SAI_PORT_STAT_IF_IN_DISCARDS": "10",
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "10",
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "0"
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "0",
"SAI_PORT_STAT_PFC_0_RX_PKTS": "80",
"SAI_PORT_STAT_PFC_1_RX_PKTS": "81",
"SAI_PORT_STAT_PFC_2_RX_PKTS": "82",
"SAI_PORT_STAT_PFC_3_RX_PKTS": "83",
"SAI_PORT_STAT_PFC_4_RX_PKTS": "84",
"SAI_PORT_STAT_PFC_5_RX_PKTS": "85",
"SAI_PORT_STAT_PFC_6_RX_PKTS": "86",
"SAI_PORT_STAT_PFC_7_RX_PKTS": "87",
"SAI_PORT_STAT_PFC_0_TX_PKTS": "800",
"SAI_PORT_STAT_PFC_1_TX_PKTS": "801",
"SAI_PORT_STAT_PFC_2_TX_PKTS": "802",
"SAI_PORT_STAT_PFC_3_TX_PKTS": "803",
"SAI_PORT_STAT_PFC_4_TX_PKTS": "804",
"SAI_PORT_STAT_PFC_5_TX_PKTS": "805",
"SAI_PORT_STAT_PFC_6_TX_PKTS": "806",
"SAI_PORT_STAT_PFC_7_TX_PKTS": "807"
},
"COUNTERS:oid:0x21000000000000": {
"SAI_SWITCH_STAT_IN_DROP_REASON_RANGE_BASE": "1000"
Expand Down
Loading