Skip to content

Commit a7897d1

Browse files
authored
[show][interface][counters] Add proposal and changes for fec-histogram for interface counters fec-histogram subcommand (sonic-net#3519)
* [show][interface][counters] Add proposal and changes for fec-histogram for show int counters fec-histogram subcommand Signed-off-by: Vaibhav Dahiya <[email protected]> * add implementation Signed-off-by: Vaibhav Dahiya <[email protected]> * add changes Signed-off-by: Vaibhav Dahiya <[email protected]> * add changes Signed-off-by: Vaibhav Dahiya <[email protected]> * add UT Signed-off-by: Vaibhav Dahiya <[email protected]> * fix test Signed-off-by: Vaibhav Dahiya <[email protected]> * correct doc Signed-off-by: Vaibhav Dahiya <[email protected]> * add changes Signed-off-by: Vaibhav Dahiya <[email protected]> * add cosmetic fix Signed-off-by: Vaibhav Dahiya <[email protected]> * add fixes Signed-off-by: Vaibhav Dahiya <[email protected]> * pep 8 Signed-off-by: Vaibhav Dahiya <[email protected]> * add indentation Signed-off-by: Vaibhav Dahiya <[email protected]> --------- Signed-off-by: Vaibhav Dahiya <[email protected]>
1 parent 5fdc1b6 commit a7897d1

File tree

4 files changed

+151
-1
lines changed

4 files changed

+151
-1
lines changed

doc/Command-Reference.md

+34
Original file line numberDiff line numberDiff line change
@@ -4806,6 +4806,7 @@ Optional argument "-p" specify a period (in seconds) with which to gather counte
48064806
show interfaces counters errors
48074807
show interfaces counters rates
48084808
show interfaces counters rif [-p|--period <period>] [-i <interface_name>]
4809+
show interfaces counters fec-histogram [-i <interface_name>]
48094810
```
48104811

48114812
- Example:
@@ -4923,6 +4924,39 @@ Optionally, you can specify a period (in seconds) with which to gather counters
49234924
admin@sonic:~$ sonic-clear rifcounters
49244925
```
49254926

4927+
The "fec-histogram" subcommand is used to display the fec histogram for the port.
4928+
4929+
When data is transmitted, it's broken down into units called codewords. FEC algorithms add extra data to each codeword that can be used to detect and correct errors in transmission.
4930+
In a FEC histogram, "bins" represent ranges of errors or specific categories of errors. For instance, Bin0 might represent codewords with no errors, while Bin1 could represent codewords with a single bit error, and so on. The histogram shows how many codewords fell into each bin. A high number in the higher bins might indicate a problem with the transmission link, such as signal degradation.
4931+
4932+
- Example:
4933+
```
4934+
admin@str-s6000-acs-11:/usr/bin$ show interface counters fec-histogram -i <PORT>
4935+
4936+
Symbol Errors Per Codeword Codewords
4937+
-------------------------- ---------
4938+
BIN0: 1000000
4939+
BIN1: 900000
4940+
BIN2: 800000
4941+
BIN3: 700000
4942+
BIN4: 600000
4943+
BIN5: 500000
4944+
BIN6: 400000
4945+
BIN7: 300000
4946+
BIN8: 0
4947+
BIN9: 0
4948+
BIN10: 0
4949+
BIN11: 0
4950+
BIN12: 0
4951+
BIN13: 0
4952+
BIN14: 0
4953+
BIN15: 0
4954+
4955+
```
4956+
4957+
4958+
4959+
49264960
**show interfaces description**
49274961

49284962
This command displays the key fields of the interfaces such as Operational Status, Administrative Status, Alias and Description.

show/interfaces/__init__.py

+70
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
HWSKU_JSON = 'hwsku.json'
2020

21+
REDIS_HOSTIP = "127.0.0.1"
22+
2123
# Read given JSON file
2224
def readJsonFile(fileName):
2325
try:
@@ -646,6 +648,74 @@ def fec_stats(verbose, period, namespace, display):
646648

647649
clicommon.run_command(cmd, display_cmd=verbose)
648650

651+
652+
def get_port_oid_mapping():
653+
''' Returns dictionary of all ports interfaces and their OIDs. '''
654+
db = SonicV2Connector(host=REDIS_HOSTIP)
655+
db.connect(db.COUNTERS_DB)
656+
657+
port_oid_map = db.get_all(db.COUNTERS_DB, 'COUNTERS_PORT_NAME_MAP')
658+
659+
db.close(db.COUNTERS_DB)
660+
661+
return port_oid_map
662+
663+
664+
def fetch_fec_histogram(port_oid_map, target_port):
665+
''' Fetch and display FEC histogram for the given port. '''
666+
asic_db = SonicV2Connector(host=REDIS_HOSTIP)
667+
asic_db.connect(asic_db.ASIC_DB)
668+
669+
config_db = ConfigDBConnector()
670+
config_db.connect()
671+
672+
counter_db = SonicV2Connector(host=REDIS_HOSTIP)
673+
counter_db.connect(counter_db.COUNTERS_DB)
674+
675+
if target_port not in port_oid_map:
676+
click.echo('Port {} not found in COUNTERS_PORT_NAME_MAP'.format(target_port), err=True)
677+
raise click.Abort()
678+
679+
port_oid = port_oid_map[target_port]
680+
asic_db_kvp = counter_db.get_all(counter_db.COUNTERS_DB, 'COUNTERS:{}'.format(port_oid))
681+
682+
if asic_db_kvp is not None:
683+
684+
fec_errors = {f'BIN{i}': asic_db_kvp.get
685+
(f'SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S{i}', '0') for i in range(16)}
686+
687+
# Prepare the data for tabulation
688+
table_data = [(bin_label, error_value) for bin_label, error_value in fec_errors.items()]
689+
690+
# Define headers
691+
headers = ["Symbol Errors Per Codeword", "Codewords"]
692+
693+
# Print FEC histogram using tabulate
694+
click.echo(tabulate(table_data, headers=headers))
695+
else:
696+
click.echo('No kvp found in ASIC DB for port {}, exiting'.format(target_port), err=True)
697+
raise click.Abort()
698+
699+
asic_db.close(asic_db.ASIC_DB)
700+
config_db.close(config_db.CONFIG_DB)
701+
counter_db.close(counter_db.COUNTERS_DB)
702+
703+
704+
# 'fec-histogram' subcommand ("show interfaces counters fec-histogram")
705+
@counters.command('fec-histogram')
706+
@multi_asic_util.multi_asic_click_options
707+
@click.argument('interfacename', required=True)
708+
def fec_histogram(interfacename, namespace, display):
709+
"""Show interface counters fec-histogram"""
710+
port_oid_map = get_port_oid_mapping()
711+
712+
# Try to convert interface name from alias
713+
interfacename = try_convert_interfacename_from_alias(click.get_current_context(), interfacename)
714+
715+
# Fetch and display the FEC histogram
716+
fetch_fec_histogram(port_oid_map, interfacename)
717+
718+
649719
# 'rates' subcommand ("show interfaces counters rates")
650720
@counters.command()
651721
@click.option('-p', '--period')

tests/mock_tables/counters_db.json

+17-1
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,23 @@
882882
"SAI_PORT_STAT_ETHER_STATS_JABBERS": "0",
883883
"SAI_PORT_STAT_IF_IN_FEC_CORRECTABLE_FRAMES": "130402",
884884
"SAI_PORT_STAT_IF_IN_FEC_NOT_CORRECTABLE_FRAMES": "3",
885-
"SAI_PORT_STAT_IF_IN_FEC_SYMBOL_ERRORS": "4"
885+
"SAI_PORT_STAT_IF_IN_FEC_SYMBOL_ERRORS": "4",
886+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S0": "1000000",
887+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S1": "900000",
888+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S2": "800000",
889+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S3": "700000",
890+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S4": "600000",
891+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S5": "500000",
892+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S6": "400000",
893+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S7": "300000",
894+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S8": "0",
895+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S9": "0",
896+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S10": "0",
897+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S11": "0",
898+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S12": "0",
899+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S13": "0",
900+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S14": "0",
901+
"SAI_PORT_STAT_IF_IN_FEC_CODEWORD_ERRORS_S15": "0"
886902
},
887903
"COUNTERS:oid:0x1000000000013": {
888904
"SAI_PORT_STAT_IF_IN_UCAST_PKTS": "4",

tests/portstat_test.py

+30
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,27 @@
4242
Ethernet8 N/A 100,317 0 0
4343
"""
4444

45+
intf_fec_counters_fec_hist = """\
46+
Symbol Errors Per Codeword Codewords
47+
---------------------------- -----------
48+
BIN0 1000000
49+
BIN1 900000
50+
BIN2 800000
51+
BIN3 700000
52+
BIN4 600000
53+
BIN5 500000
54+
BIN6 400000
55+
BIN7 300000
56+
BIN8 0
57+
BIN9 0
58+
BIN10 0
59+
BIN11 0
60+
BIN12 0
61+
BIN13 0
62+
BIN14 0
63+
BIN15 0
64+
"""
65+
4566
intf_fec_counters_period = """\
4667
The rates are calculated within 3 seconds period
4768
IFACE STATE FEC_CORR FEC_UNCORR FEC_SYMBOL_ERR
@@ -337,6 +358,15 @@ def test_show_intf_fec_counters(self):
337358
assert return_code == 0
338359
assert result == intf_fec_counters
339360

361+
def test_show_intf_counters_fec_histogram(self):
362+
runner = CliRunner()
363+
result = runner.invoke(
364+
show.cli.commands["interfaces"].commands["counters"].commands["fec-histogram"], ["Ethernet0"])
365+
print(result.exit_code)
366+
print(result.output)
367+
assert result.exit_code == 0
368+
assert result.output == intf_fec_counters_fec_hist
369+
340370
def test_show_intf_fec_counters_period(self):
341371
runner = CliRunner()
342372
result = runner.invoke(show.cli.commands["interfaces"].commands["counters"].commands["fec-stats"],

0 commit comments

Comments
 (0)