Skip to content

Commit 58be765

Browse files
committed
[CLI][PFC] Add multi ASIC options for pfcstat and 'show pfc counters'
1 parent 0ae650d commit 58be765

File tree

5 files changed

+237
-67
lines changed

5 files changed

+237
-67
lines changed

scripts/pfcstat

+80-22
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22

33
#####################################################################
44
#
5-
# pfcstat is a tool for summarizing Priority-based Flow Control (PFC) statistics.
5+
# pfcstat is a tool for summarizing Priority-based Flow Control (PFC) statistics.
66
#
77
#####################################################################
88

9-
import swsssdk
109
import sys
1110
import argparse
1211
import cPickle as pickle
@@ -20,6 +19,24 @@ from collections import namedtuple, OrderedDict
2019
from natsort import natsorted
2120
from tabulate import tabulate
2221

22+
from sonic_py_common.multi_asic import get_external_ports
23+
from utilities_common import multi_asic as multi_asic_util
24+
from utilities_common import constants
25+
26+
# mock the redis for unit test purposes #
27+
try:
28+
if os.environ["UTILITIES_UNIT_TESTING"] == "2":
29+
modules_path = os.path.join(os.path.dirname(__file__), "..")
30+
tests_path = os.path.join(modules_path, "sonic-utilities-tests")
31+
sys.path.insert(0, modules_path)
32+
sys.path.insert(0, tests_path)
33+
import mock_tables.dbconnector
34+
if os.environ["UTILITIES_UNIT_TESTING_TOPOLOGY"] == "multi_asic":
35+
import mock_tables.mock_multi_asic
36+
mock_tables.dbconnector.load_namespace_config()
37+
38+
except KeyError:
39+
pass
2340

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

5673
class Pfcstat(object):
57-
def __init__(self):
58-
self.db = swsssdk.SonicV2Connector(host='127.0.0.1')
59-
self.db.connect(self.db.COUNTERS_DB)
60-
61-
def get_cnstat(self, rx):
74+
def __init__(self, namespace, display):
75+
self.multi_asic = multi_asic_util.MultiAsic(display, namespace)
76+
self.db = None
77+
self.config_db = None
78+
self.cnstat_dict = OrderedDict()
79+
80+
@multi_asic_util.run_on_multi_asic
81+
def collect_cnstat(self, rx):
6282
"""
6383
Get the counters info from database.
6484
"""
@@ -73,7 +93,9 @@ class Pfcstat(object):
7393
bucket_dict = counter_bucket_tx_dict
7494
for counter_name, pos in bucket_dict.iteritems():
7595
full_table_id = COUNTER_TABLE_PREFIX + table_id
76-
counter_data = self.db.get(self.db.COUNTERS_DB, full_table_id, counter_name)
96+
counter_data = self.db.get(
97+
self.db.COUNTERS_DB, full_table_id, counter_name
98+
)
7799
if counter_data is None:
78100
fields[pos] = STATUS_NA
79101
else:
@@ -82,15 +104,34 @@ class Pfcstat(object):
82104
return cntr
83105

84106
# Get the info from database
85-
counter_port_name_map = self.db.get_all(self.db.COUNTERS_DB, COUNTERS_PORT_NAME_MAP)
107+
counter_port_name_map = self.db.get_all(
108+
self.db.COUNTERS_DB, COUNTERS_PORT_NAME_MAP
109+
)
110+
if counter_port_name_map is None:
111+
return
112+
display_ports_set = set(counter_port_name_map.keys())
113+
if self.multi_asic.display_option == constants.DISPLAY_EXTERNAL:
114+
display_ports_set = get_external_ports(
115+
display_ports_set, self.multi_asic.current_namespace
116+
)
86117
# Build a dictionary of the stats
87118
cnstat_dict = OrderedDict()
88119
cnstat_dict['time'] = datetime.datetime.now()
89-
if counter_port_name_map is None:
90-
return cnstat_dict
91-
for port in natsorted(counter_port_name_map):
92-
cnstat_dict[port] = get_counters(counter_port_name_map[port])
93-
return cnstat_dict
120+
if counter_port_name_map is not None:
121+
for port in natsorted(counter_port_name_map):
122+
if port in display_ports_set:
123+
cnstat_dict[port] = get_counters(
124+
counter_port_name_map[port]
125+
)
126+
self.cnstat_dict.update(cnstat_dict)
127+
128+
def get_cnstat(self, rx):
129+
"""
130+
Get the counters info from database.
131+
"""
132+
self.cnstat_dict.clear()
133+
self.collect_cnstat(rx)
134+
return self.cnstat_dict
94135

