1 #include "otsdaq-utilities/Console/ConsoleSupervisor.h"
2 #include <xdaq/NamespaceURI.h>
3 #include "otsdaq/CgiDataUtilities/CgiDataUtilities.h"
4 #include "otsdaq/Macros/CoutMacros.h"
5 #include "otsdaq/MessageFacility/MessageFacility.h"
6 #include "otsdaq/NetworkUtilities/ReceiverSocket.h"
7 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
24 #define USER_CONSOLE_PREF_PATH \
25 std::string(__ENV__("SERVICE_DATA_PATH")) + "/ConsolePreferences/"
26 #define USER_CONSOLE_SNAPSHOT_PATH \
27 std::string(__ENV__("SERVICE_DATA_PATH")) + "/ConsoleSnapshots/"
28 #define USERS_PREFERENCES_FILETYPE "pref"
29 #define CUSTOM_COUNT_LIST_FILENAME std::string("CustomCountList.dat")
31 #define QUIET_CFG_FILE \
32 std::string(__ENV__("USER_DATA")) + \
33 "/MessageFacilityConfigurations/" \
36 #define CONSOLE_SPECIAL_ERROR \
37 std::string("|30-Aug-2019 15:30:17 CDT|0|||Error|Console||-1||ConsoleSupervisor|") + \
38 std::string(__FILE__) + std::string("|") + std::to_string(__LINE__) + \
40 #define CONSOLE_SPECIAL_WARNING \
42 "|30-Aug-2019 15:30:17 CDT|0|||Warning|Console||-1||ConsoleSupervisor|") + \
43 std::string(__FILE__) + std::string("|") + std::to_string(__LINE__) + \
47 #define __MF_SUBJECT__ "Console"
49 #define CONSOLE_MISSED_NEEDLE "Console missed * packet(s)"
61 const std::string ConsoleSupervisor::ConsoleMessageStruct::LABEL_TRACE =
"TRACE";
62 const std::string ConsoleSupervisor::ConsoleMessageStruct::LABEL_TRACE_PLUS =
"TRACE+";
65 ConsoleSupervisor::ConsoleMessageStruct::fieldNames({
66 {FieldType::TIMESTAMP,
"Timestamp"},
67 {FieldType::SEQID,
"SequenceID"},
68 {FieldType::LEVEL,
"Level"},
69 {FieldType::LABEL,
"Label"},
70 {FieldType::SOURCEID,
"SourceID"},
71 {FieldType::HOSTNAME,
"Hostname"},
72 {FieldType::SOURCE,
"Source"},
73 {FieldType::FILE,
"File"},
74 {FieldType::LINE,
"Line"},
75 {FieldType::MSG,
"Msg"},
79 ConsoleSupervisor::ConsoleSupervisor(xdaq::ApplicationStub* stub)
82 , maxMessageCount_(100000)
83 , maxClientMessageRequest_(500)
85 __SUP_COUT__ <<
"Constructor started." << __E__;
90 mkdir(((std::string)USER_CONSOLE_PREF_PATH).c_str(), 0755);
91 mkdir(((std::string)USER_CONSOLE_SNAPSHOT_PATH).c_str(), 0755);
94 this, &ConsoleSupervisor::resetConsoleCounts,
"ResetConsoleCounts", XDAQ_NS_URI);
106 loadCustomCountList();
107 if(priorityCustomTriggerList_.size() ==
110 addCustomTriggeredAction(CONSOLE_MISSED_NEEDLE,
"System Message");
117 __SUP_COUT__ <<
"Constructor complete." << __E__;
122 ConsoleSupervisor::~ConsoleSupervisor(
void) { destroy(); }
124 void ConsoleSupervisor::init(
void)
129 ConsoleSupervisor::messageFacilityReceiverWorkLoop(cs);
136 void ConsoleSupervisor::destroy(
void)
142 xoap::MessageReference ConsoleSupervisor::resetConsoleCounts(
143 xoap::MessageReference )
145 __COUT_INFO__ <<
"Resetting Console Error/Warn/Info counts and preparing for new "
151 std::lock_guard<std::mutex> lock(messageMutex_);
153 firstErrorMessageTime_ = 0;
154 lastErrorMessageTime_ = 0;
156 firstWarnMessageTime_ = 0;
157 lastWarnMessageTime_ = 0;
159 firstInfoMessageTime_ = 0;
160 lastInfoMessageTime_ = 0;
162 return SOAPUtilities::makeSOAPMessageReference(
"Done");
172 __COUT__ <<
"Starting workloop based on config file: " << QUIET_CFG_FILE << __E__;
174 std::string configFile = QUIET_CFG_FILE;
175 FILE* fp = fopen(configFile.c_str(),
"r");
178 __SS__ <<
"File with port info could not be loaded: " << QUIET_CFG_FILE << __E__;
179 __COUT__ <<
"\n" << ss.str();
186 sscanf(tmp,
"%*s %d", &myport);
190 sscanf(tmp,
"%*s %s", myip);
196 rsock.initialize(0x1400000 );
202 std::lock_guard<std::mutex> lock(cs->messageMutex_);
208 __SS__ <<
"FATAL Console error. Could not initialize socket on port "
210 <<
". Perhaps the port is already in use? Check for multiple stale "
211 "instances of otsdaq processes, or notify admins."
212 <<
" Multiple instances of otsdaq on the same node should be "
213 "possible, but port numbers must be unique."
219 __SS__ <<
"FATAL Console error. Could not initialize socket on port " << myport
220 <<
". Perhaps it is already in use? Exiting Console receive loop."
222 __COUT__ << ss.str();
224 cs->messages_.emplace_back(CONSOLE_SPECIAL_ERROR + ss.str(),
226 cs->priorityCustomTriggerList_);
228 cs->messages_.back().setTime(time(0));
229 if(cs->messages_.size() > cs->maxMessageCount_)
231 cs->messages_.erase(cs->messages_.begin());
239 int heartbeatCount = 0;
240 int selfGeneratedMessageCount = 0;
242 std::map<unsigned int, unsigned int> sourceLastSequenceID;
245 long long newSourceId;
246 uint32_t newSequenceId;
250 __COUT__ <<
"DEBUG messages look like this." << __E__;
259 buffer, 1 , 0 ,
false ) !=
263 if(buffer.size() == 1)
271 __COUT__ <<
"Console has first message." << __E__;
275 __COUT_INFO__ <<
"INFO messages look like this." << __E__;
276 __COUT_WARN__ <<
"WARNING messages look like this." << __E__;
277 __COUT_ERR__ <<
"ERROR messages look like this." << __E__;
289 if(selfGeneratedMessageCount)
290 --selfGeneratedMessageCount;
298 std::lock_guard<std::mutex> lock(cs->messageMutex_);
302 while(c < buffer.size())
306 cs->messages_.emplace_back(&(buffer.c_str()[c]),
308 cs->priorityCustomTriggerList_);
309 if(cs->messages_.back().hasCustomTriggerMatchAction())
310 cs->customTriggerActionQueue_.push(
311 cs->messages_.back().getCustomTriggerMatch());
314 if(cs->messages_.back().getLevel() ==
"Error")
316 if(cs->errorCount_ == 0)
318 cs->firstErrorMessageTime_ = time(0);
319 cs->firstErrorMessage_ = cs->messages_.back().getMsg();
322 cs->lastErrorMessageTime_ = time(0);
324 cs->lastErrorMessage_ = cs->messages_.back().getMsg();
326 else if(cs->messages_.back().getLevel() ==
"Warning")
328 if(cs->warnCount_ == 0)
330 cs->firstWarnMessageTime_ = time(0);
331 cs->firstWarnMessage_ = cs->messages_.back().getMsg();
333 cs->lastWarnMessageTime_ = time(0);
335 cs->lastWarnMessage_ = cs->messages_.back().getMsg();
337 else if(cs->messages_.back().getLevel() ==
"Info")
339 if(cs->infoCount_ == 0)
341 cs->firstInfoMessageTime_ = time(0);
342 cs->firstInfoMessage_ = cs->messages_.back().getMsg();
344 cs->lastInfoMessageTime_ = time(0);
346 cs->lastInfoMessage_ = cs->messages_.back().getMsg();
350 newSourceId = cs->messages_.back().getSourceIDAsNumber();
351 newSequenceId = cs->messages_.back().getSequenceIDAsNumber();
358 (newSourceId != -1 &&
359 sourceLastSequenceID.find(newSourceId) !=
362 ((newSequenceId == 0 && sourceLastSequenceID[newSourceId] !=
365 sourceLastSequenceID[newSourceId] + 1))
369 std::stringstream missedSs;
370 missedSs <<
"Console missed "
371 << (newSequenceId - 1) -
372 (sourceLastSequenceID[newSourceId] + 1) + 1
373 <<
" packet(s) from " << cs->messages_.back().getSource()
375 __SS__ << missedSs.str();
376 std::cout << ss.str();
379 cs->messages_.emplace_back(CONSOLE_SPECIAL_WARNING + missedSs.str(),
381 cs->priorityCustomTriggerList_);
383 cs->messages_.back().setTime(time(0));
385 if(cs->priorityCustomTriggerList_.size())
387 cs->customTriggerActionQueue_.push(
388 cs->priorityCustomTriggerList_
390 cs->priorityCustomTriggerList_[0]
392 cs->customTriggerActionQueue_.back().triggeredMessageCountIndex =
393 cs->messages_.back().getCount();
394 cs->messages_.back().setCustomTriggerMatch(
395 cs->customTriggerActionQueue_.back());
400 sourceLastSequenceID[newSourceId] = newSequenceId;
402 while(cs->messages_.size() > 0 &&
403 cs->messages_.size() > cs->maxMessageCount_)
405 cs->messages_.erase(cs->messages_.begin());
408 c += strlen(&(buffer.c_str()[c])) + 1;
422 (heartbeatCount < 60 * 5 &&
423 heartbeatCount % 60 == 59))
425 ++selfGeneratedMessageCount;
426 __COUT__ <<
"Console is alive and waiting... (if no messages, next "
427 "heartbeat is in two minutes)"
430 else if(heartbeatCount % (60 * 30) == 59)
432 ++selfGeneratedMessageCount;
433 __COUT__ <<
"Console is alive and waiting a long time... (if no "
434 "messages, next heartbeat is in one hour)"
445 if(i == 120 || selfGeneratedMessageCount == 5)
448 __COUTV__(selfGeneratedMessageCount);
449 __COUT__ <<
"No messages received at Console Supervisor. Exiting Console "
450 "messageFacilityReceiverWorkLoop"
455 if(cs->customTriggerActionQueue_.size() && !cs->customTriggerActionThreadExists_)
457 cs->customTriggerActionThreadExists_ =
true;
461 ConsoleSupervisor::customTriggerActionThread(c);
470 catch(
const std::runtime_error& e)
472 __COUT_ERR__ <<
"Error caught at Console Supervisor thread: " << e.what() << __E__;
476 __COUT_ERR__ <<
"Unknown error caught at Console Supervisor thread." << __E__;
485 __COUT__ <<
"Starting customTriggerActionThread" << __E__;
486 CustomTriggeredAction_t triggeredAction;
492 std::lock_guard<std::mutex> lock(cs->messageMutex_);
493 if(cs->customTriggerActionQueue_.size())
495 triggeredAction = cs->customTriggerActionQueue_.front();
496 cs->customTriggerActionQueue_.pop();
500 if(triggeredAction.action.size())
502 __COUTS__(2) <<
"Handling action '" << triggeredAction.action
503 <<
"' on custom count search string: "
507 cs->doTriggeredAction(triggeredAction);
510 triggeredAction.action =
"";
511 triggeredAction.triggeredMessageCountIndex =
518 catch(
const std::runtime_error& e)
520 __COUT_ERR__ <<
"Error caught at Console Supervisor Action thread: " << e.what()
525 __COUT_ERR__ <<
"Unknown error caught at Console Supervisor Action thread." << __E__;
529 void ConsoleSupervisor::doTriggeredAction(
const CustomTriggeredAction_t& triggeredAction)
531 __SUP_COUT_INFO__ <<
"Launching Triggered Action '" << triggeredAction.action
532 <<
"' fired on custom count search string: "
549 __SUP_SS__ <<
"Unrecognized triggered action '" << triggeredAction.action
550 <<
",' valid actions are "
556 if(triggeredAction.action !=
"Count Only")
557 theRemoteWebUsers_.sendSystemMessage(
559 "In the Console Supervisor, a custom count fired the action '" +
560 triggeredAction.action +
"' on the search string '" +
564 if(triggeredAction.action ==
"Halt")
569 "Console-triggered FSM Halt", 0, 0);
573 theRemoteWebUsers_.sendSystemMessage(
575 "FSM Halt from Console Supervisor Triggered Action has failed!");
577 __SUP_COUTV__(
"FSM Halt triggered from console");
579 else if(triggeredAction.action ==
"Pause")
584 "Console-triggered FSM Pause", 1, 0);
588 theRemoteWebUsers_.sendSystemMessage(
590 "FSM Pause from Console Supervisor Triggered Action has failed!");
592 __SUP_COUTV__(
"FSM Pause triggered from console");
594 else if(triggeredAction.action ==
"Stop")
599 "Console-triggered FSM Stop", 0, 1);
601 catch(
const std::exception& e)
603 theRemoteWebUsers_.sendSystemMessage(
605 "FSM Stop from Console Supervisor Triggered Action has failed!");
607 __SUP_COUTV__(
"FSM Stop triggered from console");
609 else if(triggeredAction.action ==
"Run Script")
611 std::string triggerScriptPath =
"";
612 std::string scriptResult =
"";
615 triggerScriptPath = __ENV__(
"OTS_CUSTOM_TRIGGER_SCRIPT");
616 triggerScriptPath =
"source " + triggerScriptPath;
618 __COUT_INFO__ <<
"The Script " << triggerScriptPath
619 <<
" Was launched, here is the result " << scriptResult;
623 __SS__ <<
"Trigger script path not defined! Please use environment variable "
624 "'OTS_CUSTOM_TRIGGER_SCRIPT' or contact admins."
634 void ConsoleSupervisor::addCustomTriggeredAction(
const std::string& triggerNeedle,
635 const std::string& triggerAction,
637 uint32_t triggerOnCount,
641 __SUP_COUTV__(
"Adding custom triggered action");
642 __SUP_COUTV__(triggerNeedle);
643 __SUP_COUTV__(triggerAction);
644 __SUP_COUTV__(priority);
645 __SUP_COUTV__(triggerOnCount);
646 __SUP_COUTV__(doLoop);
647 __SUP_COUTV__(isArmed);
649 bool allAsterisks =
true;
650 for(
const auto& c : triggerNeedle)
653 allAsterisks =
false;
658 __SUP_SS__ <<
"Illegal empty Search String value for the new Custom Count and "
659 "Action! Please enter a valid Search String (* wildcards are "
660 "allowed, e.g. \"value = * seconds\")."
666 uint32_t currentPriority = -1;
667 for(
const auto& customTrigger : priorityCustomTriggerList_)
673 __SUP_SS__ <<
"Failure! Can not add Custom Count Search String that already "
676 <<
"' already existing at priority = " << currentPriority << __E__;
681 if(priority >= priorityCustomTriggerList_.size())
682 priority = priorityCustomTriggerList_.size();
683 if(priority == 0 && triggerNeedle != CONSOLE_MISSED_NEEDLE)
685 __SUP_SS__ <<
"Illegal priority position of '" << priority
686 <<
"' requested. Please enter a priority value greater than 0. "
687 "Position 0 is reserved for identifying missing messages at the "
688 "Console Supervisor. Note: the action for missing messages, at "
689 "priority 0, may be customized by the user."
693 __SUP_COUTV__(priority);
706 __SUP_SS__ <<
"Unrecognized triggered action '" << triggerAction
707 <<
",' valid actions are "
713 priorityCustomTriggerList_.insert(priorityCustomTriggerList_.begin() + priority,
714 CustomTriggeredAction_t());
721 priorityCustomTriggerList_[priority].needleSubstrings,
724 priorityCustomTriggerList_[priority].action = triggerAction;
725 priorityCustomTriggerList_[priority].triggerOnCount = triggerOnCount;
726 priorityCustomTriggerList_[priority].doLoop = doLoop;
727 priorityCustomTriggerList_[priority].isArmed = isArmed;
729 __SUP_COUT__ <<
"Added custom count: '"
731 priorityCustomTriggerList_[priority].needleSubstrings,
"*")
732 <<
"' at priority: " << priority
733 <<
" triggered every: " << triggerOnCount <<
" occurrences";
735 __SUP_COUT__ <<
" and will loop.";
737 __SUP_COUT__ <<
" and will not loop.";
738 __SUP_COUT__ << __E__;
746 uint32_t ConsoleSupervisor::modifyCustomTriggeredAction(
const std::string& currentNeedle,
747 const std::string& modifyType,
748 const std::string& setNeedle,
749 const std::string& setAction,
750 uint32_t setPriority,
751 uint32_t setTriggerOnCount,
755 __SUP_COUTV__(currentNeedle);
756 __SUP_COUTV__(modifyType);
757 __SUP_COUTV__(setNeedle);
758 __SUP_COUTV__(setAction);
759 __SUP_COUTV__(setPriority);
760 __SUP_COUTV__(setTriggerOnCount);
761 __SUP_COUTV__(setDoLoop);
762 __SUP_COUTV__(setIsArmed);
765 uint32_t currentPriority = -1;
767 for(
const auto& customTrigger : priorityCustomTriggerList_)
778 __SUP_COUTV__(currentPriority);
781 __SUP_SS__ <<
"Attempt to modify Custom Count Search String failed. Could not "
782 "find specified Search String '"
783 << currentNeedle <<
"' in prioritized list." << __E__;
787 if(modifyType ==
"Deletion")
789 if(currentPriority == 0)
791 __SUP_SS__ <<
"Illegal deletion requested of priority position 0. Position 0 "
792 "is reserved for identifying missing messages at the Console "
793 "Supervisor. Note: the action of priority 0 may be customized "
794 "by the user, but it can not be deleted."
799 __SUP_COUT__ <<
"Deleting custom count: "
801 priorityCustomTriggerList_[currentPriority].needleSubstrings,
804 << priorityCustomTriggerList_[currentPriority].action
805 <<
" and priority: " << currentPriority << __E__;
806 priorityCustomTriggerList_.erase(priorityCustomTriggerList_.begin() +
811 if(modifyType ==
"Priority" || modifyType ==
"All")
813 if(setPriority >= priorityCustomTriggerList_.size())
814 setPriority = priorityCustomTriggerList_.size();
815 if(setPriority == 0 && setNeedle != CONSOLE_MISSED_NEEDLE)
817 __SUP_SS__ <<
"Illegal priority position of '" << setPriority
818 <<
"' requested. Position 0 is reserved for identifying missing "
819 "messages at the Console Supervisor. Note: the action of "
820 "priority 0 may be customized by the user."
826 setPriority = currentPriority;
828 if(modifyType ==
"Action" || modifyType ==
"All")
840 __SUP_SS__ <<
"Unrecognized custom count action '" << setAction
841 <<
",' valid actions are "
846 priorityCustomTriggerList_[currentPriority].action = setAction;
849 if(modifyType ==
"Search String" || modifyType ==
"All")
852 priorityCustomTriggerList_[currentPriority].needleSubstrings.clear();
855 priorityCustomTriggerList_[currentPriority].needleSubstrings,
860 if(modifyType ==
"Trigger on Count" || modifyType ==
"All")
863 priorityCustomTriggerList_[currentPriority].triggerOnCount = setTriggerOnCount;
865 if(modifyType ==
"Do Loop" || modifyType ==
"All")
868 priorityCustomTriggerList_[currentPriority].doLoop = setDoLoop;
870 if(modifyType ==
"Arm Trigger" || modifyType ==
"All")
873 priorityCustomTriggerList_[currentPriority].isArmed = setIsArmed;
876 if(currentPriority != setPriority)
879 priorityCustomTriggerList_.insert(
880 priorityCustomTriggerList_.begin() + setPriority,
881 priorityCustomTriggerList_[currentPriority]);
884 if(currentPriority >= setPriority)
887 priorityCustomTriggerList_.erase(priorityCustomTriggerList_.begin() +
890 if(currentPriority < setPriority)
894 __SUP_COUT__ <<
"Modified '" << modifyType <<
"' custom count: "
896 priorityCustomTriggerList_[setPriority].needleSubstrings, {
'*'})
897 <<
" now w/action: " << priorityCustomTriggerList_[setPriority].action
898 <<
" and at priority: " << setPriority << __E__;
904 void ConsoleSupervisor::loadCustomCountList()
907 __SUP_COUT__ <<
"loadCustomCountList() from "
908 << USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME << __E__;
910 FILE* fp = fopen((USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME).c_str(),
"r");
913 __SUP_COUT__ <<
"Ignoring missing Custom Count list file at path: "
914 << (USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME) << __E__;
917 priorityCustomTriggerList_.clear();
924 size_t triggerOnCount = 0;
926 bool isArmed =
false;
927 while(fgets(line, 1000, fp))
933 line[strlen(line) - 1] =
'\0';
943 priority = std::stoi(line);
945 triggerOnCount = std::stoi(line);
947 doLoop = std::stoi(line) > 0 ? true :
false;
950 isArmed = std::stoi(line) > 0 ? true :
false;
951 __SUP_COUTTV__(needle);
952 __SUP_COUTTV__(priority);
953 __SUP_COUTTV__(action);
954 __SUP_COUTTV__(triggerOnCount);
955 __SUP_COUTTV__(doLoop);
956 __SUP_COUTTV__(isArmed);
959 CONSOLE_MISSED_NEEDLE)
960 addCustomTriggeredAction(
961 CONSOLE_MISSED_NEEDLE,
"System Message", 0, 1,
false,
true);
962 addCustomTriggeredAction(
963 needle, action, priority, triggerOnCount, doLoop, isArmed);
972 void ConsoleSupervisor::saveCustomCountList()
974 __SUP_COUT__ <<
"saveCustomCountList()" << __E__;
976 FILE* fp = fopen((USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME).c_str(),
"w");
979 __SUP_SS__ <<
"Failed to create Custom Count list file at path: "
980 << (USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME) << __E__;
983 unsigned int priority = 0;
984 for(
auto& customCount : priorityCustomTriggerList_)
989 fprintf(fp,
"%s\n", customCount.action.c_str());
990 fprintf(fp,
"%d\n", priority);
991 fprintf(fp,
"%zu\n", customCount.triggerOnCount);
992 fprintf(fp,
"%s\n", customCount.doLoop ?
"1" :
"0");
993 fprintf(fp,
"%s\n", customCount.isArmed ?
"1" :
"0");
1000 void ConsoleSupervisor::defaultPage(xgi::Input* , xgi::Output* out)
1004 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
1005 "src='/WebPath/html/Console.html?urn="
1006 << getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
1014 CorePropertySupervisorBase::setSupervisorProperty(
1015 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
1024 cgicc::Cgicc& cgiIn,
1026 const WebUsers::RequestUserInfo& userInfo)
1049 if(requestType ==
"GetConsoleMsgs")
1054 if(lastUpdateCountStr ==
"")
1056 __SUP_COUT_ERR__ <<
"Invalid Parameters! lastUpdateCount="
1057 << lastUpdateCountStr << __E__;
1058 xmlOut.addTextElementToData(
"Error",
1059 "Error - Invalid parameters for GetConsoleMsgs.");
1063 size_t lastUpdateCount = std::stoull(lastUpdateCountStr);
1067 insertMessageRefresh(&xmlOut, lastUpdateCount);
1069 else if(requestType ==
"PrependHistoricMessages")
1071 size_t earliestOnhandMessageCount =
1072 CgiDataUtilities::postDataAsInt(cgiIn,
"earlyCount");
1073 __SUP_COUTV__(earliestOnhandMessageCount);
1074 prependHistoricMessages(&xmlOut, earliestOnhandMessageCount);
1076 else if(requestType ==
"SaveUserPreferences")
1078 int colorIndex = CgiDataUtilities::postDataAsInt(cgiIn,
"colorIndex");
1079 int showSideBar = CgiDataUtilities::postDataAsInt(cgiIn,
"showSideBar");
1080 int noWrap = CgiDataUtilities::postDataAsInt(cgiIn,
"noWrap");
1081 int messageOnly = CgiDataUtilities::postDataAsInt(cgiIn,
"messageOnly");
1082 int hideLineNumers = CgiDataUtilities::postDataAsInt(cgiIn,
"hideLineNumers");
1091 if(userInfo.username_ ==
"")
1093 __SUP_COUT_ERR__ <<
"Invalid user found! user=" << userInfo.username_
1095 xmlOut.addTextElementToData(
"Error",
1096 "Error - InvauserInfo.username_user found.");
1100 std::string fn = (std::string)USER_CONSOLE_PREF_PATH + userInfo.username_ +
"." +
1101 (std::string)USERS_PREFERENCES_FILETYPE;
1104 FILE* fp = fopen(fn.c_str(),
"w");
1108 __THROW__(ss.str() +
"Could not open file: " + fn);
1110 fprintf(fp,
"colorIndex %d\n", colorIndex);
1111 fprintf(fp,
"showSideBar %d\n", showSideBar);
1112 fprintf(fp,
"noWrap %d\n", noWrap);
1113 fprintf(fp,
"messageOnly %d\n", messageOnly);
1114 fprintf(fp,
"hideLineNumers %d\n", hideLineNumers);
1117 else if(requestType ==
"LoadUserPreferences")
1121 unsigned int colorIndex, showSideBar, noWrap, messageOnly, hideLineNumers;
1123 if(userInfo.username_ ==
"")
1125 __SUP_COUT_ERR__ <<
"Invalid user found! user=" << userInfo.username_
1127 xmlOut.addTextElementToData(
"Error",
"Error - Invalid user found.");
1131 std::string fn = (std::string)USER_CONSOLE_PREF_PATH + userInfo.username_ +
"." +
1132 (std::string)USERS_PREFERENCES_FILETYPE;
1136 FILE* fp = fopen(fn.c_str(),
"r");
1140 __SUP_COUT__ <<
"Returning defaults." << __E__;
1141 xmlOut.addTextElementToData(
"colorIndex",
"0");
1142 xmlOut.addTextElementToData(
"showSideBar",
"0");
1143 xmlOut.addTextElementToData(
"noWrap",
"1");
1144 xmlOut.addTextElementToData(
"messageOnly",
"0");
1145 xmlOut.addTextElementToData(
"hideLineNumers",
"1");
1148 fscanf(fp,
"%*s %u", &colorIndex);
1149 fscanf(fp,
"%*s %u", &showSideBar);
1150 fscanf(fp,
"%*s %u", &noWrap);
1151 fscanf(fp,
"%*s %u", &messageOnly);
1152 fscanf(fp,
"%*s %u", &hideLineNumers);
1161 sprintf(tmpStr,
"%u", colorIndex);
1162 xmlOut.addTextElementToData(
"colorIndex", tmpStr);
1163 sprintf(tmpStr,
"%u", showSideBar);
1164 xmlOut.addTextElementToData(
"showSideBar", tmpStr);
1165 sprintf(tmpStr,
"%u", noWrap);
1166 xmlOut.addTextElementToData(
"noWrap", tmpStr);
1167 sprintf(tmpStr,
"%u", messageOnly);
1168 xmlOut.addTextElementToData(
"messageOnly", tmpStr);
1169 sprintf(tmpStr,
"%u", hideLineNumers);
1170 xmlOut.addTextElementToData(
"hideLineNumers", tmpStr);
1172 else if(requestType ==
"GetTraceLevels")
1174 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1177 txParameters.
addParameter(
"Request",
"GetTraceLevels");
1185 traceMapToXDAQHostname_.clear();
1187 std::string traceList =
"";
1188 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1189 for(
const auto& appInfo : allTraceApps)
1191 __SUP_COUT__ <<
"Supervisor hostname = " << appInfo.first <<
"/"
1192 << appInfo.second.getId()
1193 <<
" name = " << appInfo.second.getName()
1194 <<
" class = " << appInfo.second.getClass()
1195 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1198 xoap::MessageReference retMsg =
1199 SOAPMessenger::sendWithSOAPReply(appInfo.second.getDescriptor(),
1200 "TRACESupervisorRequest",
1202 SOAPUtilities::receive(retMsg, rxParameters);
1203 __SUP_COUT__ <<
"Received TRACE response: "
1204 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1205 << SOAPUtilities::translate(retMsg) << __E__;
1207 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1209 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1211 << appInfo.first <<
"/" << appInfo.second.getId()
1212 <<
" name = " << appInfo.second.getName()
1213 <<
" class = " << appInfo.second.getClass()
1214 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1217 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1219 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1224 catch(
const xdaq::exception::Exception& e)
1226 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1227 << appInfo.second.getId()
1228 <<
" name = " << appInfo.second.getName() <<
". \n\n"
1229 << e.what() << __E__;
1232 __SUP_COUT_ERR__ << ss.str();
1236 std::vector<std::string> traceHostnameArr;
1237 __COUTTV__(rxParameters.getValue(
"TRACEHostnameList"));
1239 rxParameters.getValue(
"TRACEHostnameList"), traceHostnameArr, {
';'});
1240 for(
const auto& traceHostname : traceHostnameArr)
1242 if(traceHostname ==
"")
1244 traceMapToXDAQHostname_[traceHostname] = appInfo.first;
1252 __COUTTV__(rxParameters.getValue(
"TRACEList"));
1253 traceList += rxParameters.getValue(
"TRACEList");
1256 __SUP_COUT__ <<
"TRACE hostname map received: \n"
1258 __SUP_COUT__ <<
"TRACE List received: \n" << traceList << __E__;
1259 xmlOut.addTextElementToData(
"traceList", traceList);
1261 else if(requestType ==
"SetTraceLevels")
1263 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1265 std::string individualValues =
1272 __SUP_COUTV__(individualValues);
1273 __SUP_COUTV__(setMode);
1275 __SUP_COUTV__(setValueMSB);
1276 __SUP_COUTV__(setValueLSB);
1278 std::map<std::string , std::string > hostToLabelMap;
1280 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1287 std::string modifiedTraceList =
"";
1288 std::string xdaqHostname;
1290 for(
auto& hostLabelsPair : hostToLabelMap)
1294 __SUP_COUTV__(hostLabelsPair.first);
1295 __SUP_COUTV__(hostLabelsPair.second);
1300 xdaqHostname = traceMapToXDAQHostname_.at(hostLabelsPair.first);
1304 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1305 << hostLabelsPair.first <<
"' to xdaq Context hostname."
1307 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1313 __SUP_COUTV__(xdaqHostname);
1315 auto& appInfo = allTraceApps.at(xdaqHostname);
1316 __SUP_COUT__ <<
"Supervisor hostname = " << hostLabelsPair.first <<
"/"
1317 << xdaqHostname <<
":" << appInfo.getId()
1318 <<
" name = " << appInfo.getName()
1319 <<
" class = " << appInfo.getClass()
1320 <<
" hostname = " << appInfo.getHostname() << __E__;
1324 txParameters.
addParameter(
"Request",
"SetTraceLevels");
1325 txParameters.
addParameter(
"IndividualValues", individualValues);
1326 txParameters.
addParameter(
"Host", hostLabelsPair.first);
1328 txParameters.
addParameter(
"Labels", hostLabelsPair.second);
1332 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1333 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1334 SOAPUtilities::receive(retMsg, rxParameters);
1335 __SUP_COUT__ <<
"Received TRACE response: "
1336 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1337 << SOAPUtilities::translate(retMsg) << __E__;
1339 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1341 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1343 << hostLabelsPair.first <<
"/" << appInfo.getId()
1344 <<
" name = " << appInfo.getName()
1345 <<
" class = " << appInfo.getClass()
1346 <<
" hostname = " << appInfo.getHostname() << __E__;
1349 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1351 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1356 catch(
const xdaq::exception::Exception& e)
1358 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1359 << appInfo.getId() <<
" name = " << appInfo.getName()
1361 << e.what() << __E__;
1365 modifiedTraceList +=
1366 ";" + hostLabelsPair.first;
1370 modifiedTraceList += rxParameters.getValue(
"TRACEList");
1374 __SUP_COUT__ <<
"mod'd TRACE List received: \n" << modifiedTraceList << __E__;
1375 xmlOut.addTextElementToData(
"modTraceList", modifiedTraceList);
1377 else if(requestType ==
"GetTriggerStatus")
1379 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1381 txParameters.
addParameter(
"Request",
"GetTriggerStatus");
1388 std::string traceTriggerStatus =
"";
1389 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1390 for(
const auto& appInfo : allTraceApps)
1392 __SUP_COUT__ <<
"Supervisor hostname = " << appInfo.first <<
"/"
1393 << appInfo.second.getId()
1394 <<
" name = " << appInfo.second.getName()
1395 <<
" class = " << appInfo.second.getClass()
1396 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1399 xoap::MessageReference retMsg =
1400 SOAPMessenger::sendWithSOAPReply(appInfo.second.getDescriptor(),
1401 "TRACESupervisorRequest",
1403 SOAPUtilities::receive(retMsg, rxParameters);
1404 __SUP_COUT__ <<
"Received TRACE response: "
1405 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1406 << SOAPUtilities::translate(retMsg) << __E__;
1408 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1410 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1412 << appInfo.first <<
"/" << appInfo.second.getId()
1413 <<
" name = " << appInfo.second.getName()
1414 <<
" class = " << appInfo.second.getClass()
1415 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1418 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1420 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1425 catch(
const xdaq::exception::Exception& e)
1427 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1428 << appInfo.second.getId()
1429 <<
" name = " << appInfo.second.getName() <<
". \n\n"
1430 << e.what() << __E__;
1434 traceTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1437 __SUP_COUT__ <<
"TRACE Trigger Status received: \n"
1438 << traceTriggerStatus << __E__;
1439 xmlOut.addTextElementToData(
"traceTriggerStatus", traceTriggerStatus);
1441 else if(requestType ==
"SetTriggerEnable")
1443 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1447 __SUP_COUTV__(hostList);
1449 std::vector<std::string > hosts;
1451 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1458 std::string modifiedTriggerStatus =
"";
1459 std::string xdaqHostname;
1461 for(
auto& host : hosts)
1465 __SUP_COUTV__(host);
1472 xdaqHostname = traceMapToXDAQHostname_.at(host);
1476 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1477 << host <<
"' to xdaq Context hostname." << __E__;
1478 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1484 __SUP_COUTV__(xdaqHostname);
1486 auto& appInfo = allTraceApps.at(xdaqHostname);
1487 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1488 << appInfo.getId() <<
" name = " << appInfo.getName()
1489 <<
" class = " << appInfo.getClass()
1490 <<
" hostname = " << appInfo.getHostname() << __E__;
1494 txParameters.
addParameter(
"Request",
"SetTriggerEnable");
1497 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1498 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1499 SOAPUtilities::receive(retMsg, rxParameters);
1500 __SUP_COUT__ <<
"Received TRACE response: "
1501 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1502 << SOAPUtilities::translate(retMsg) << __E__;
1504 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1506 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1508 << host <<
"/" << appInfo.getId()
1509 <<
" name = " << appInfo.getName()
1510 <<
" class = " << appInfo.getClass()
1511 <<
" hostname = " << appInfo.getHostname() << __E__;
1514 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1516 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1521 catch(
const xdaq::exception::Exception& e)
1523 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1524 << appInfo.getId() <<
" name = " << appInfo.getName()
1526 << e.what() << __E__;
1530 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1533 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1534 << modifiedTriggerStatus << __E__;
1535 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1537 else if(requestType ==
"ResetTRACE")
1539 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1543 __SUP_COUTV__(hostList);
1545 std::vector<std::string > hosts;
1547 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1554 std::string modifiedTriggerStatus =
"";
1555 std::string xdaqHostname;
1557 for(
auto& host : hosts)
1561 __SUP_COUTV__(host);
1568 xdaqHostname = traceMapToXDAQHostname_.at(host);
1572 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1573 << host <<
"' to xdaq Context hostname." << __E__;
1574 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1580 __SUP_COUTV__(xdaqHostname);
1582 auto& appInfo = allTraceApps.at(xdaqHostname);
1583 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1584 << appInfo.getId() <<
" name = " << appInfo.getName()
1585 <<
" class = " << appInfo.getClass()
1586 <<
" hostname = " << appInfo.getHostname() << __E__;
1593 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1594 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1595 SOAPUtilities::receive(retMsg, rxParameters);
1596 __SUP_COUT__ <<
"Received TRACE response: "
1597 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1598 << SOAPUtilities::translate(retMsg) << __E__;
1600 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1602 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1604 << host <<
"/" << appInfo.getId()
1605 <<
" name = " << appInfo.getName()
1606 <<
" class = " << appInfo.getClass()
1607 <<
" hostname = " << appInfo.getHostname() << __E__;
1610 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1612 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1617 catch(
const xdaq::exception::Exception& e)
1619 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1620 << appInfo.getId() <<
" name = " << appInfo.getName()
1622 << e.what() << __E__;
1626 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1629 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1630 << modifiedTriggerStatus << __E__;
1631 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1633 else if(requestType ==
"EnableTRACE")
1635 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1640 __SUP_COUTV__(hostList);
1641 __SUP_COUTV__(enable);
1643 std::vector<std::string > hosts;
1645 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1652 std::string modifiedTriggerStatus =
"";
1653 std::string xdaqHostname;
1655 for(
auto& host : hosts)
1659 __SUP_COUTV__(host);
1666 xdaqHostname = traceMapToXDAQHostname_.at(host);
1670 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1671 << host <<
"' to xdaq Context hostname." << __E__;
1672 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1678 __SUP_COUTV__(xdaqHostname);
1680 auto& appInfo = allTraceApps.at(xdaqHostname);
1681 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1682 << appInfo.getId() <<
" name = " << appInfo.getName()
1683 <<
" class = " << appInfo.getClass()
1684 <<
" hostname = " << appInfo.getHostname() << __E__;
1692 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1693 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1694 SOAPUtilities::receive(retMsg, rxParameters);
1695 __SUP_COUT__ <<
"Received TRACE response: "
1696 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1697 << SOAPUtilities::translate(retMsg) << __E__;
1699 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1701 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1703 << host <<
"/" << appInfo.getId()
1704 <<
" name = " << appInfo.getName()
1705 <<
" class = " << appInfo.getClass()
1706 <<
" hostname = " << appInfo.getHostname() << __E__;
1709 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1711 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1716 catch(
const xdaq::exception::Exception& e)
1718 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1719 << appInfo.getId() <<
" name = " << appInfo.getName()
1721 << e.what() << __E__;
1725 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1728 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1729 << modifiedTriggerStatus << __E__;
1730 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1732 else if(requestType ==
"GetTraceSnapshot")
1734 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1740 __SUP_COUTV__(hostList);
1741 __SUP_COUTV__(filterFor);
1742 __SUP_COUTV__(filterOut);
1744 std::vector<std::string > hosts;
1746 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1754 std::string modifiedTriggerStatus =
"";
1755 std::string xdaqHostname;
1757 for(
auto& host : hosts)
1761 __SUP_COUTV__(host);
1768 xdaqHostname = traceMapToXDAQHostname_.at(host);
1772 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1773 << host <<
"' to xdaq Context hostname." << __E__;
1774 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1780 __SUP_COUTV__(xdaqHostname);
1782 auto& appInfo = allTraceApps.at(xdaqHostname);
1783 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1784 << appInfo.getId() <<
" name = " << appInfo.getName()
1785 <<
" class = " << appInfo.getClass()
1786 <<
" hostname = " << appInfo.getHostname() << __E__;
1795 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1796 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1797 SOAPUtilities::receive(retMsg, rxParameters);
1798 __SUP_COUT__ <<
"Received TRACE response: "
1799 << SOAPUtilities::translate(retMsg).getCommand() << __E__;
1802 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1804 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1806 << host <<
"/" << appInfo.getId()
1807 <<
" name = " << appInfo.getName()
1808 <<
" class = " << appInfo.getClass()
1809 <<
" hostname = " << appInfo.getHostname() << __E__;
1812 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1814 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1819 catch(
const xdaq::exception::Exception& e)
1821 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1822 << appInfo.getId() <<
" name = " << appInfo.getName()
1824 << e.what() << __E__;
1828 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1829 xmlOut.addTextElementToData(
"host", host);
1830 std::string snapshot = rxParameters.getValue(
"TRACESnapshot");
1839 std::string filename =
1840 USER_CONSOLE_SNAPSHOT_PATH +
"snapshot_" + host +
".txt";
1841 __SUP_COUTV__(filename);
1842 FILE* fp = fopen(filename.c_str(),
"w");
1845 __SUP_SS__ <<
"Failed to create snapshot file: " << filename << __E__;
1849 "TRACE Snapshot taken at %s\n",
1852 if(snapshot.size() > 5 && snapshot[2] !=
'i')
1857 " idx us_tod delta pid tid cpu "
1858 " trcname lvl r msg \n");
1860 "----- ---------------- ----------- ------ ------ --- "
1861 "-------------------------------------- --- - "
1862 "--------------------------\n");
1864 fprintf(fp,
"%s", snapshot.c_str());
1869 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1870 << modifiedTriggerStatus << __E__;
1871 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1873 else if(requestType ==
"GetCustomCountsAndActions" ||
1874 requestType ==
"AddCustomCountsAndAction" ||
1875 requestType ==
"ModifyCustomCountsAndAction")
1877 __SUP_COUT__ <<
"requestType " << requestType
1878 <<
" size=" << priorityCustomTriggerList_.size() << __E__;
1883 std::lock_guard<std::mutex> lock(messageMutex_);
1885 if(requestType ==
"AddCustomCountsAndAction" ||
1886 requestType ==
"ModifyCustomCountsAndAction")
1890 uint32_t priority = CgiDataUtilities::postDataAsInt(cgiIn,
"priority");
1893 uint32_t triggerOnCount =
1894 CgiDataUtilities::postDataAsInt(cgiIn,
"triggerOnCount");
1896 CgiDataUtilities::postDataAsInt(cgiIn,
"doLoop") > 0 ? true :
false;
1898 CgiDataUtilities::postDataAsInt(cgiIn,
"isArmed") > 0 ? true :
false;
1900 __SUP_COUTV__(needle);
1901 __SUP_COUTV__(priority);
1902 __SUP_COUTV__(action);
1903 __SUP_COUTV__(triggerOnCount);
1904 __SUP_COUTV__(doLoop);
1905 __SUP_COUTV__(isArmed);
1907 if(requestType ==
"ModifyCustomCountsAndAction")
1911 std::string currentNeedle =
1915 std::vector<std::string> csvNeedles =
1917 for(
size_t i = csvNeedles.size() - 1; i < csvNeedles.size(); --i)
1919 if(csvNeedles[i].size() == 0)
1922 priority = modifyCustomTriggeredAction(
1934 addCustomTriggeredAction(
1935 needle, action, priority, triggerOnCount, doLoop, isArmed);
1937 saveCustomCountList();
1941 size_t untriggeredCount =
1944 for(
const auto& customCount : priorityCustomTriggerList_)
1946 xercesc::DOMElement* customCountParent =
1947 xmlOut.addTextElementToData(
"customCount",
"");
1949 if(customCount.occurrences < untriggeredCount)
1950 untriggeredCount -= customCount.occurrences;
1953 __SUP_SS__ <<
"Impossible custom count; notify admins! "
1954 << customCount.occurrences <<
" > " << untriggeredCount
1966 "count", std::to_string(customCount.occurrences), customCountParent);
1968 "action", customCount.action, customCountParent);
1970 std::to_string(customCount.triggerOnCount),
1973 "doLoop", std::to_string(customCount.doLoop), customCountParent);
1975 "isArmed", std::to_string(customCount.isArmed), customCountParent);
1979 xercesc::DOMElement* customCountParent =
1980 xmlOut.addTextElementToData(
"customCount",
"");
1983 "count", std::to_string(untriggeredCount), customCountParent);
1991 __SUP_SS__ <<
"requestType Request, " << requestType <<
", not recognized."
2006 std::stringstream ss;
2009 CorePropertySupervisorBase::getSupervisorUptime()));
2017 ss <<
", Error #: " << errorCount_;
2018 ss <<
", Warn #: " << warnCount_;
2019 ss <<
", Last Error ("
2023 << (lastErrorMessageTime_ ? StringMacros::encodeURIComponent(lastErrorMessage_)
2025 ss <<
", Last Warn ("
2029 << (lastWarnMessageTime_ ? StringMacros::encodeURIComponent(lastWarnMessage_)
2031 ss <<
", Last Info ("
2035 << (lastInfoMessageTime_ ? StringMacros::encodeURIComponent(lastInfoMessage_)
2037 ss <<
", Info #: " << infoCount_;
2038 ss <<
", First Error ("
2039 << (firstErrorMessageTime_
2043 << (firstErrorMessageTime_ ? StringMacros::encodeURIComponent(firstErrorMessage_)
2045 ss <<
", First Warn ("
2049 << (firstWarnMessageTime_ ? StringMacros::encodeURIComponent(firstWarnMessage_)
2051 ss <<
", First Info ("
2055 << (firstInfoMessageTime_ ? StringMacros::encodeURIComponent(firstInfoMessage_)
2085 const size_t lastUpdateCount)
2089 if(messages_.size() == 0)
2093 if(lastUpdateCount > messages_.back().getCount() && lastUpdateCount != (
size_t)-1)
2095 __SS__ <<
"Invalid lastUpdateCount: " << lastUpdateCount
2096 <<
" messagesArray size = " << messages_.back().getCount() << __E__;
2102 std::lock_guard<std::mutex> lock(messageMutex_);
2104 xmlOut->addTextElementToData(
"last_update_count",
2105 std::to_string(messages_.back().getCount()));
2107 refreshParent_ = xmlOut->addTextElementToData(
"messages",
"");
2109 bool requestOutOfSync =
false;
2110 std::string requestOutOfSyncMsg;
2112 size_t refreshReadPointer = 0;
2113 if(lastUpdateCount != (
size_t)-1)
2115 while(refreshReadPointer < messages_.size() &&
2116 messages_[refreshReadPointer].getCount() <= lastUpdateCount)
2118 ++refreshReadPointer;
2122 if(refreshReadPointer >= messages_.size())
2126 if(messages_.size() - refreshReadPointer > maxClientMessageRequest_)
2132 refreshReadPointer = messages_.size() - maxClientMessageRequest_;
2144 xmlOut->addTextElementToData(
2145 "earliest_update_count",
2146 std::to_string(messages_[refreshReadPointer].getCount()));
2149 for(; refreshReadPointer < messages_.size(); ++refreshReadPointer)
2151 auto msg = messages_[refreshReadPointer];
2152 if(msg.getCount() < lastUpdateCount)
2154 if(!requestOutOfSync)
2156 requestOutOfSync =
true;
2157 __SS__ <<
"Request is out of sync! Message count should be more recent! "
2158 << msg.getCount() <<
" < " << lastUpdateCount << __E__;
2159 requestOutOfSyncMsg = ss.str();
2165 addMessageToResponse(xmlOut, msg);
2169 if(requestOutOfSync)
2170 __SUP_COUT__ << requestOutOfSyncMsg;
2194 void ConsoleSupervisor::prependHistoricMessages(
HttpXmlDocument* xmlOut,
2195 const size_t earliestOnhandMessageCount)
2199 if(messages_.size() == 0)
2203 if(earliestOnhandMessageCount >= messages_.back().getCount())
2206 <<
"Invalid claim from user request of earliest onhand message sequence ID = "
2207 << earliestOnhandMessageCount
2208 <<
". Latest existing sequence ID = " << messages_.back().getCount()
2209 <<
". Was the Console Supervisor restarted?" << __E__;
2215 std::lock_guard<std::mutex> lock(messageMutex_);
2217 refreshParent_ = xmlOut->addTextElementToData(
"messages",
"");
2219 size_t refreshReadPointer = 0;
2220 size_t readCountStart = earliestOnhandMessageCount - maxClientMessageRequest_;
2221 if(readCountStart >= messages_.back().getCount())
2225 while(refreshReadPointer < messages_.size() &&
2226 messages_[refreshReadPointer].getCount() < readCountStart)
2228 ++refreshReadPointer;
2231 if(refreshReadPointer >= messages_.size())
2234 xmlOut->addTextElementToData(
"earliest_update_count",
2235 std::to_string(readCountStart));
2239 for(; refreshReadPointer < messages_.size(); ++refreshReadPointer)
2241 auto msg = messages_[refreshReadPointer];
2242 if(messages_[refreshReadPointer].getCount() >= earliestOnhandMessageCount)
2245 addMessageToResponse(xmlOut, msg);
2256 for(
auto& field : msg.fields)
2258 if(field.first == ConsoleMessageStruct::FieldType::SOURCE)
2260 if(field.first == ConsoleMessageStruct::FieldType::SOURCEID)
2264 if(field.first == ConsoleMessageStruct::FieldType::TIMESTAMP)
2271 "message_" + ConsoleMessageStruct::fieldNames.at(field.first),
2284 "message_Count", std::to_string(msg.getCount()), refreshParent_);
static std::string postData(cgicc::Cgicc &cgi, const std::string &needle)
virtual void forceSupervisorPropertyValues(void) override
virtual void request(const std::string &requestType, cgicc::Cgicc &cgiIn, HttpXmlDocument &xmlOut, const WebUsers::RequestUserInfo &userInfo) override
static const std::set< std::string > CUSTOM_TRIGGER_ACTIONS
Count always happens, and System Message always happens for FSM commands.
virtual std::string getStatusProgressDetail(void) override
void sendAsyncExceptionToGateway(const std::string &errMsg, bool isPauseException, bool isStopException)
void addParameter(const std::string name, const std::string value)
xercesc::DOMElement * addTextElementToParent(const std::string &childName, const std::string &childText, xercesc::DOMElement *parent)
void INIT_MF(const char *name)
@ SEQID
sequence ID is incrementing number independent from each source
static std::string getTimestampString(const std::string &linuxTimeInSeconds)
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static std::string exec(const char *cmd)
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
static std::string vectorToString(const std::vector< T > &setToReturn, const std::string &delimeter=", ")
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")
static void getMapFromString(const std::string &inputString, std::map< S, T > &mapToReturn, const std::set< char > &pairPairDelimiter={',', '|', '&'}, const std::set< char > &nameValueDelimiter={'=', ':'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
static std::string getTimeDurationString(const time_t durationInSeconds=time(0))
static std::string decodeURIComponent(const std::string &data)