Skip to content

Commit 5d1ad05

Browse files
authored
[show] add support for muxcable metrics (#1615)
* [show] add support for muxcable metrics What I did Added support for show muxcable metrics. This essentially records what events came to different modules per se for toggling the mux from one state to another. for example admin@sonic$ show muxcable metrics Ethernet0 --json { "linkmgrd_switch_active_start": "2021-May-13 10:00:21.420898", "linkmgrd_switch_standby_end": "2021-May-13 10:01:15.696728", "linkmgrd_switch_unknown_end": "2021-May-13 10:00:26.123319", "xcvrd_switch_standby_end": "2021-May-13 10:01:15.696051", "xcvrd_switch_standby_start": "2021-May-13 10:01:15.690835" } or admin@sonic:$ show muxcable metrics Ethernet0 PORT EVENT TIME --------- ---------------------------- --------------------------- Ethernet0 linkmgrd_switch_active_start 2021-May-13 10:00:21.420898 Ethernet0 linkmgrd_switch_standby_end 2021-May-13 10:01:15.696728 Ethernet0 linkmgrd_switch_unknown_end 2021-May-13 10:00:26.123319 Ethernet0 xcvrd_switch_standby_end 2021-May-13 10:01:15.696051 Ethernet0 xcvrd_switch_standby_start 2021-May-13 10:01:15.690835 How I did it added changes in show/muxcable.py by reading and publishing the state DB contents for the corresponding table Signed-off-by: vaibhav-dahiya <vdahiya@microsoft.com>
1 parent feeab29 commit 5d1ad05

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed

show/muxcable.py

+60
Original file line numberDiff line numberDiff line change
@@ -925,3 +925,63 @@ def version(port):
925925
sys.exit(CONFIG_FAIL)
926926
else:
927927
click.echo("there is not a valid asic table for this asic_index".format(asic_index))
928+
929+
@muxcable.command()
930+
@click.argument('port', metavar='<port_name>', required=True, default=None)
931+
@click.option('--json', 'json_output', required=False, is_flag=True, type=click.BOOL, help="display the output in json format")
932+
def metrics(port, json_output):
933+
"""Show muxcable metrics <port>"""
934+
935+
metrics_table_keys = {}
936+
per_npu_statedb = {}
937+
metrics_dict = {}
938+
939+
# Getting all front asic namespace and correspding config and state DB connector
940+
941+
namespaces = multi_asic.get_front_end_namespaces()
942+
for namespace in namespaces:
943+
asic_id = multi_asic.get_asic_index_from_namespace(namespace)
944+
# replace these with correct macros
945+
per_npu_statedb[asic_id] = swsscommon.SonicV2Connector(use_unix_socket_path=True, namespace=namespace)
946+
per_npu_statedb[asic_id].connect(per_npu_statedb[asic_id].STATE_DB)
947+
948+
metrics_table_keys[asic_id] = per_npu_statedb[asic_id].keys(
949+
per_npu_statedb[asic_id].STATE_DB, 'MUX_METRICS_TABLE|*')
950+
951+
if port is not None:
952+
953+
logical_port_list = platform_sfputil_helper.get_logical_list()
954+
955+
if port not in logical_port_list:
956+
click.echo(("ERR: Not a valid logical port for muxcable firmware {}".format(port)))
957+
sys.exit(CONFIG_FAIL)
958+
959+
asic_index = None
960+
if platform_sfputil is not None:
961+
asic_index = platform_sfputil_helper.get_asic_id_for_logical_port(port)
962+
if asic_index is None:
963+
# TODO this import is only for unit test purposes, and should be removed once sonic_platform_base
964+
# is fully mocked
965+
import sonic_platform_base.sonic_sfp.sfputilhelper
966+
asic_index = sonic_platform_base.sonic_sfp.sfputilhelper.SfpUtilHelper().get_asic_id_for_logical_port(port)
967+
if asic_index is None:
968+
click.echo("Got invalid asic index for port {}, cant retreive mux status".format(port))
969+
970+
971+
metrics_dict[asic_index] = per_npu_statedb[asic_index].get_all(
972+
per_npu_statedb[asic_index].STATE_DB, 'MUX_METRICS_TABLE|{}'.format(port))
973+
974+
if json_output:
975+
click.echo("{}".format(json.dumps(metrics_dict[asic_index], indent=4)))
976+
else:
977+
print_data = []
978+
for key, val in metrics_dict[asic_index].items():
979+
print_port_data = []
980+
print_port_data.append(port)
981+
print_port_data.append(key)
982+
print_port_data.append(val)
983+
print_data.append(print_port_data)
984+
985+
headers = ['PORT', 'EVENT', 'TIME']
986+
987+
click.echo(tabulate(print_data, headers=headers))

tests/mock_tables/state_db.json

+6
Original file line numberDiff line numberDiff line change
@@ -708,5 +708,11 @@
708708
"non_fatal|Undefined": "0",
709709
"non_fatal|UnsupReq": "0",
710710
"non_fatal|UnxCmplt": "0"
711+
},
712+
"MUX_METRICS_TABLE|Ethernet0": {
713+
"linkmgrd_switch_active_start": "2021-May-13 10:00:21.420898",
714+
"linkmgrd_switch_standby_end": "2021-May-13 10:01:15.696728",
715+
"xcvrd_switch_standby_end": "2021-May-13 10:01:15.696051",
716+
"xcvrd_switch_standby_start": "2021-May-13 10:01:15.690835"
711717
}
712718
}

