@@ -48,12 +48,14 @@ NStats = namedtuple("NStats", "rx_ok, rx_err, rx_drop, rx_ovr, tx_ok,\
48
48
rx_uca, rx_mca, rx_bca, rx_all,\
49
49
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,\
50
50
tx_uca, tx_mca, tx_bca, tx_all,\
51
- rx_jbr, rx_frag, rx_usize, rx_ovrrun" )
51
+ rx_jbr, rx_frag, rx_usize, rx_ovrrun,\
52
+ fec_corr, fec_uncorr, fec_symbol_err" )
52
53
header_all = ['IFACE' , 'STATE' , 'RX_OK' , 'RX_BPS' , 'RX_PPS' , 'RX_UTIL' , 'RX_ERR' , 'RX_DRP' , 'RX_OVR' ,
53
54
'TX_OK' , 'TX_BPS' , 'TX_PPS' , 'TX_UTIL' , 'TX_ERR' , 'TX_DRP' , 'TX_OVR' ]
54
55
header_std = ['IFACE' , 'STATE' , 'RX_OK' , 'RX_BPS' , 'RX_UTIL' , 'RX_ERR' , 'RX_DRP' , 'RX_OVR' ,
55
56
'TX_OK' , 'TX_BPS' , 'TX_UTIL' , 'TX_ERR' , 'TX_DRP' , 'TX_OVR' ]
56
57
header_errors_only = ['IFACE' , 'STATE' , 'RX_ERR' , 'RX_DRP' , 'RX_OVR' , 'TX_ERR' , 'TX_DRP' , 'TX_OVR' ]
58
+ header_fec_only = ['IFACE' , 'STATE' , 'FEC_CORR' , 'FEC_UNCORR' , 'FEC_SYMBOL_ERR' ]
57
59
header_rates_only = ['IFACE' , 'STATE' , 'RX_OK' , 'RX_BPS' , 'RX_PPS' , 'RX_UTIL' , 'TX_OK' , 'TX_BPS' , 'TX_PPS' , 'TX_UTIL' ]
58
60
59
61
rates_key_list = [ 'RX_BPS' , 'RX_PPS' , 'RX_UTIL' , 'TX_BPS' , 'TX_PPS' , 'TX_UTIL' ]
@@ -64,7 +66,7 @@ RateStats = namedtuple("RateStats", ratestat_fields)
64
66
The order and count of statistics mentioned below needs to be in sync with the values in portstat script
65
67
So, any fields added/deleted in here should be reflected in portstat script also
66
68
"""
67
- BUCKET_NUM = 42
69
+ BUCKET_NUM = 45
68
70
counter_bucket_dict = {
69
71
0 :['SAI_PORT_STAT_IF_IN_UCAST_PKTS' , 'SAI_PORT_STAT_IF_IN_NON_UCAST_PKTS' ],
70
72
1 :['SAI_PORT_STAT_IF_IN_ERRORS' ],
@@ -107,7 +109,10 @@ counter_bucket_dict = {
107
109
38 :['SAI_PORT_STAT_ETHER_STATS_JABBERS' ],
108
110
39 :['SAI_PORT_STAT_ETHER_STATS_FRAGMENTS' ],
109
111
40 :['SAI_PORT_STAT_ETHER_STATS_UNDERSIZE_PKTS' ],
110
- 41 :['SAI_PORT_STAT_IP_IN_RECEIVES' ]
112
+ 41 :['SAI_PORT_STAT_IP_IN_RECEIVES' ],
113
+ 42 :['SAI_PORT_STAT_IF_IN_FEC_CORRECTABLE_FRAMES' ],
114
+ 43 :['SAI_PORT_STAT_IF_IN_FEC_NOT_CORRECTABLE_FRAMES' ],
115
+ 44 :['SAI_PORT_STAT_IF_IN_FEC_SYMBOL_ERRORS' ]
111
116
}
112
117
113
118
STATUS_NA = 'N/A'
@@ -246,7 +251,7 @@ class Portstat(object):
246
251
return STATUS_NA
247
252
248
253
249
- def cnstat_print (self , cnstat_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , rates_only , detail = False ):
254
+ def cnstat_print (self , cnstat_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , fec_stats_only , rates_only , detail = False ):
250
255
"""
251
256
Print the cnstat.
252
257
"""
@@ -291,6 +296,12 @@ class Portstat(object):
291
296
format_number_with_comma (data .tx_err ),
292
297
format_number_with_comma (data .tx_drop ),
293
298
format_number_with_comma (data .tx_ovr )))
299
+ elif fec_stats_only :
300
+ header = header_fec_only
301
+ table .append ((key , self .get_port_state (key ),
302
+ format_number_with_comma (data .fec_corr ),
303
+ format_number_with_comma (data .fec_uncorr ),
304
+ format_number_with_comma (data .fec_symbol_err )))
294
305
elif rates_only :
295
306
header = header_rates_only
296
307
table .append ((key , self .get_port_state (key ),
@@ -384,7 +395,10 @@ class Portstat(object):
384
395
print ("Time Since Counters Last Cleared............... " + str (cnstat_old_dict .get ('time' )))
385
396
386
397
387
- 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 ):
398
+ def cnstat_diff_print (self , cnstat_new_dict , cnstat_old_dict ,
399
+ ratestat_dict , intf_list , use_json ,
400
+ print_all , errors_only , fec_stats_only ,
401
+ rates_only , detail = False ):
388
402
"""
389
403
Print the difference between two cnstat results.
390
404
"""
@@ -461,6 +475,19 @@ class Portstat(object):
461
475
format_number_with_comma (cntr .tx_err ),
462
476
format_number_with_comma (cntr .tx_drop ),
463
477
format_number_with_comma (cntr .tx_ovr )))
478
+ elif fec_stats_only :
479
+ header = header_fec_only
480
+ if old_cntr is not None :
481
+ table .append ((key , self .get_port_state (key ),
482
+ ns_diff (cntr .fec_corr , old_cntr .fec_corr ),
483
+ ns_diff (cntr .fec_uncorr , old_cntr .fec_uncorr ),
484
+ ns_diff (cntr .fec_symbol_err , old_cntr .fec_symbol_err )))
485
+ else :
486
+ table .append ((key , self .get_port_state (key ),
487
+ format_number_with_comma (cntr .fec_corr ),
488
+ format_number_with_comma (cntr .fec_uncorr ),
489
+ format_number_with_comma (cntr .fec_symbol_err )))
490
+
464
491
elif rates_only :
465
492
header = header_rates_only
466
493
if old_cntr is not None :
@@ -547,6 +574,7 @@ Examples:
547
574
parser .add_argument ('-d' , '--delete' , action = 'store_true' , help = 'Delete saved stats, either the uid or the specified tag' )
548
575
parser .add_argument ('-D' , '--delete-all' , action = 'store_true' , help = 'Delete all saved stats' )
549
576
parser .add_argument ('-e' , '--errors' , action = 'store_true' , help = 'Display interface errors' )
577
+ parser .add_argument ('-f' , '--fec-stats' , action = 'store_true' , help = 'Display FEC related statistics' )
550
578
parser .add_argument ('-j' , '--json' , action = 'store_true' , help = 'Display in JSON format' )
551
579
parser .add_argument ('-r' , '--raw' , action = 'store_true' , help = 'Raw stats (unmodified output of netstat)' )
552
580
parser .add_argument ('-R' , '--rate' , action = 'store_true' , help = 'Display interface rates' )
@@ -563,6 +591,7 @@ Examples:
563
591
delete_saved_stats = args .delete
564
592
delete_all_stats = args .delete_all
565
593
errors_only = args .errors
594
+ fec_stats_only = args .fec_stats
566
595
rates_only = args .rate
567
596
use_json = args .json
568
597
raw_stats = args .raw
@@ -619,7 +648,7 @@ Examples:
619
648
620
649
# Now decide what information to display
621
650
if raw_stats :
622
- portstat .cnstat_print (cnstat_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , rates_only )
651
+ portstat .cnstat_print (cnstat_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , fec_stats_only , rates_only )
623
652
sys .exit (0 )
624
653
625
654
# At this point, either we'll create a file or open an existing one.
@@ -647,21 +676,21 @@ Examples:
647
676
cnstat_cached_dict = pickle .load (open (cnstat_fqn_file , 'rb' ))
648
677
if not detail :
649
678
print ("Last cached time was " + str (cnstat_cached_dict .get ('time' )))
650
- portstat .cnstat_diff_print (cnstat_dict , cnstat_cached_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , rates_only , detail )
679
+ 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 )
651
680
except IOError as e :
652
681
print (e .errno , e )
653
682
else :
654
683
if tag_name :
655
684
print ("\n File '%s' does not exist" % cnstat_fqn_file )
656
685
print ("Did you run 'portstat -c -t %s' to record the counters via tag %s?\n " % (tag_name , tag_name ))
657
686
else :
658
- portstat .cnstat_print (cnstat_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , rates_only , detail )
687
+ portstat .cnstat_print (cnstat_dict , ratestat_dict , intf_list , use_json , print_all , errors_only , fec_stats_only , rates_only , detail )
659
688
else :
660
689
#wait for the specified time and then gather the new stats and output the difference.
661
690
time .sleep (wait_time_in_seconds )
662
691
print ("The rates are calculated within %s seconds period" % wait_time_in_seconds )
663
692
cnstat_new_dict , ratestat_new_dict = portstat .get_cnstat_dict ()
664
- portstat .cnstat_diff_print (cnstat_new_dict , cnstat_dict , ratestat_new_dict , intf_list , use_json , print_all , errors_only , rates_only , detail )
693
+ 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 )
665
694
666
695
if __name__ == "__main__" :
667
696
main ()
0 commit comments