@@ -51,12 +51,14 @@ NStats = namedtuple("NStats", "rx_ok, rx_err, rx_drop, rx_ovr, tx_ok,\
51
51
rx_uca, rx_mca, rx_bca, rx_all,\
52
52
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,\
53
53
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" )
55
56
header_all = ['IFACE' , 'STATE' , 'RX_OK' , 'RX_BPS' , 'RX_PPS' , 'RX_UTIL' , 'RX_ERR' , 'RX_DRP' , 'RX_OVR' ,
56
57
'TX_OK' , 'TX_BPS' , 'TX_PPS' , 'TX_UTIL' , 'TX_ERR' , 'TX_DRP' , 'TX_OVR' ]
57
58
header_std = ['IFACE' , 'STATE' , 'RX_OK' , 'RX_BPS' , 'RX_UTIL' , 'RX_ERR' , 'RX_DRP' , 'RX_OVR' ,
58
59
'TX_OK' , 'TX_BPS' , 'TX_UTIL' , 'TX_ERR' , 'TX_DRP' , 'TX_OVR' ]
59
60
header_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' ]
60
62
header_rates_only = ['IFACE' , 'STATE' , 'RX_OK' , 'RX_BPS' , 'RX_PPS' , 'RX_UTIL' , 'TX_OK' , 'TX_BPS' , 'TX_PPS' , 'TX_UTIL' ]
61
63
62
64
rates_key_list = [ 'RX_BPS' , 'RX_PPS' , 'RX_UTIL' , 'TX_BPS' , 'TX_PPS' , 'TX_UTIL' ]
@@ -67,7 +69,7 @@ RateStats = namedtuple("RateStats", ratestat_fields)
67
69
The order and count of statistics mentioned below needs to be in sync with the values in portstat script
68
70
So, any fields added/deleted in here should be reflected in portstat script also
69
71
"""
70
- BUCKET_NUM = 42
72
+ BUCKET_NUM = 45
71
73
counter_bucket_dict = {
72
74
0 :['SAI_PORT_STAT_IF_IN_UCAST_PKTS' , 'SAI_PORT_STAT_IF_IN_NON_UCAST_PKTS' ],
73
75
1 :['SAI_PORT_STAT_IF_IN_ERRORS' ],
@@ -110,7 +112,10 @@ counter_bucket_dict = {
110
112
38 :['SAI_PORT_STAT_ETHER_STATS_JABBERS' ],
111
113
39 :['SAI_PORT_STAT_ETHER_STATS_FRAGMENTS' ],
112
114
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' ]
114
119
}
115
120
116
121
STATUS_NA = 'N/A'
@@ -250,7 +255,7 @@ class Portstat(object):
250
255
return STATUS_NA
251
256
252
257
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 ):
254
259
"""
255
260
Print the cnstat.
256
261
"""
@@ -295,6 +300,12 @@ class Portstat(object):
295
300
format_number_with_comma (data .tx_err ),
296
301
format_number_with_comma (data .tx_drop ),
297
302
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 )))
298
309
elif rates_only :
299
310
header = header_rates_only
300
311
table .append ((key , self .get_port_state (key ),
@@ -388,7 +399,10 @@ class Portstat(object):
388
399
print ("Time Since Counters Last Cleared............... " + str (cnstat_old_dict .get ('time' )))
389
400
390
401
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 ):
392
406
"""
393
407
Print the difference between two cnstat results.
394
408
"""
@@ -465,6 +479,19 @@ class Portstat(object):
465
479
format_number_with_comma (cntr .tx_err ),
466
480
format_number_with_comma (cntr .tx_drop ),
467
481
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
+
468
495
elif rates_only :
469
496
header = header_rates_only
470
497
if old_cntr is not None :
@@ -551,6 +578,7 @@ Examples:
551
578
parser .add_argument ('-d' , '--delete' , action = 'store_true' , help = 'Delete saved stats, either the uid or the specified tag' )
552
579
parser .add_argument ('-D' , '--delete-all' , action = 'store_true' , help = 'Delete all saved stats' )
553
580
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' )
554
582
parser .add_argument ('-j' , '--json' , action = 'store_true' , help = 'Display in JSON format' )
555
583
parser .add_argument ('-r' , '--raw' , action = 'store_true' , help = 'Raw stats (unmodified output of netstat)' )
556
584
parser .add_argument ('-R' , '--rate' , action = 'store_true' , help = 'Display interface rates' )
@@ -567,6 +595,7 @@ Examples:
567
595
delete_saved_stats = args .delete
568
596
delete_all_stats = args .delete_all
569
597
errors_only = args .errors
598
+ fec_stats_only = args .fec_stats
570
599
rates_only = args .rate
571
600
use_json = args .json
572
601
raw_stats = args .raw
@@ -603,7 +632,7 @@ Examples:
603
632
604
633
# Now decide what information to display
605
634
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 )
607
636
sys .exit (0 )
608
637
609
638
if save_fresh_stats :
@@ -622,21 +651,21 @@ Examples:
622
651
cnstat_cached_dict = pickle .load (open (cnstat_fqn_file , 'rb' ))
623
652
if not detail :
624
653
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 )
626
655
except IOError as e :
627
656
print (e .errno , e )
628
657
else :
629
658
if tag_name :
630
659
print ("\n File '%s' does not exist" % cnstat_fqn_file )
631
660
print ("Did you run 'portstat -c -t %s' to record the counters via tag %s?\n " % (tag_name , tag_name ))
632
661
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 )
634
663
else :
635
664
#wait for the specified time and then gather the new stats and output the difference.
636
665
time .sleep (wait_time_in_seconds )
637
666
print ("The rates are calculated within %s seconds period" % wait_time_in_seconds )
638
667
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 )
640
669
641
670
if __name__ == "__main__" :
642
671
main ()
0 commit comments