95136
def cnstat_print(self, cnstat_dict, rx):
96137
"""
@@ -166,10 +207,22 @@ Examples:
166207
pfcstat
167208
pfcstat -c
168209
pfcstat -d
210+
pfcstat -n asic1
211+
pfcstat -s all -n asic0
169212
""")
170213

171-
parser.add_argument('-c', '--clear', action='store_true', help='Clear previous stats and save new ones')
172-
parser.add_argument('-d', '--delete', action='store_true', help='Delete saved stats')
214+
parser.add_argument( '-c', '--clear', action='store_true',
215+
help='Clear previous stats and save new ones'
216+
)
217+
parser.add_argument(
218+
'-d', '--delete', action='store_true', help='Delete saved stats'
219+
)
220+
parser.add_argument('-s', '--show', default=constants.DISPLAY_EXTERNAL,
221+
help='Display all interfaces or only external interfaces'
222+
)
223+
parser.add_argument('-n', '--namespace', default=None,
224+
help='Display interfaces for specific namespace'
225+
)
173226
args = parser.parse_args()
174227

175228
save_fresh_stats = args.clear
@@ -178,15 +231,20 @@ Examples:
178231
uid = str(os.getuid())
179232
cnstat_file = uid
180233

181-
cnstat_dir = "/tmp/pfcstat-" + uid
182-
cnstat_fqn_file_rx = cnstat_dir + "/" + cnstat_file + "rx"
183-
cnstat_fqn_file_tx = cnstat_dir + "/" + cnstat_file + "tx"
234+
cnstat_dir = os.path.join(os.sep, "tmp", "pfcstat-{}".format(uid))
235+
cnstat_fqn_file_rx = os.path.join(cnstat_dir, "{}rx".format(cnstat_file))
236+
cnstat_fqn_file_tx = os.path.join(cnstat_dir, "{}tx".format(cnstat_file))
237+
238+
# if '-c' option is provided get stats from all (frontend and backend) ports
239+
if save_fresh_stats:
240+
args.namespace = None
241+
args.show = constants.DISPLAY_ALL
184242

185-
pfcstat = Pfcstat()
243+
pfcstat = Pfcstat(args.namespace, args.show)
186244

187245
if delete_all_stats:
188246
for file in os.listdir(cnstat_dir):
189-
os.remove(cnstat_dir + "/" + file)
247+
os.remove(os.path.join(cnstat_dir, file))
190248

191249
try:
192250
os.rmdir(cnstat_dir)
@@ -239,7 +297,7 @@ Examples:
239297
else:
240298
pfcstat.cnstat_print(cnstat_dict_rx, True)
241299

242-
print
300+
print("")
243301
"""
244302
Print the counters of pfc tx counter
245303
"""

show/main.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -920,11 +920,14 @@ def pfc():
920920

921921
# 'counters' subcommand ("show interfaces pfccounters")
922922
@pfc.command()
923+
@multi_asic_util.multi_asic_click_options
923924
@click.option('--verbose', is_flag=True, help="Enable verbose output")
924-
def counters(verbose):
925+
def counters(namespace, display, verbose):
925926
"""Show pfc counters"""
926927

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

929932
run_command(cmd, display_cmd=verbose)
930933

sonic-utilities-tests/mock_tables/asic0/counters_db.json

