@@ -37,6 +37,26 @@ DebugCounterOrch::DebugCounterOrch(DBConnector *db, const vector<string>& table_
3737 publishDropCounterCapabilities ();
3838
3939 gPortsOrch ->attach (this );
40+
41+ // Add drop monitor lua script
42+ string dropMonitorPluginName = " drop_monitor.lua" ;
43+ string dropMonitorSha;
44+
45+ try
46+ {
47+ string dropMonitorLuaScript = swss::loadLuaScript (dropMonitorPluginName);
48+ dropMonitorSha = swss::loadRedisScript (m_countersDb.get (), dropMonitorLuaScript);
49+ }
50+ catch (const runtime_error &e)
51+ {
52+ SWSS_LOG_ERROR (" Drop monitor flex counter group was not set successfully: %s" , e.what ());
53+ }
54+
55+ setFlexCounterGroupParameter (DEBUG_DROP_MONITOR_FLEX_COUNTER_GROUP,
56+ DEBUG_DROP_MONITOR_FLEX_COUNTER_POLLING_INTERVAL_MS,
57+ STATS_MODE_READ,
58+ PORT_PLUGIN_FIELD,
59+ dropMonitorSha);
4060}
4161
4262DebugCounterOrch::~DebugCounterOrch (void )
@@ -193,6 +213,70 @@ void DebugCounterOrch::doTask(Consumer& consumer)
193213 SWSS_LOG_ERROR (" Unknown operation type %s\n " , op.c_str ());
194214 }
195215 }
216+ else if (table_name == " DEBUG_DROP_MONITOR" )
217+ {
218+ if (op == SET_COMMAND)
219+ {
220+ if (key == " CONFIG" )
221+ {
222+ for (const auto & value : values)
223+ {
224+ string config_name = value.first ;
225+ string config_value = value.second ;
226+
227+ // Check the status of the drop counter monitor feature
228+ try
229+ {
230+ if (config_name == " status" )
231+ {
232+ if (config_value == " enabled" )
233+ {
234+ debug_monitor_enabled = true ;
235+ string monitored_debug_counter_stat = counterIdsToStr (portDebugMonitorStatIds);
236+ SWSS_LOG_DEBUG (" Enabling debug drop monitor: %s" , monitored_debug_counter_stat.c_str ());
237+ setFlexCounterGroupOperation (DEBUG_DROP_MONITOR_FLEX_COUNTER_GROUP, " enable" );
238+ for (auto const &curr : gPortsOrch ->getAllPorts ())
239+ {
240+ string key = string (DEBUG_DROP_MONITOR_FLEX_COUNTER_GROUP) + " :" + sai_serialize_object_id (curr.second .m_port_id );
241+ startFlexCounterPolling (gSwitchId , key, monitored_debug_counter_stat, PORT_COUNTER_ID_LIST);
242+ }
243+ }
244+ else if (config_value == " disabled" )
245+ {
246+ debug_monitor_enabled = false ;
247+ SWSS_LOG_DEBUG (" Disabling debug drop monitor" );
248+ setFlexCounterGroupOperation (DEBUG_DROP_MONITOR_FLEX_COUNTER_GROUP, " disable" );
249+ for (auto const &curr : gPortsOrch ->getAllPorts ())
250+ {
251+ string key = string (DEBUG_DROP_MONITOR_FLEX_COUNTER_GROUP) + " :" + sai_serialize_object_id (curr.second .m_port_id );
252+ stopFlexCounterPolling (gSwitchId , key);
253+ }
254+ }
255+ else
256+ {
257+ SWSS_LOG_ERROR (" The status of drop counter monitor was not recognized: %s. Accepted values are enabled/disabled." , config_value.c_str ());
258+ task_status = task_process_status::task_failed;
259+ }
260+ }
261+ else
262+ {
263+ SWSS_LOG_ERROR (" Config for drop counter monitor was not recognized: %s. Accepted values are status." , config_value.c_str ());
264+ task_status = task_process_status::task_failed;
265+ }
266+ }
267+ catch (const std::runtime_error& e)
268+ {
269+ SWSS_LOG_ERROR (" Encountered an error when updating DEBUG_DROP_MONITOR. config_name: %s, config_value: %s" , config_name.c_str (), config_value.c_str ());
270+ task_status = task_process_status::task_failed;
271+ }
272+ }
273+ }
274+ }
275+ else
276+ {
277+ SWSS_LOG_ERROR (" Unknown operation type %s\n " , op.c_str ());
278+ }
279+ }
196280 else
197281 {
198282 SWSS_LOG_ERROR (" Received update from unknown table '%s'" , table_name.c_str ());
@@ -336,7 +420,7 @@ task_process_status DebugCounterOrch::uninstallDebugCounter(const string& counte
336420 string counter_type = counter->getCounterType ();
337421 string counter_stat = counter->getDebugCounterSAIStat ();
338422
339- uninstallDebugFlexCounters (counter_type, counter_stat);
423+ uninstallDebugFlexCounters (counter_type, counter_stat, SAI_NULL_OBJECT_ID, counter_name );
340424
341425 if (counter_type == PORT_INGRESS_DROPS || counter_type == PORT_EGRESS_DROPS)
342426 {
@@ -531,6 +615,11 @@ void DebugCounterOrch::installDebugFlexCounters(const string& counter_type,
531615 SWSS_LOG_ENTER ();
532616 CounterType flex_counter_type = getFlexCounterType (counter_type);
533617
618+ // Track the new counter_stat in debug drop monitor
619+ portDebugMonitorStatIds.insert (counter_stat);
620+ string monitored_debug_counter_stat = counterIdsToStr (portDebugMonitorStatIds);
621+ SWSS_LOG_DEBUG (" Added %s to: %s" , counter_stat.c_str (), monitored_debug_counter_stat.c_str ());
622+
534623 if (flex_counter_type == CounterType::SWITCH_DEBUG)
535624 {
536625 flex_counter_manager.addFlexCounterStat (gSwitchId , flex_counter_type, counter_stat);
@@ -556,17 +645,34 @@ void DebugCounterOrch::installDebugFlexCounters(const string& counter_type,
556645 curr.second .m_port_id ,
557646 flex_counter_type,
558647 counter_stat);
648+
649+ if (debug_monitor_enabled)
650+ {
651+ string key = string (DEBUG_DROP_MONITOR_FLEX_COUNTER_GROUP) + " :" + sai_serialize_object_id (curr.second .m_port_id );
652+ stopFlexCounterPolling (gSwitchId , key);
653+ startFlexCounterPolling (gSwitchId , key, monitored_debug_counter_stat, PORT_COUNTER_ID_LIST);
654+ }
559655 }
560656 }
561657}
562658
563659void DebugCounterOrch::uninstallDebugFlexCounters (const string& counter_type,
564660 const string& counter_stat,
565- sai_object_id_t port_id)
661+ sai_object_id_t port_id,
662+ const string& counter_name)
566663{
567664 SWSS_LOG_ENTER ();
568665 CounterType flex_counter_type = getFlexCounterType (counter_type);
569666
667+ // Remove the counter_stat from being tracked in debug drop monitor
668+ auto counter_stat_iter = portDebugMonitorStatIds.find (counter_stat);
669+ portDebugMonitorStatIds.erase (counter_stat_iter);
670+ string monitored_debug_counter_stat = counterIdsToStr (portDebugMonitorStatIds);
671+ SWSS_LOG_DEBUG (" Removed %s from: %s" , counter_stat.c_str (), monitored_debug_counter_stat.c_str ());
672+
673+ // Make a vector of keys to delete from COUNTERS_DB, these keys are used by drop counter monitor
674+ std::vector<std::string> debug_drop_monitor_stats_fields;
675+
570676 if (flex_counter_type == CounterType::SWITCH_DEBUG)
571677 {
572678 flex_counter_manager.removeFlexCounterStat (gSwitchId , flex_counter_type, counter_stat);
@@ -575,6 +681,10 @@ void DebugCounterOrch::uninstallDebugFlexCounters(const string& counter_type,
575681 {
576682 for (auto const &curr : gPortsOrch ->getAllPorts ())
577683 {
684+ // Remove debug counter stat from being tracked by drop counter monitor
685+ string key = string (DEBUG_COUNTER_FLEX_COUNTER_GROUP) + " :" + sai_serialize_object_id (curr.second .m_port_id );
686+ stopFlexCounterPolling (gSwitchId , key);
687+
578688 if (port_id != SAI_NULL_OBJECT_ID)
579689 {
580690 if (curr.second .m_port_id != port_id)
@@ -592,8 +702,20 @@ void DebugCounterOrch::uninstallDebugFlexCounters(const string& counter_type,
592702 curr.second .m_port_id ,
593703 flex_counter_type,
594704 counter_stat);
705+
706+ debug_drop_monitor_stats_fields.push_back (" DEBUG_DROP_MONITOR_STATS|" + counter_name + " |" + curr.first );
707+
708+ if (debug_monitor_enabled)
709+ {
710+ string key = string (DEBUG_DROP_MONITOR_FLEX_COUNTER_GROUP) + " :" + sai_serialize_object_id (curr.second .m_port_id );
711+ stopFlexCounterPolling (gSwitchId , key);
712+ startFlexCounterPolling (gSwitchId , key, monitored_debug_counter_stat, PORT_COUNTER_ID_LIST);
713+ }
595714 }
596715 }
716+
717+ // Delete DEBUG_DROP_MONITOR_STATS for this debug counter
718+ m_countersDb->del (debug_drop_monitor_stats_fields);
597719}
598720
599721// Debug Counter Initialization Helper Functions START HERE ----------------------------------------
@@ -657,6 +779,11 @@ void DebugCounterOrch::createDropCounter(const string& counter_name, const strin
657779 }
658780}
659781
782+ bool DebugCounterOrch::getDebugMonitorStatus ()
783+ {
784+ return debug_monitor_enabled;
785+ }
786+
660787// Debug Counter Configuration Helper Functions START HERE -----------------------------------------
661788
662789// parseDropReasonUpdate takes a key from CONFIG_DB and returns the 1) the counter name being targeted and
@@ -684,5 +811,21 @@ bool DebugCounterOrch::isDropReasonValid(const string& drop_reason) const
684811 return true ;
685812}
686813
814+ string DebugCounterOrch::counterIdsToStr (const std::unordered_set<string>& ids) const
815+ {
816+ SWSS_LOG_ENTER ();
817+ string str;
818+
819+ for (const auto & i: ids)
820+ {
821+ str += i + " ," ;
822+ }
687823
824+ // Remove trailing ','
825+ if (!str.empty ())
826+ {
827+ str.pop_back ();
828+ }
688829
830+ return str;
831+ }
0 commit comments