@@ -10,15 +10,35 @@ import argparse
10
10
import cPickle as pickle
11
11
import datetime
12
12
import os .path
13
- import swsssdk
14
13
import sys
15
14
import time
15
+ from collections import OrderedDict , namedtuple
16
+
16
17
17
- from collections import namedtuple , OrderedDict
18
18
from natsort import natsorted
19
19
from tabulate import tabulate
20
- from utilities_common .netstat import ns_diff , ns_brate , ns_prate , ns_util , table_as_json
20
+ from sonic_py_common import multi_asic
21
+
22
+ from utilities_common import constants
21
23
from utilities_common .intf_filter import parse_interface_in_filter
24
+ import utilities_common .multi_asic as multi_asic_util
25
+ from utilities_common .netstat import (ns_brate , ns_diff , ns_prate , ns_util ,
26
+ table_as_json )
27
+
28
+ # mock the redis for unit test purposes #
29
+ try :
30
+ if os .environ ["UTILITIES_UNIT_TESTING" ] == "2" :
31
+ modules_path = os .path .join (os .path .dirname (__file__ ), ".." )
32
+ tests_path = os .path .join (modules_path , "tests" )
33
+ sys .path .insert (0 , modules_path )
34
+ sys .path .insert (0 , tests_path )
35
+ import mock_tables .dbconnector
36
+ if os .environ ["UTILITIES_UNIT_TESTING_TOPOLOGY" ] == "multi_asic" :
37
+ import mock_tables .mock_multi_asic
38
+ mock_tables .dbconnector .load_namespace_config ()
39
+
40
+ except KeyError :
41
+ pass
22
42
23
43
PORT_RATE = 40
24
44
@@ -62,11 +82,25 @@ PORT_STATE_UP = 'U'
62
82
PORT_STATE_DOWN = 'D'
63
83
PORT_STATE_DISABLED = 'X'
64
84
85
+
65
86
class Portstat (object ):
66
- def __init__ (self ):
67
- self .db = swsssdk .SonicV2Connector (host = '127.0.0.1' )
68
- self .db .connect (self .db .COUNTERS_DB )
69
- self .db .connect (self .db .APPL_DB )
87
+ def __init__ (self , namespace , display_option ):
88
+ self .db = None
89
+ self .multi_asic = multi_asic_util .MultiAsic (display_option , namespace )
90
+
91
+ def get_cnstat_dict (self ):
92
+ self .cnstat_dict = OrderedDict ()
93
+ self .cnstat_dict ['time' ] = datetime .datetime .now ()
94
+ self .collect_stat ()
95
+ return self .cnstat_dict
96
+
97
+ @multi_asic_util .run_on_multi_asic
98
+ def collect_stat (self ):
99
+ """
100
+ Collect the statisitics from all the asics present on the
101
+ device and store in a dict
102
+ """
103
+ self .cnstat_dict .update (self .get_cnstat ())
70
104
71
105
def get_cnstat (self ):
72
106
"""
@@ -91,10 +125,12 @@ class Portstat(object):
91
125
counter_port_name_map = self .db .get_all (self .db .COUNTERS_DB , COUNTERS_PORT_NAME_MAP );
92
126
# Build a dictionary of the stats
93
127
cnstat_dict = OrderedDict ()
94
- cnstat_dict ['time' ] = datetime .datetime .now ()
95
128
if counter_port_name_map is None :
96
129
return cnstat_dict
97
130
for port in natsorted (counter_port_name_map ):
131
+ port_name = port .split (":" )[0 ]
132
+ if self .multi_asic .skip_display (constants .PORT_OBJ , port_name ):
133
+ continue
98
134
cnstat_dict [port ] = get_counters (counter_port_name_map [port ])
99
135
return cnstat_dict
100
136
@@ -104,30 +140,36 @@ class Portstat(object):
104
140
"""
105
141
# Get speed from APPL_DB
106
142
full_table_id = PORT_STATUS_TABLE_PREFIX + port_name
107
- speed = self .db .get (self .db .APPL_DB , full_table_id , PORT_SPEED_FIELD )
108
- if speed is None :
109
- speed = PORT_RATE
110
- else :
111
- speed = int (speed )// 1000
143
+ speed = PORT_RATE
144
+ for ns in self .multi_asic .get_ns_list_based_on_options ():
145
+ self .db = multi_asic .connect_to_all_dbs_for_ns (ns )
146
+ speed = self .db .get (self .db .APPL_DB , full_table_id , PORT_SPEED_FIELD )
147
+ if speed is not None :
148
+ return int (speed )// 1000
112
149
return speed
113
150
114
151
def get_port_state (self , port_name ):
115
152
"""
116
153
Get the port state
117
154
"""
118
155
full_table_id = PORT_STATUS_TABLE_PREFIX + port_name
119
- admin_state = self .db .get (self .db .APPL_DB , full_table_id , PORT_ADMIN_STATUS_FIELD )
120
- oper_state = self .db .get (self .db .APPL_DB , full_table_id , PORT_OPER_STATUS_FIELD )
121
- if admin_state is None or oper_state is None :
122
- return STATUS_NA
123
- elif admin_state .upper () == PORT_STATUS_VALUE_DOWN :
124
- return PORT_STATE_DISABLED
125
- elif admin_state .upper () == PORT_STATUS_VALUE_UP and oper_state .upper () == PORT_STATUS_VALUE_UP :
126
- return PORT_STATE_UP
127
- elif admin_state .upper () == PORT_STATUS_VALUE_UP and oper_state .upper () == PORT_STATUS_VALUE_DOWN :
128
- return PORT_STATE_DOWN
129
- else :
130
- return STATUS_NA
156
+ for ns in self .multi_asic .get_ns_list_based_on_options ():
157
+ self .db = multi_asic .connect_to_all_dbs_for_ns (ns )
158
+ admin_state = self .db .get (self .db .APPL_DB , full_table_id , PORT_ADMIN_STATUS_FIELD )
159
+ oper_state = self .db .get (self .db .APPL_DB , full_table_id , PORT_OPER_STATUS_FIELD )
160
+
161
+ if admin_state is None or oper_state is None :
162
+ continue
163
+ if admin_state .upper () == PORT_STATUS_VALUE_DOWN :
164
+ return PORT_STATE_DISABLED
165
+ elif admin_state .upper () == PORT_STATUS_VALUE_UP and oper_state .upper () == PORT_STATUS_VALUE_UP :
166
+ return PORT_STATE_UP
167
+ elif admin_state .upper () == PORT_STATUS_VALUE_UP and oper_state .upper () == PORT_STATUS_VALUE_DOWN :
168
+ return PORT_STATE_DOWN
169
+ else :
170
+ return STATUS_NA
171
+ return STATUS_NA
172
+
131
173
132
174
def cnstat_print (self , cnstat_dict , intf_list , use_json , print_all , errors_only , rates_only ):
133
175
"""
@@ -171,6 +213,7 @@ class Portstat(object):
171
213
else :
172
214
print (tabulate (table , header , tablefmt = 'simple' , stralign = 'right' ))
173
215
216
+
174
217
def cnstat_diff_print (self , cnstat_new_dict , cnstat_old_dict , intf_list , use_json , print_all , errors_only , rates_only ):
175
218
"""
176
219
Print the difference between two cnstat results.
@@ -311,6 +354,8 @@ Examples:
311
354
parser .add_argument ('-t' , '--tag' , type = str , help = 'Save stats with name TAG' , default = None )
312
355
parser .add_argument ('-p' , '--period' , type = int , help = 'Display stats over a specified period (in seconds).' , default = 0 )
313
356
parser .add_argument ('-i' , '--interface' , type = str , help = 'Display stats for interface lists.' , default = None )
357
+ parser .add_argument ('-s' ,'--show' , default = constants .DISPLAY_EXTERNAL , help = 'Display all interfaces or only external interfaces' )
358
+ parser .add_argument ('-n' ,'--namespace' , default = None , help = 'Display interfaces for specific namespace' )
314
359
args = parser .parse_args ()
315
360
316
361
save_fresh_stats = args .clear
@@ -325,6 +370,9 @@ Examples:
325
370
wait_time_in_seconds = args .period
326
371
print_all = args .all
327
372
intf_fs = args .interface
373
+ namespace = args .namespace
374
+ display_option = args .show
375
+
328
376
if tag_name is not None :
329
377
cnstat_file = uid + "-" + tag_name
330
378
else :
@@ -358,9 +406,14 @@ Examples:
358
406
359
407
intf_list = parse_interface_in_filter (intf_fs )
360
408
361
- portstat = Portstat ()
362
- # The cnstat_dict just give an ordered dict of all output.
363
- cnstat_dict = portstat .get_cnstat ()
409
+ # When saving counters to the file, save counters
410
+ # for all ports(Internal and External)
411
+ if save_fresh_stats :
412
+ namespace = None
413
+ display_option = constants .DISPLAY_ALL
414
+
415
+ portstat = Portstat (namespace , display_option )
416
+ cnstat_dict = portstat .get_cnstat_dict ()
364
417
365
418
# Now decide what information to display
366
419
if raw_stats :
@@ -403,8 +456,8 @@ Examples:
403
456
else :
404
457
#wait for the specified time and then gather the new stats and output the difference.
405
458
time .sleep (wait_time_in_seconds )
406
- print ( "The rates are calculated within %s seconds period" % wait_time_in_seconds )
407
- cnstat_new_dict = portstat .get_cnstat ()
459
+ print "The rates are calculated within %s seconds period" % wait_time_in_seconds
460
+ cnstat_new_dict = portstat .get_cnstat_dict ()
408
461
portstat .cnstat_diff_print (cnstat_new_dict , cnstat_dict , intf_list , use_json , print_all , errors_only , rates_only )
409
462
410
463
if __name__ == "__main__" :
0 commit comments