+78-7
Original file line numberDiff line numberDiff line change
@@ -123,27 +123,98 @@
123123
"SAI_PORT_STAT_IF_IN_ERRORS": "10",
124124
"SAI_PORT_STAT_IF_IN_DISCARDS": "100",
125125
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "80",
126-
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "20"
126+
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "20",
127+
"SAI_PORT_STAT_PFC_0_RX_PKTS": "20",
128+
"SAI_PORT_STAT_PFC_1_RX_PKTS": "21",
129+
"SAI_PORT_STAT_PFC_2_RX_PKTS": "22",
130+
"SAI_PORT_STAT_PFC_3_RX_PKTS": "23",
131+
"SAI_PORT_STAT_PFC_4_RX_PKTS": "24",
132+
"SAI_PORT_STAT_PFC_5_RX_PKTS": "25",
133+
"SAI_PORT_STAT_PFC_6_RX_PKTS": "26",
134+
"SAI_PORT_STAT_PFC_7_RX_PKTS": "27",
135+
"SAI_PORT_STAT_PFC_0_TX_PKTS": "400",
136+
"SAI_PORT_STAT_PFC_1_TX_PKTS": "201",
137+
"SAI_PORT_STAT_PFC_2_TX_PKTS": "202",
138+
"SAI_PORT_STAT_PFC_3_TX_PKTS": "203",
139+
"SAI_PORT_STAT_PFC_4_TX_PKTS": "204",
140+
"SAI_PORT_STAT_PFC_5_TX_PKTS": "205",
141+
"SAI_PORT_STAT_PFC_6_TX_PKTS": "206",
142+
"SAI_PORT_STAT_PFC_7_TX_PKTS": "207"
127143
},
128144
"COUNTERS:oid:0x1000000000004": {
129145
"SAI_PORT_STAT_IF_IN_ERRORS": "0",
130146
"SAI_PORT_STAT_IF_IN_DISCARDS": "1000",
131147
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "800",
132-
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "100"
148+
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "100",
149+
"SAI_PORT_STAT_PFC_0_RX_PKTS": "40",
150+
"SAI_PORT_STAT_PFC_1_RX_PKTS": "41",
151+
"SAI_PORT_STAT_PFC_2_RX_PKTS": "42",
152+
"SAI_PORT_STAT_PFC_3_RX_PKTS": "43",
153+
"SAI_PORT_STAT_PFC_4_RX_PKTS": "44",
154+
"SAI_PORT_STAT_PFC_5_RX_PKTS": "45",
155+
"SAI_PORT_STAT_PFC_6_RX_PKTS": "46",
156+
"SAI_PORT_STAT_PFC_7_RX_PKTS": "47",
157+
"SAI_PORT_STAT_PFC_0_TX_PKTS": "400",
158+
"SAI_PORT_STAT_PFC_1_TX_PKTS": "401",
159+
"SAI_PORT_STAT_PFC_2_TX_PKTS": "402",
160+
"SAI_PORT_STAT_PFC_3_TX_PKTS": "403",
161+
"SAI_PORT_STAT_PFC_4_TX_PKTS": "404",
162+
"SAI_PORT_STAT_PFC_5_TX_PKTS": "405",
163+
"SAI_PORT_STAT_PFC_6_TX_PKTS": "406",
164+
"SAI_PORT_STAT_PFC_7_TX_PKTS": "407"
133165
},
134166
"COUNTERS:oid:0x1000000000006": {
135-
"SAI_PORT_STAT_IF_IN_ERRORS": "100",
136-
"SAI_PORT_STAT_IF_IN_DISCARDS": "10",
137-
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "10",
138-
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "0"
167+
"SAI_PORT_STAT_IF_IN_ERRORS": "0",
168+
"SAI_PORT_STAT_IF_IN_DISCARDS": "1000",
169+
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "800",
170+
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "100",
171+
"SAI_PORT_STAT_PFC_0_RX_PKTS": "60",
172+
"SAI_PORT_STAT_PFC_1_RX_PKTS": "61",
173+
"SAI_PORT_STAT_PFC_2_RX_PKTS": "62",
174+
"SAI_PORT_STAT_PFC_3_RX_PKTS": "63",
175+
"SAI_PORT_STAT_PFC_4_RX_PKTS": "64",
176+
"SAI_PORT_STAT_PFC_5_RX_PKTS": "65",
177+
"SAI_PORT_STAT_PFC_6_RX_PKTS": "66",
178+
"SAI_PORT_STAT_PFC_7_RX_PKTS": "67",
179+
"SAI_PORT_STAT_PFC_0_TX_PKTS": "600",
180+
"SAI_PORT_STAT_PFC_1_TX_PKTS": "601",
181+
"SAI_PORT_STAT_PFC_2_TX_PKTS": "602",
182+
"SAI_PORT_STAT_PFC_3_TX_PKTS": "603",
183+
"SAI_PORT_STAT_PFC_4_TX_PKTS": "604",
184+
"SAI_PORT_STAT_PFC_5_TX_PKTS": "605",
185+
"SAI_PORT_STAT_PFC_6_TX_PKTS": "606",
186+
"SAI_PORT_STAT_PFC_7_TX_PKTS": "607"
187+
},
188+
"COUNTERS:oid:0x1000000000008": {
189+
"SAI_PORT_STAT_IF_IN_ERRORS": "0",
190+
"SAI_PORT_STAT_IF_IN_DISCARDS": "1000",
191+
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "800",
192+
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "100",
193+
"SAI_PORT_STAT_PFC_0_RX_PKTS": "80",
194+
"SAI_PORT_STAT_PFC_1_RX_PKTS": "81",
195+
"SAI_PORT_STAT_PFC_2_RX_PKTS": "82",
196+
"SAI_PORT_STAT_PFC_3_RX_PKTS": "83",
197+
"SAI_PORT_STAT_PFC_4_RX_PKTS": "84",
198+
"SAI_PORT_STAT_PFC_5_RX_PKTS": "85",
199+
"SAI_PORT_STAT_PFC_6_RX_PKTS": "86",
200+
"SAI_PORT_STAT_PFC_7_RX_PKTS": "87",
201+
"SAI_PORT_STAT_PFC_0_TX_PKTS": "800",
202+
"SAI_PORT_STAT_PFC_1_TX_PKTS": "801",
203+
"SAI_PORT_STAT_PFC_2_TX_PKTS": "802",
204+
"SAI_PORT_STAT_PFC_3_TX_PKTS": "803",
205+
"SAI_PORT_STAT_PFC_4_TX_PKTS": "804",
206+
"SAI_PORT_STAT_PFC_5_TX_PKTS": "805",
207+
"SAI_PORT_STAT_PFC_6_TX_PKTS": "806",
208+
"SAI_PORT_STAT_PFC_7_TX_PKTS": "807"
139209
},
140210
"COUNTERS:oid:0x21000000000000": {
141211
"SAI_SWITCH_STAT_IN_DROP_REASON_RANGE_BASE": "1000"
142212
},
143213
"COUNTERS_PORT_NAME_MAP": {
144214
"Ethernet0": "oid:0x1000000000002",
145215
"Ethernet4": "oid:0x1000000000004",
146-
"Ethernet8": "oid:0x1000000000006"
216+
"Ethernet-BP0": "oid:0x1000000000006",
217+
"Ethernet-BP4": "oid:0x1000000000008"
147218
},
148219
"COUNTERS_LAG_NAME_MAP": {
149220
"PortChannel0001": "oid:0x60000000005a1",

sonic-utilities-tests/mock_tables/counters_db.json

+51-3
Original file line numberDiff line numberDiff line change
@@ -119,19 +119,67 @@
119119
"SAI_PORT_STAT_IF_IN_ERRORS": "10",
120120
"SAI_PORT_STAT_IF_IN_DISCARDS": "100",
121121
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "80",
122-
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "20"
122+
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "20",
123+
"SAI_PORT_STAT_PFC_0_RX_PKTS": "0",
124+
"SAI_PORT_STAT_PFC_1_RX_PKTS": "0",
125+
"SAI_PORT_STAT_PFC_2_RX_PKTS": "0",
126+
"SAI_PORT_STAT_PFC_3_RX_PKTS": "0",
127+
"SAI_PORT_STAT_PFC_4_RX_PKTS": "0",
128+
"SAI_PORT_STAT_PFC_5_RX_PKTS": "0",
129+
"SAI_PORT_STAT_PFC_6_RX_PKTS": "0",
130+
"SAI_PORT_STAT_PFC_7_RX_PKTS": "0",
131+
"SAI_PORT_STAT_PFC_0_TX_PKTS": "0",
132+
"SAI_PORT_STAT_PFC_1_TX_PKTS": "0",
133+
"SAI_PORT_STAT_PFC_2_TX_PKTS": "0",
134+
"SAI_PORT_STAT_PFC_3_TX_PKTS": "0",
135+
"SAI_PORT_STAT_PFC_4_TX_PKTS": "0",
136+
"SAI_PORT_STAT_PFC_5_TX_PKTS": "0",
137+
"SAI_PORT_STAT_PFC_6_TX_PKTS": "0",
138+
"SAI_PORT_STAT_PFC_7_TX_PKTS": "0"
123139
},
124140
"COUNTERS:oid:0x1000000000004": {
125141
"SAI_PORT_STAT_IF_IN_ERRORS": "0",
126142
"SAI_PORT_STAT_IF_IN_DISCARDS": "1000",
127143
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "800",
128-
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "100"
144+
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "100",
145+
"SAI_PORT_STAT_PFC_0_RX_PKTS": "40",
146+
"SAI_PORT_STAT_PFC_1_RX_PKTS": "41",
147+
"SAI_PORT_STAT_PFC_2_RX_PKTS": "42",
148+
"SAI_PORT_STAT_PFC_3_RX_PKTS": "43",
149+
"SAI_PORT_STAT_PFC_4_RX_PKTS": "44",
150+
"SAI_PORT_STAT_PFC_5_RX_PKTS": "45",
151+
"SAI_PORT_STAT_PFC_6_RX_PKTS": "46",
152+
"SAI_PORT_STAT_PFC_7_RX_PKTS": "47",
153+
"SAI_PORT_STAT_PFC_0_TX_PKTS": "400",
154+
"SAI_PORT_STAT_PFC_1_TX_PKTS": "401",
155+
"SAI_PORT_STAT_PFC_2_TX_PKTS": "402",
156+
"SAI_PORT_STAT_PFC_3_TX_PKTS": "403",
157+
"SAI_PORT_STAT_PFC_4_TX_PKTS": "404",
158+
"SAI_PORT_STAT_PFC_5_TX_PKTS": "405",
159+
"SAI_PORT_STAT_PFC_6_TX_PKTS": "406",
160+
"SAI_PORT_STAT_PFC_7_TX_PKTS": "407"
129161
},
130162
"COUNTERS:oid:0x1000000000006": {
131163
"SAI_PORT_STAT_IF_IN_ERRORS": "100",
132164
"SAI_PORT_STAT_IF_IN_DISCARDS": "10",
133165
"SAI_PORT_STAT_IN_DROP_REASON_RANGE_BASE": "10",
134-
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "0"
166+
"SAI_PORT_STAT_OUT_CONFIGURED_DROP_REASONS_1_DROPPED_PKTS": "0",
167+
"SAI_PORT_STAT_PFC_0_RX_PKTS": "80",
168+
"SAI_PORT_STAT_PFC_1_RX_PKTS": "81",
169+
"SAI_PORT_STAT_PFC_2_RX_PKTS": "82",
170+
"SAI_PORT_STAT_PFC_3_RX_PKTS": "83",
171+
"SAI_PORT_STAT_PFC_4_RX_PKTS": "84",
172+
"SAI_PORT_STAT_PFC_5_RX_PKTS": "85",
173+
"SAI_PORT_STAT_PFC_6_RX_PKTS": "86",
174+
"SAI_PORT_STAT_PFC_7_RX_PKTS": "87",
175+
"SAI_PORT_STAT_PFC_0_TX_PKTS": "800",
176+
"SAI_PORT_STAT_PFC_1_TX_PKTS": "801",
177+
"SAI_PORT_STAT_PFC_2_TX_PKTS": "802",
178+
"SAI_PORT_STAT_PFC_3_TX_PKTS": "803",
179+
"SAI_PORT_STAT_PFC_4_TX_PKTS": "804",
180+
"SAI_PORT_STAT_PFC_5_TX_PKTS": "805",
181+
"SAI_PORT_STAT_PFC_6_TX_PKTS": "806",
182+
"SAI_PORT_STAT_PFC_7_TX_PKTS": "807"
135183
},
136184
"COUNTERS:oid:0x21000000000000": {
137185
"SAI_SWITCH_STAT_IN_DROP_REASON_RANGE_BASE": "1000"

0 commit comments

Comments
 (0)