Skip to content

Commit 8dee36c

Browse files
authored
[portstat] Update portstat to use CounterTable API (sonic-net#2207)
What I did To support gearbox port counter in CLI, following sonic-net/sonic-swss#2218 and sonic-net/sonic-swss-common#622. How I did it Use swsscommon CounterTable API and PortCounter type, covering different underlying switch architecture, asic-only, asic+gearbox.
1 parent 7d9faf3 commit 8dee36c

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed

scripts/portstat

+8-6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ try:
3333
except KeyError:
3434
pass
3535

36+
from swsscommon.swsscommon import CounterTable, PortCounter
3637
from utilities_common import constants
3738
from utilities_common.intf_filter import parse_interface_in_filter
3839
import utilities_common.multi_asic as multi_asic_util
@@ -157,20 +158,20 @@ class Portstat(object):
157158
"""
158159
Get the counters info from database.
159160
"""
160-
def get_counters(table_id):
161+
def get_counters(port):
161162
"""
162163
Get the counters from specific table.
163164
"""
164165
fields = ["0"]*BUCKET_NUM
165166

167+
_, fvs = counter_table.get(PortCounter(), port)
168+
fvs = dict(fvs)
166169
for pos, cntr_list in counter_bucket_dict.items():
167170
for counter_name in cntr_list:
168-
full_table_id = COUNTER_TABLE_PREFIX + table_id
169-
counter_data = self.db.get(self.db.COUNTERS_DB, full_table_id, counter_name)
170-
if counter_data is None:
171+
if counter_name not in fvs:
171172
fields[pos] = STATUS_NA
172173
elif fields[pos] != STATUS_NA:
173-
fields[pos] = str(int(fields[pos]) + int(counter_data))
174+
fields[pos] = str(int(fields[pos]) + int(fvs[counter_name]))
174175

175176
cntr = NStats._make(fields)
176177
return cntr
@@ -196,13 +197,14 @@ class Portstat(object):
196197
cnstat_dict = OrderedDict()
197198
cnstat_dict['time'] = datetime.datetime.now()
198199
ratestat_dict = OrderedDict()
200+
counter_table = CounterTable(self.db.get_redis_client(self.db.COUNTERS_DB))
199201
if counter_port_name_map is None:
200202
return cnstat_dict, ratestat_dict
201203
for port in natsorted(counter_port_name_map):
202204
port_name = port.split(":")[0]
203205
if self.multi_asic.skip_display(constants.PORT_OBJ, port_name):
204206
continue
205-
cnstat_dict[port] = get_counters(counter_port_name_map[port])
207+
cnstat_dict[port] = get_counters(port)
206208
ratestat_dict[port] = get_rates(counter_port_name_map[port])
207209
return cnstat_dict, ratestat_dict
208210

tests/mock_tables/dbconnector.py

+20
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,30 @@ def keys(self, pattern='*'):
182182
return [key for key in self.redis if regex.match(key)]
183183

184184

185+
class PortCounter:
186+
pass
187+
188+
189+
class CounterTable:
190+
def __init__(self, db):
191+
self.db = db
192+
193+
def get(self, counter, name):
194+
if isinstance(counter, PortCounter):
195+
name_map = "COUNTERS_PORT_NAME_MAP"
196+
else:
197+
return False, ()
198+
199+
key = self.db.hget(name_map, name)
200+
return True, tuple(self.db.get("COUNTERS:" + key).items())
201+
202+
185203
swsssdk.interface.DBInterface._subscribe_keyspace_notification = _subscribe_keyspace_notification
186204
mockredis.MockRedis.config_set = config_set
187205
redis.StrictRedis = SwssSyncClient
188206
SonicV2Connector.connect = connect_SonicV2Connector
189207
swsscommon.SonicV2Connector = SonicV2Connector
190208
swsscommon.ConfigDBConnector = ConfigDBConnector
191209
swsscommon.ConfigDBPipeConnector = ConfigDBPipeConnector
210+
swsscommon.CounterTable = CounterTable
211+
swsscommon.PortCounter = PortCounter

0 commit comments

Comments
 (0)