@@ -29,13 +29,37 @@ except KeyError:
29
29
from collections import namedtuple , OrderedDict
30
30
from natsort import natsorted
31
31
from tabulate import tabulate
32
- from utilities_common .netstat import ns_diff , ns_brate , ns_prate , table_as_json , STATUS_NA
32
+ from utilities_common .netstat import ns_diff , table_as_json , STATUS_NA , format_brate , format_prate
33
+ from swsscommon .swsscommon import SonicV2Connector
34
+
35
+ nstat_fields = (
36
+ "rx_b_ok" ,
37
+ "rx_p_ok" ,
38
+ "tx_b_ok" ,
39
+ "tx_p_ok" ,
40
+ "rx_b_err" ,
41
+ "rx_p_err" ,
42
+ "tx_b_err" ,
43
+ "tx_p_err"
44
+ )
45
+
46
+ NStats = namedtuple ("NStats" , nstat_fields )
33
47
34
- NStats = namedtuple ("NStats" , "rx_b_ok, rx_p_ok, tx_b_ok, tx_p_ok,\
35
- rx_b_err, rx_p_err, tx_b_err, tx_p_err," )
48
+ header = [
49
+ 'IFACE' ,
50
+ 'RX_OK' ,
51
+ 'RX_BPS' ,
52
+ 'RX_PPS' ,
53
+ 'RX_ERR' ,
54
+ 'TX_OK' ,
55
+ 'TX_BPS' ,
56
+ 'TX_PPS' ,
57
+ 'TX_ERR'
58
+ ]
36
59
37
- header = ['IFACE' , 'RX_OK' , 'RX_BPS' , 'RX_PPS' , 'RX_ERR' ,
38
- 'TX_OK' , 'TX_BPS' , 'TX_PPS' , 'TX_ERR' ]
60
+ rates_key_list = [ 'RX_BPS' , 'RX_PPS' , 'TX_BPS' , 'TX_PPS' ]
61
+ ratestat_fields = ("rx_bps" , "rx_pps" , "tx_bps" , "tx_pps" )
62
+ RateStats = namedtuple ("RateStats" , ratestat_fields )
39
63
40
64
counter_names = (
41
65
'SAI_ROUTER_INTERFACE_STAT_IN_OCTETS' ,
@@ -48,18 +72,10 @@ counter_names = (
48
72
'SAI_ROUTER_INTERFACE_STAT_OUT_ERROR_PACKETS'
49
73
)
50
74
75
+ RATES_TABLE_PREFIX = "RATES:"
51
76
52
77
COUNTER_TABLE_PREFIX = "COUNTERS:"
53
78
COUNTERS_RIF_NAME_MAP = "COUNTERS_RIF_NAME_MAP"
54
- COUNTERS_RIF_TYPE_MAP = "COUNTERS_RIF_TYPE_MAP"
55
-
56
- INTERFACE_TABLE_PREFIX = "PORT_TABLE:"
57
- INTF_STATUS_VALUE_UP = 'UP'
58
- INTF_STATUS_VALUE_DOWN = 'DOWN'
59
-
60
- INTF_STATE_UP = 'U'
61
- INTF_STATE_DOWN = 'D'
62
- INTF_STATE_DISABLED = 'X'
63
79
64
80
class Intfstat (object ):
65
81
def __init__ (self ):
@@ -75,7 +91,7 @@ class Intfstat(object):
75
91
"""
76
92
Get the counters from specific table.
77
93
"""
78
- fields = [STATUS_NA ] * ( len (header ) - 1 )
94
+ fields = [STATUS_NA ] * len (nstat_fields )
79
95
for pos , counter_name in enumerate (counter_names ):
80
96
full_table_id = COUNTER_TABLE_PREFIX + table_id
81
97
counter_data = self .db .get (self .db .COUNTERS_DB , full_table_id , counter_name )
@@ -84,13 +100,28 @@ class Intfstat(object):
84
100
cntr = NStats ._make (fields )
85
101
return cntr
86
102
103
+ def get_rates (table_id ):
104
+ """
105
+ Get the rates from specific table.
106
+ """
107
+ fields = ["0" ,"0" ,"0" ,"0" ]
108
+ for pos , name in enumerate (rates_key_list ):
109
+ full_table_id = RATES_TABLE_PREFIX + table_id
110
+ counter_data = self .db .get (self .db .COUNTERS_DB , full_table_id , name )
111
+ if counter_data is None :
112
+ fields [pos ] = STATUS_NA
113
+ elif fields [pos ] != STATUS_NA :
114
+ fields [pos ] = float (counter_data )
115
+ cntr = RateStats ._make (fields )
116
+ return cntr
117
+
87
118
# Build a dictionary of the stats
88
119
cnstat_dict = OrderedDict ()
89
120
cnstat_dict ['time' ] = datetime .datetime .now ()
121
+ ratestat_dict = OrderedDict ()
90
122
91
123
# Get the info from database
92
- counter_rif_name_map = self .db .get_all (self .db .COUNTERS_DB , COUNTERS_RIF_NAME_MAP );
93
-
124
+ counter_rif_name_map = self .db .get_all (self .db .COUNTERS_DB , COUNTERS_RIF_NAME_MAP )
94
125
95
126
if counter_rif_name_map is None :
96
127
print ("No %s in the DB!" % COUNTERS_RIF_NAME_MAP )
@@ -102,31 +133,15 @@ class Intfstat(object):
102
133
103
134
if rif :
104
135
cnstat_dict [rif ] = get_counters (counter_rif_name_map [rif ])
105
- return cnstat_dict
136
+ ratestat_dict [rif ] = get_rates (counter_rif_name_map [rif ])
137
+ return cnstat_dict , ratestat_dict
106
138
107
139
for rif in natsorted (counter_rif_name_map ):
108
140
cnstat_dict [rif ] = get_counters (counter_rif_name_map [rif ])
109
- return cnstat_dict
110
-
111
- def get_intf_state (self , port_name ):
112
- """
113
- Get the port state
114
- """
115
- full_table_id = PORT_STATUS_TABLE_PREFIX + port_name
116
- admin_state = self .db .get (self .db .APPL_DB , full_table_id , PORT_ADMIN_STATUS_FIELD )
117
- oper_state = self .db .get (self .db .APPL_DB , full_table_id , PORT_OPER_STATUS_FIELD )
118
- if admin_state is None or oper_state is None :
119
- return STATUS_NA
120
- elif admin_state .upper () == PORT_STATUS_VALUE_DOWN :
121
- return PORT_STATE_DISABLED
122
- elif admin_state .upper () == PORT_STATUS_VALUE_UP and oper_state .upper () == PORT_STATUS_VALUE_UP :
123
- return PORT_STATE_UP
124
- elif admin_state .upper () == PORT_STATUS_VALUE_UP and oper_state .upper () == PORT_STATUS_VALUE_DOWN :
125
- return PORT_STATE_DOWN
126
- else :
127
- return STATUS_NA
141
+ ratestat_dict [rif ] = get_rates (counter_rif_name_map [rif ])
142
+ return cnstat_dict , ratestat_dict
128
143
129
- def cnstat_print (self , cnstat_dict , use_json ):
144
+ def cnstat_print (self , cnstat_dict , ratestat_dict , use_json ):
130
145
"""
131
146
Print the cnstat.
132
147
"""
@@ -136,16 +151,25 @@ class Intfstat(object):
136
151
if key == 'time' :
137
152
continue
138
153
139
- table .append ((key , data .rx_p_ok , STATUS_NA , STATUS_NA , data .rx_p_err ,
140
- data .tx_p_ok , STATUS_NA , STATUS_NA , data .tx_p_err ))
154
+ rates = ratestat_dict .get (key , RateStats ._make ([STATUS_NA ] * len (rates_key_list )))
155
+
156
+ table .append ((key ,
157
+ data .rx_p_ok ,
158
+ format_brate (rates .rx_bps ),
159
+ format_prate (rates .rx_pps ),
160
+ data .rx_p_err ,
161
+ data .tx_p_ok ,
162
+ format_brate (rates .tx_bps ),
163
+ format_prate (rates .tx_pps ),
164
+ data .tx_p_err ))
141
165
142
166
if use_json :
143
167
print (table_as_json (table , header ))
144
168
145
169
else :
146
170
print (tabulate (table , header , tablefmt = 'simple' , stralign = 'right' ))
147
171
148
- def cnstat_diff_print (self , cnstat_new_dict , cnstat_old_dict , use_json ):
172
+ def cnstat_diff_print (self , cnstat_new_dict , cnstat_old_dict , ratestat_dict , use_json ):
149
173
"""
150
174
Print the difference between two cnstat results.
151
175
"""
@@ -154,33 +178,34 @@ class Intfstat(object):
154
178
155
179
for key , cntr in cnstat_new_dict .items ():
156
180
if key == 'time' :
157
- time_gap = cnstat_new_dict .get ('time' ) - cnstat_old_dict .get ('time' )
158
- time_gap = time_gap .total_seconds ()
159
181
continue
160
182
old_cntr = None
161
183
if key in cnstat_old_dict :
162
184
old_cntr = cnstat_old_dict .get (key )
163
185
186
+ rates = ratestat_dict .get (key , RateStats ._make ([STATUS_NA ] * len (rates_key_list )))
187
+
164
188
if old_cntr is not None :
165
189
table .append ((key ,
166
190
ns_diff (cntr .rx_p_ok , old_cntr .rx_p_ok ),
167
- ns_brate ( cntr . rx_b_ok , old_cntr . rx_b_ok , time_gap ),
168
- ns_prate ( cntr . rx_p_ok , old_cntr . rx_p_ok , time_gap ),
191
+ format_brate ( rates . rx_bps ),
192
+ format_prate ( rates . rx_pps ),
169
193
ns_diff (cntr .rx_p_err , old_cntr .rx_p_err ),
170
194
ns_diff (cntr .tx_p_ok , old_cntr .tx_p_ok ),
171
- ns_brate ( cntr . tx_b_ok , old_cntr . tx_b_ok , time_gap ),
172
- ns_prate ( cntr . tx_p_ok , old_cntr . tx_p_ok , time_gap ),
195
+ format_brate ( rates . tx_bps ),
196
+ format_prate ( rates . tx_pps ),
173
197
ns_diff (cntr .tx_p_err , old_cntr .tx_p_err )))
174
198
else :
175
199
table .append ((key ,
176
200
cntr .rx_p_ok ,
177
- STATUS_NA ,
178
- STATUS_NA ,
201
+ format_brate ( rates . rx_bps ) ,
202
+ format_prate ( rates . rx_pps ) ,
179
203
cntr .rx_p_err ,
180
204
cntr .tx_p_ok ,
181
- STATUS_NA ,
182
- STATUS_NA ,
205
+ format_brate ( rates . tx_bps ) ,
206
+ format_prate ( rates . tx_pps ) ,
183
207
cntr .tx_p_err ))
208
+
184
209
if use_json :
185
210
print (table_as_json (table , header ))
186
211
else :
@@ -292,7 +317,7 @@ def main():
292
317
sys .exit (0 )
293
318
294
319
intfstat = Intfstat ()
295
- cnstat_dict = intfstat .get_cnstat (rif = interface_name )
320
+ cnstat_dict , ratestat_dict = intfstat .get_cnstat (rif = interface_name )
296
321
297
322
# At this point, either we'll create a file or open an existing one.
298
323
if not os .path .exists (cnstat_dir ):
@@ -346,7 +371,7 @@ def main():
346
371
if interface_name :
347
372
intfstat .cnstat_single_interface (interface_name , cnstat_dict , cnstat_cached_dict )
348
373
else :
349
- intfstat .cnstat_diff_print (cnstat_dict , cnstat_cached_dict , use_json )
374
+ intfstat .cnstat_diff_print (cnstat_dict , cnstat_cached_dict , ratestat_dict , use_json )
350
375
except IOError as e :
351
376
print (e .errno , e )
352
377
else :
@@ -357,16 +382,16 @@ def main():
357
382
if interface_name :
358
383
intfstat .cnstat_single_interface (interface_name , cnstat_dict , None )
359
384
else :
360
- intfstat .cnstat_print (cnstat_dict , use_json )
385
+ intfstat .cnstat_print (cnstat_dict , ratestat_dict , use_json )
361
386
else :
362
387
#wait for the specified time and then gather the new stats and output the difference.
363
388
time .sleep (wait_time_in_seconds )
364
389
print ("The rates are calculated within %s seconds period" % wait_time_in_seconds )
365
- cnstat_new_dict = intfstat .get_cnstat (rif = interface_name )
390
+ cnstat_new_dict , ratestat_new_dict = intfstat .get_cnstat (rif = interface_name )
366
391
if interface_name :
367
392
intfstat .cnstat_single_interface (interface_name , cnstat_new_dict , cnstat_dict )
368
393
else :
369
- intfstat .cnstat_diff_print (cnstat_new_dict , cnstat_dict , use_json )
394
+ intfstat .cnstat_diff_print (cnstat_new_dict , cnstat_dict , ratestat_new_dict , use_json )
370
395
371
396
if __name__ == "__main__" :
372
397
main ()
0 commit comments