@@ -51,12 +51,14 @@ NStats = namedtuple("NStats", "rx_ok, rx_err, rx_drop, rx_ovr, tx_ok,\
5151 rx_uca, rx_mca, rx_bca, rx_all,\
5252 tx_64, tx_65_127, tx_128_255, tx_256_511, tx_512_1023, tx_1024_1518, tx_1519_2047, tx_2048_4095, tx_4096_9216, tx_9217_16383,\
5353 tx_uca, tx_mca, tx_bca, tx_all,\
54- rx_jbr, rx_frag, rx_usize, rx_ovrrun" )
54+ rx_jbr, rx_frag, rx_usize, rx_ovrrun,\
55+ fec_corr, fec_uncorr, fec_symbol_err" )
5556header_all = ['IFACE' , 'STATE' , 'RX_OK' , 'RX_BPS' , 'RX_PPS' , 'RX_UTIL' , 'RX_ERR' , 'RX_DRP' , 'RX_OVR' ,
5657 'TX_OK' , 'TX_BPS' , 'TX_PPS' , 'TX_UTIL' , 'TX_ERR' , 'TX_DRP' , 'TX_OVR' ]
5758header_std = ['IFACE' , 'STATE' , 'RX_OK' , 'RX_BPS' , 'RX_UTIL' , 'RX_ERR' , 'RX_DRP' , 'RX_OVR' ,
5859 'TX_OK' , 'TX_BPS' , 'TX_UTIL' , 'TX_ERR' , 'TX_DRP' , 'TX_OVR' ]
5960header_errors_only = ['IFACE' , 'STATE' , 'RX_ERR' , 'RX_DRP' , 'RX_OVR' , 'TX_ERR' , 'TX_DRP' , 'TX_OVR' ]
61+ header_fec_only = ['IFACE' , 'STATE' , 'FEC_CORR' , 'FEC_UNCORR' , 'FEC_SYMBOL_ERR' ]
6062header_rates_only = ['IFACE' , 'STATE' , 'RX_OK' , 'RX_BPS' , 'RX_PPS' , 'RX_UTIL' , 'TX_OK' , 'TX_BPS' , 'TX_PPS' , 'TX_UTIL' ]
6163
6264rates_key_list = [ 'RX_BPS' , 'RX_PPS' , 'RX_UTIL' , 'TX_BPS' , 'TX_PPS' , 'TX_UTIL' ]
@@ -67,7 +69,7 @@ RateStats = namedtuple("RateStats", ratestat_fields)
6769The order and count of statistics mentioned below needs to be in sync with the values in portstat script
6870So, any fields added/deleted in here should be reflected in portstat script also
6971"""
70- BUCKET_NUM = 42
72+ BUCKET_NUM = 45
7173counter_bucket_dict = {
7274 0 :['SAI_PORT_STAT_IF_IN_UCAST_PKTS' , 'SAI_PORT_STAT_IF_IN_NON_UCAST_PKTS' ],
7375 1 :['SAI_PORT_STAT_IF_IN_ERRORS' ],
@@ -110,7 +112,10 @@ counter_bucket_dict = {
110112 38 :['SAI_PORT_STAT_ETHER_STATS_JABBERS' ],
111113 39 :['SAI_PORT_STAT_ETHER_STATS_FRAGMENTS' ],
112114 40 :['SAI_PORT_STAT_ETHER_STATS_UNDERSIZE_PKTS' ],
113- 41 :['SAI_PORT_STAT_IP_IN_RECEIVES' ]
115+ 41 :['SAI_PORT_STAT_IP_IN_RECEIVES' ],
116+ 42 :['SAI_PORT_STAT_IF_IN_FEC_CORRECTABLE_FRAMES' ],
117+ 43 :['SAI_PORT_STAT_IF_IN_FEC_NOT_CORRECTABLE_FRAMES' ],
118+ 44 :['SAI_PORT_STAT_IF_IN_FEC_SYMBOL_ERRORS' ]
114119}
115120
116121STATUS_NA = 'N/A'
@@ -250,7 +255,7 @@ class Portstat(object):
250255 return STATUS_NA
251256
252257
253- def cnstat_print (self , cnstat_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , rates_only , detail = False ):
258+ def cnstat_print (self , cnstat_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , fec_stats_only , rates_only , detail = False ):
254259 """
255260 Print the cnstat.
256261 """
@@ -295,6 +300,12 @@ class Portstat(object):
295300 format_number_with_comma (data .tx_err ),
296301 format_number_with_comma (data .tx_drop ),
297302 format_number_with_comma (data .tx_ovr )))
303+ elif fec_stats_only :
304+ header = header_fec_only
305+ table .append ((key , self .get_port_state (key ),
306+ format_number_with_comma (data .fec_corr ),
307+ format_number_with_comma (data .fec_uncorr ),
308+ format_number_with_comma (data .fec_symbol_err )))
298309 elif rates_only :
299310 header = header_rates_only
300311 table .append ((key , self .get_port_state (key ),
@@ -388,7 +399,10 @@ class Portstat(object):
388399 print ("Time Since Counters Last Cleared............... " + str (cnstat_old_dict .get ('time' )))
389400
390401
391- def cnstat_diff_print (self , cnstat_new_dict , cnstat_old_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , rates_only , detail = False ):
402+ def cnstat_diff_print (self , cnstat_new_dict , cnstat_old_dict ,
403+ ratestat_dict , intf_list , use_json ,
404+ print_all , errors_only , fec_stats_only ,
405+ rates_only , detail = False ):
392406 """
393407 Print the difference between two cnstat results.
394408 """
@@ -465,6 +479,19 @@ class Portstat(object):
465479 format_number_with_comma (cntr .tx_err ),
466480 format_number_with_comma (cntr .tx_drop ),
467481 format_number_with_comma (cntr .tx_ovr )))
482+ elif fec_stats_only :
483+ header = header_fec_only
484+ if old_cntr is not None :
485+ table .append ((key , self .get_port_state (key ),
486+ ns_diff (cntr .fec_corr , old_cntr .fec_corr ),
487+ ns_diff (cntr .fec_uncorr , old_cntr .fec_uncorr ),
488+ ns_diff (cntr .fec_symbol_err , old_cntr .fec_symbol_err )))
489+ else :
490+ table .append ((key , self .get_port_state (key ),
491+ format_number_with_comma (cntr .fec_corr ),
492+ format_number_with_comma (cntr .fec_uncorr ),
493+ format_number_with_comma (cntr .fec_symbol_err )))
494+
468495 elif rates_only :
469496 header = header_rates_only
470497 if old_cntr is not None :
@@ -551,6 +578,7 @@ Examples:
551578 parser .add_argument ('-d' , '--delete' , action = 'store_true' , help = 'Delete saved stats, either the uid or the specified tag' )
552579 parser .add_argument ('-D' , '--delete-all' , action = 'store_true' , help = 'Delete all saved stats' )
553580 parser .add_argument ('-e' , '--errors' , action = 'store_true' , help = 'Display interface errors' )
581+ parser .add_argument ('-f' , '--fec-stats' , action = 'store_true' , help = 'Display FEC related statistics' )
554582 parser .add_argument ('-j' , '--json' , action = 'store_true' , help = 'Display in JSON format' )
555583 parser .add_argument ('-r' , '--raw' , action = 'store_true' , help = 'Raw stats (unmodified output of netstat)' )
556584 parser .add_argument ('-R' , '--rate' , action = 'store_true' , help = 'Display interface rates' )
@@ -567,6 +595,7 @@ Examples:
567595 delete_saved_stats = args .delete
568596 delete_all_stats = args .delete_all
569597 errors_only = args .errors
598+ fec_stats_only = args .fec_stats
570599 rates_only = args .rate
571600 use_json = args .json
572601 raw_stats = args .raw
@@ -603,7 +632,7 @@ Examples:
603632
604633 # Now decide what information to display
605634 if raw_stats :
606- portstat .cnstat_print (cnstat_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , rates_only )
635+ portstat .cnstat_print (cnstat_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , fec_stats_only , rates_only )
607636 sys .exit (0 )
608637
609638 if save_fresh_stats :
@@ -622,21 +651,21 @@ Examples:
622651 cnstat_cached_dict = pickle .load (open (cnstat_fqn_file , 'rb' ))
623652 if not detail :
624653 print ("Last cached time was " + str (cnstat_cached_dict .get ('time' )))
625- portstat .cnstat_diff_print (cnstat_dict , cnstat_cached_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , rates_only , detail )
654+ portstat .cnstat_diff_print (cnstat_dict , cnstat_cached_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , fec_stats_only , rates_only , detail )
626655 except IOError as e :
627656 print (e .errno , e )
628657 else :
629658 if tag_name :
630659 print ("\n File '%s' does not exist" % cnstat_fqn_file )
631660 print ("Did you run 'portstat -c -t %s' to record the counters via tag %s?\n " % (tag_name , tag_name ))
632661 else :
633- portstat .cnstat_print (cnstat_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , rates_only , detail )
662+ portstat .cnstat_print (cnstat_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , fec_stats_only , rates_only , detail )
634663 else :
635664 #wait for the specified time and then gather the new stats and output the difference.
636665 time .sleep (wait_time_in_seconds )
637666 print ("The rates are calculated within %s seconds period" % wait_time_in_seconds )
638667 cnstat_new_dict , ratestat_new_dict = portstat .get_cnstat_dict ()
639- portstat .cnstat_diff_print (cnstat_new_dict , cnstat_dict , ratestat_new_dict , intf_list , use_json , print_all , errors_only , rates_only , detail )
668+ portstat .cnstat_diff_print (cnstat_new_dict , cnstat_dict , ratestat_new_dict , intf_list , use_json , print_all , errors_only , fec_stats_only , rates_only , detail )
640669
641670if __name__ == "__main__" :
642671 main ()
0 commit comments