tests/muxcable_test.py

+43
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,23 @@
189189
}
190190
"""
191191

192+
show_muxcable_metrics_expected_output = """\
193+
PORT EVENT TIME
194+
--------- ---------------------------- ---------------------------
195+
Ethernet0 linkmgrd_switch_active_start 2021-May-13 10:00:21.420898
196+
Ethernet0 linkmgrd_switch_standby_end 2021-May-13 10:01:15.696728
197+
Ethernet0 xcvrd_switch_standby_end 2021-May-13 10:01:15.696051
198+
Ethernet0 xcvrd_switch_standby_start 2021-May-13 10:01:15.690835
199+
"""
200+
201+
show_muxcable_metrics_expected_output_json = """\
202+
{
203+
"linkmgrd_switch_active_start": "2021-May-13 10:00:21.420898",
204+
"linkmgrd_switch_standby_end": "2021-May-13 10:01:15.696728",
205+
"xcvrd_switch_standby_end": "2021-May-13 10:01:15.696051",
206+
"xcvrd_switch_standby_start": "2021-May-13 10:01:15.690835"
207+
}
208+
"""
192209

193210
class TestMuxcable(object):
194211
@classmethod
@@ -780,6 +797,32 @@ def test_config_muxcable_rollback_firmware(self):
780797
"Ethernet0"], obj=db)
781798
assert result.exit_code == 0
782799

800+
@mock.patch('utilities_common.platform_sfputil_helper.get_logical_list', mock.MagicMock(return_value=["Ethernet0", "Ethernet12"]))
801+
@mock.patch('utilities_common.platform_sfputil_helper.get_asic_id_for_logical_port', mock.MagicMock(return_value=0))
802+
@mock.patch('show.muxcable.platform_sfputil', mock.MagicMock(return_value={0: ["Ethernet12", "Ethernet0"]}))
803+
@mock.patch('utilities_common.platform_sfputil_helper.logical_port_name_to_physical_port_list', mock.MagicMock(return_value=[0]))
804+
def test_show_muxcable_metrics_port(self):
805+
runner = CliRunner()
806+
db = Db()
807+
808+
result = runner.invoke(show.cli.commands["muxcable"].commands["metrics"],
809+
["Ethernet0"], obj=db)
810+
assert result.exit_code == 0
811+
assert result.output == show_muxcable_metrics_expected_output
812+
813+
@mock.patch('utilities_common.platform_sfputil_helper.get_logical_list', mock.MagicMock(return_value=["Ethernet0", "Ethernet12"]))
814+
@mock.patch('utilities_common.platform_sfputil_helper.get_asic_id_for_logical_port', mock.MagicMock(return_value=0))
815+
@mock.patch('show.muxcable.platform_sfputil', mock.MagicMock(return_value={0: ["Ethernet12", "Ethernet0"]}))
816+
@mock.patch('utilities_common.platform_sfputil_helper.logical_port_name_to_physical_port_list', mock.MagicMock(return_value=[0]))
817+
def test_show_muxcable_metrics_port(self):
818+
runner = CliRunner()
819+
db = Db()
820+
821+
result = runner.invoke(show.cli.commands["muxcable"].commands["metrics"],
822+
["Ethernet0", "--json"], obj=db)
823+
assert result.exit_code == 0
824+
assert result.output == show_muxcable_metrics_expected_output_json
825+
783826
@classmethod
784827
def teardown_class(cls):
785828
os.environ['UTILITIES_UNIT_TESTING'] = "0"

0 commit comments

Comments
 (0)