Skip to content

Commit 1eacd05

Browse files
authored
[sairedis] Client/Server add support for SAI stats api (sonic-net#855)
1 parent 59fedfa commit 1eacd05

File tree

3 files changed

+163
-6
lines changed

3 files changed

+163
-6
lines changed

lib/inc/ServerSai.h

+8
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,14 @@ namespace sairedis
337337
_In_ const sai_object_id_t* object_ids,
338338
_In_ const sai_status_t* statuses);
339339

340+
// STATS API
341+
342+
sai_status_t processGetStatsEvent(
343+
_In_ const swss::KeyOpFieldsValuesTuple &kco);
344+
345+
sai_status_t processClearStatsEvent(
346+
_In_ const swss::KeyOpFieldsValuesTuple &kco);
347+
340348
// NON QUAD API
341349

342350
sai_status_t processFdbFlush(

lib/src/ServerSai.cpp

+102-6
Original file line numberDiff line numberDiff line change
@@ -691,12 +691,11 @@ sai_status_t ServerSai::processSingleEvent(
691691
if (op == REDIS_ASIC_STATE_COMMAND_BULK_SET)
692692
return processBulkQuadEvent(SAI_COMMON_API_BULK_SET, kco);
693693

694-
// TODO implement
695-
// if (op == REDIS_ASIC_STATE_COMMAND_GET_STATS)
696-
// return processGetStatsEvent(kco);
697-
//
698-
// if (op == REDIS_ASIC_STATE_COMMAND_CLEAR_STATS)
699-
// return processClearStatsEvent(kco);
694+
if (op == REDIS_ASIC_STATE_COMMAND_GET_STATS)
695+
return processGetStatsEvent(kco);
696+
697+
if (op == REDIS_ASIC_STATE_COMMAND_CLEAR_STATS)
698+
return processClearStatsEvent(kco);
700699

701700
if (op == REDIS_ASIC_STATE_COMMAND_FLUSH)
702701
return processFdbFlush(kco);
@@ -1737,3 +1736,100 @@ sai_status_t ServerSai::processFdbFlush(
17371736

17381737
return status;
17391738
}
1739+
1740+
sai_status_t ServerSai::processClearStatsEvent(
1741+
_In_ const swss::KeyOpFieldsValuesTuple &kco)
1742+
{
1743+
SWSS_LOG_ENTER();
1744+
1745+
const std::string &key = kfvKey(kco);
1746+
1747+
sai_object_meta_key_t metaKey;
1748+
sai_deserialize_object_meta_key(key, metaKey);
1749+
1750+
auto info = sai_metadata_get_object_type_info(metaKey.objecttype);
1751+
1752+
if (info->isnonobjectid)
1753+
{
1754+
SWSS_LOG_THROW("non object id not supported on clear stats: %s, FIXME", key.c_str());
1755+
}
1756+
1757+
std::vector<sai_stat_id_t> counter_ids;
1758+
1759+
for (auto&v: kfvFieldsValues(kco))
1760+
{
1761+
int32_t val;
1762+
sai_deserialize_enum(fvField(v), info->statenum, val);
1763+
1764+
counter_ids.push_back(val);
1765+
}
1766+
1767+
auto status = m_sai->clearStats(
1768+
metaKey.objecttype,
1769+
metaKey.objectkey.key.object_id,
1770+
(uint32_t)counter_ids.size(),
1771+
counter_ids.data());
1772+
1773+
m_selectableChannel->set(sai_serialize_status(status), {}, REDIS_ASIC_STATE_COMMAND_GETRESPONSE);
1774+
1775+
return status;
1776+
}
1777+
1778+
sai_status_t ServerSai::processGetStatsEvent(
1779+
_In_ const swss::KeyOpFieldsValuesTuple &kco)
1780+
{
1781+
SWSS_LOG_ENTER();
1782+
1783+
const std::string &key = kfvKey(kco);
1784+
1785+
sai_object_meta_key_t metaKey;
1786+
sai_deserialize_object_meta_key(key, metaKey);
1787+
1788+
// TODO get stats on created object in init view mode could fail
1789+
1790+
auto info = sai_metadata_get_object_type_info(metaKey.objecttype);
1791+
1792+
if (info->isnonobjectid)
1793+
{
1794+
SWSS_LOG_THROW("non object id not supported on clear stats: %s, FIXME", key.c_str());
1795+
}
1796+
1797+
std::vector<sai_stat_id_t> counter_ids;
1798+
1799+
for (auto&v: kfvFieldsValues(kco))
1800+
{
1801+
int32_t val;
1802+
sai_deserialize_enum(fvField(v), info->statenum, val);
1803+
1804+
counter_ids.push_back(val);
1805+
}
1806+
1807+
std::vector<uint64_t> result(counter_ids.size());
1808+
1809+
auto status = m_sai->getStats(
1810+
metaKey.objecttype,
1811+
metaKey.objectkey.key.object_id,
1812+
(uint32_t)counter_ids.size(),
1813+
counter_ids.data(),
1814+
result.data());
1815+
1816+
std::vector<swss::FieldValueTuple> entry;
1817+
1818+
if (status != SAI_STATUS_SUCCESS)
1819+
{
1820+
SWSS_LOG_ERROR("Failed to get stats");
1821+
}
1822+
else
1823+
{
1824+
const auto& values = kfvFieldsValues(kco);
1825+
1826+
for (size_t i = 0; i < values.size(); i++)
1827+
{
1828+
entry.emplace_back(fvField(values[i]), std::to_string(result[i]));
1829+
}
1830+
}
1831+
1832+
m_selectableChannel->set(sai_serialize_status(status), entry, REDIS_ASIC_STATE_COMMAND_GETRESPONSE);
1833+
1834+
return status;
1835+
}

tests/testclient.cpp

+53
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class TestClient
2727

2828
void test_fdb_flush();
2929

30+
void test_stats();
31+
3032
private:
3133

3234
int profileGetNextValue(
@@ -457,6 +459,55 @@ void TestClient::test_fdb_flush()
457459
ASSERT_SUCCESS(sai_api_uninitialize());
458460
}
459461

462+
void TestClient::test_stats()
463+
{
464+
SWSS_LOG_ENTER();
465+
466+
m_profileMap.clear();
467+
468+
m_profileMap[SAI_REDIS_KEY_ENABLE_CLIENT] = "true"; // act as a client
469+
470+
m_profileIter = m_profileMap.begin();
471+
472+
m_smt.profileGetValue = std::bind(&TestClient::profileGetValue, this, _1, _2);
473+
m_smt.profileGetNextValue = std::bind(&TestClient::profileGetNextValue, this, _1, _2, _3);
474+
475+
m_test_services = m_smt.getServiceMethodTable();
476+
477+
ASSERT_SUCCESS(sai_api_initialize(0, &m_test_services));
478+
479+
sai_switch_api_t* switch_api;
480+
481+
ASSERT_SUCCESS(sai_api_query(SAI_API_SWITCH, (void**)&switch_api));
482+
483+
sai_attribute_t attr;
484+
485+
// connect to existing switch
486+
attr.id = SAI_SWITCH_ATTR_INIT_SWITCH;
487+
attr.value.booldata = false;
488+
489+
sai_object_id_t switch_id = SAI_NULL_OBJECT_ID;
490+
491+
ASSERT_SUCCESS(switch_api->create_switch(&switch_id, 1, &attr));
492+
493+
ASSERT_TRUE(switch_id != SAI_NULL_OBJECT_ID);
494+
495+
SWSS_LOG_NOTICE("switchId: %s", sai_serialize_object_id(switch_id).c_str());
496+
497+
uint64_t counters[1];
498+
sai_stat_id_t counter_ids[1] = { SAI_SWITCH_STAT_ECC_DROP };
499+
500+
SWSS_LOG_NOTICE(" * get_switch_stats");
501+
502+
ASSERT_SUCCESS(switch_api->get_switch_stats(switch_id, 1, counter_ids, counters));
503+
504+
SWSS_LOG_NOTICE(" * clear_switch_stats");
505+
506+
ASSERT_SUCCESS(switch_api->clear_switch_stats(switch_id, 1, counter_ids));
507+
508+
ASSERT_SUCCESS(sai_api_uninitialize());
509+
}
510+
460511
int main()
461512
{
462513
swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_DEBUG);
@@ -475,5 +526,7 @@ int main()
475526

476527
tc.test_fdb_flush();
477528

529+
tc.test_stats();
530+
478531
return EXIT_SUCCESS;
479532
}

0 commit comments

Comments
 (0)