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) [" << sourceLastSequenceID[newSourceId]
374 <<
" -> " << newSequenceId <<
"] from "
375 << cs->messages_.back().getSource() <<
":" << newSourceId
376 <<
"! (uptime: " << cs->getSupervisorUptime() <<
" s)"
378 __SS__ << missedSs.str();
379 std::cout << ss.str();
383 if(cs->getSupervisorUptime() > 20 &&
384 sourceLastSequenceID[newSourceId] !=
389 cs->messages_.emplace_back(
390 CONSOLE_SPECIAL_WARNING + missedSs.str(),
392 cs->priorityCustomTriggerList_);
394 cs->messages_.back().setTime(time(0));
396 if(cs->priorityCustomTriggerList_.size())
398 cs->customTriggerActionQueue_.push(
399 cs->priorityCustomTriggerList_
401 cs->priorityCustomTriggerList_[0]
403 cs->customTriggerActionQueue_.back()
404 .triggeredMessageCountIndex =
405 cs->messages_.back().getCount();
406 cs->messages_.back().setCustomTriggerMatch(
407 cs->customTriggerActionQueue_.back());
413 sourceLastSequenceID[newSourceId] = newSequenceId;
415 while(cs->messages_.size() > 0 &&
416 cs->messages_.size() > cs->maxMessageCount_)
418 cs->messages_.erase(cs->messages_.begin());
421 c += strlen(&(buffer.c_str()[c])) + 1;
435 (heartbeatCount < 60 * 5 &&
436 heartbeatCount % 60 == 59))
438 ++selfGeneratedMessageCount;
439 __COUT__ <<
"Console is alive and waiting... (if no messages, next "
440 "heartbeat is in two minutes)"
443 else if(heartbeatCount % (60 * 30) == 59)
445 ++selfGeneratedMessageCount;
446 __COUT__ <<
"Console is alive and waiting a long time... (if no "
447 "messages, next heartbeat is in one hour)"
458 if(i == 120 || selfGeneratedMessageCount == 5)
461 __COUTV__(selfGeneratedMessageCount);
462 __COUT__ <<
"No messages received at Console Supervisor. Exiting Console "
463 "messageFacilityReceiverWorkLoop"
468 if(cs->customTriggerActionQueue_.size() && !cs->customTriggerActionThreadExists_)
470 cs->customTriggerActionThreadExists_ =
true;
474 ConsoleSupervisor::customTriggerActionThread(c);
483 catch(
const std::runtime_error& e)
485 __COUT_ERR__ <<
"Error caught at Console Supervisor thread: " << e.what() << __E__;
489 __COUT_ERR__ <<
"Unknown error caught at Console Supervisor thread." << __E__;
498 __COUT__ <<
"Starting customTriggerActionThread" << __E__;
499 CustomTriggeredAction_t triggeredAction;
505 std::lock_guard<std::mutex> lock(cs->messageMutex_);
506 if(cs->customTriggerActionQueue_.size())
508 triggeredAction = cs->customTriggerActionQueue_.front();
509 cs->customTriggerActionQueue_.pop();
513 if(triggeredAction.action.size())
515 __COUTS__(2) <<
"Handling action '" << triggeredAction.action
516 <<
"' on custom count search string: "
520 cs->doTriggeredAction(triggeredAction);
523 triggeredAction.action =
"";
524 triggeredAction.triggeredMessageCountIndex =
531 catch(
const std::runtime_error& e)
533 __COUT_ERR__ <<
"Error caught at Console Supervisor Action thread: " << e.what()
538 __COUT_ERR__ <<
"Unknown error caught at Console Supervisor Action thread." << __E__;
542 void ConsoleSupervisor::doTriggeredAction(
const CustomTriggeredAction_t& triggeredAction)
544 __SUP_COUT_INFO__ <<
"Launching Triggered Action '" << triggeredAction.action
545 <<
"' fired on custom count search string: "
562 __SUP_SS__ <<
"Unrecognized triggered action '" << triggeredAction.action
563 <<
",' valid actions are "
569 if(triggeredAction.action !=
"Count Only")
570 theRemoteWebUsers_.sendSystemMessage(
572 "In the Console Supervisor, a custom count fired the action '" +
573 triggeredAction.action +
"' on the search string '" +
577 if(triggeredAction.action ==
"Halt")
582 "Console-triggered FSM Halt", 0, 0);
586 theRemoteWebUsers_.sendSystemMessage(
588 "FSM Halt from Console Supervisor Triggered Action has failed!");
590 __SUP_COUTV__(
"FSM Halt triggered from console");
592 else if(triggeredAction.action ==
"Pause")
597 "Console-triggered FSM Pause", 1, 0);
601 theRemoteWebUsers_.sendSystemMessage(
603 "FSM Pause from Console Supervisor Triggered Action has failed!");
605 __SUP_COUTV__(
"FSM Pause triggered from console");
607 else if(triggeredAction.action ==
"Stop")
612 "Console-triggered FSM Stop", 0, 1);
614 catch(
const std::exception& e)
616 theRemoteWebUsers_.sendSystemMessage(
618 "FSM Stop from Console Supervisor Triggered Action has failed!");
620 __SUP_COUTV__(
"FSM Stop triggered from console");
622 else if(triggeredAction.action ==
"Run Script")
624 std::string triggerScriptPath =
"";
625 std::string scriptResult =
"";
628 triggerScriptPath = __ENV__(
"OTS_CUSTOM_TRIGGER_SCRIPT");
629 triggerScriptPath =
"source " + triggerScriptPath;
631 __COUT_INFO__ <<
"The Script " << triggerScriptPath
632 <<
" Was launched, here is the result " << scriptResult;
636 __SS__ <<
"Trigger script path not defined! Please use environment variable "
637 "'OTS_CUSTOM_TRIGGER_SCRIPT' or contact admins."
647 void ConsoleSupervisor::addCustomTriggeredAction(
const std::string& triggerNeedle,
648 const std::string& triggerAction,
650 uint32_t triggerOnCount,
654 __SUP_COUTV__(
"Adding custom triggered action");
655 __SUP_COUTV__(triggerNeedle);
656 __SUP_COUTV__(triggerAction);
657 __SUP_COUTV__(priority);
658 __SUP_COUTV__(triggerOnCount);
659 __SUP_COUTV__(doLoop);
660 __SUP_COUTV__(isArmed);
662 bool allAsterisks =
true;
663 for(
const auto& c : triggerNeedle)
666 allAsterisks =
false;
671 __SUP_SS__ <<
"Illegal empty Search String value for the new Custom Count and "
672 "Action! Please enter a valid Search String (* wildcards are "
673 "allowed, e.g. \"value = * seconds\")."
679 uint32_t currentPriority = -1;
680 for(
const auto& customTrigger : priorityCustomTriggerList_)
686 __SUP_SS__ <<
"Failure! Can not add Custom Count Search String that already "
689 <<
"' already existing at priority = " << currentPriority << __E__;
694 if(priority >= priorityCustomTriggerList_.size())
695 priority = priorityCustomTriggerList_.size();
696 if(priority == 0 && triggerNeedle != CONSOLE_MISSED_NEEDLE)
698 __SUP_SS__ <<
"Illegal priority position of '" << priority
699 <<
"' requested. Please enter a priority value greater than 0. "
700 "Position 0 is reserved for identifying missing messages at the "
701 "Console Supervisor. Note: the action for missing messages, at "
702 "priority 0, may be customized by the user."
706 __SUP_COUTV__(priority);
719 __SUP_SS__ <<
"Unrecognized triggered action '" << triggerAction
720 <<
",' valid actions are "
726 priorityCustomTriggerList_.insert(priorityCustomTriggerList_.begin() + priority,
727 CustomTriggeredAction_t());
734 priorityCustomTriggerList_[priority].needleSubstrings,
737 priorityCustomTriggerList_[priority].action = triggerAction;
738 priorityCustomTriggerList_[priority].triggerOnCount = triggerOnCount;
739 priorityCustomTriggerList_[priority].doLoop = doLoop;
740 priorityCustomTriggerList_[priority].isArmed = isArmed;
742 __SUP_COUT__ <<
"Added custom count: '"
744 priorityCustomTriggerList_[priority].needleSubstrings,
"*")
745 <<
"' at priority: " << priority
746 <<
" triggered every: " << triggerOnCount <<
" occurrences";
748 __SUP_COUT__ <<
" and will loop.";
750 __SUP_COUT__ <<
" and will not loop.";
751 __SUP_COUT__ << __E__;
759 uint32_t ConsoleSupervisor::modifyCustomTriggeredAction(
const std::string& currentNeedle,
760 const std::string& modifyType,
761 const std::string& setNeedle,
762 const std::string& setAction,
763 uint32_t setPriority,
764 uint32_t setTriggerOnCount,
768 __SUP_COUTV__(currentNeedle);
769 __SUP_COUTV__(modifyType);
770 __SUP_COUTV__(setNeedle);
771 __SUP_COUTV__(setAction);
772 __SUP_COUTV__(setPriority);
773 __SUP_COUTV__(setTriggerOnCount);
774 __SUP_COUTV__(setDoLoop);
775 __SUP_COUTV__(setIsArmed);
778 uint32_t currentPriority = -1;
780 for(
const auto& customTrigger : priorityCustomTriggerList_)
791 __SUP_COUTV__(currentPriority);
794 __SUP_SS__ <<
"Attempt to modify Custom Count Search String failed. Could not "
795 "find specified Search String '"
796 << currentNeedle <<
"' in prioritized list." << __E__;
800 if(modifyType ==
"Deletion")
802 if(currentPriority == 0)
804 __SUP_SS__ <<
"Illegal deletion requested of priority position 0. Position 0 "
805 "is reserved for identifying missing messages at the Console "
806 "Supervisor. Note: the action of priority 0 may be customized "
807 "by the user, but it can not be deleted."
812 __SUP_COUT__ <<
"Deleting custom count: "
814 priorityCustomTriggerList_[currentPriority].needleSubstrings,
817 << priorityCustomTriggerList_[currentPriority].action
818 <<
" and priority: " << currentPriority << __E__;
819 priorityCustomTriggerList_.erase(priorityCustomTriggerList_.begin() +
824 if(modifyType ==
"Priority" || modifyType ==
"All")
826 if(setPriority >= priorityCustomTriggerList_.size())
827 setPriority = priorityCustomTriggerList_.size();
828 if(setPriority == 0 && setNeedle != CONSOLE_MISSED_NEEDLE)
830 __SUP_SS__ <<
"Illegal priority position of '" << setPriority
831 <<
"' requested. Position 0 is reserved for identifying missing "
832 "messages at the Console Supervisor. Note: the action of "
833 "priority 0 may be customized by the user."
839 setPriority = currentPriority;
841 if(modifyType ==
"Action" || modifyType ==
"All")
853 __SUP_SS__ <<
"Unrecognized custom count action '" << setAction
854 <<
",' valid actions are "
859 priorityCustomTriggerList_[currentPriority].action = setAction;
862 if(modifyType ==
"Search String" || modifyType ==
"All")
865 priorityCustomTriggerList_[currentPriority].needleSubstrings.clear();
868 priorityCustomTriggerList_[currentPriority].needleSubstrings,
873 if(modifyType ==
"Trigger on Count" || modifyType ==
"All")
876 priorityCustomTriggerList_[currentPriority].triggerOnCount = setTriggerOnCount;
878 if(modifyType ==
"Do Loop" || modifyType ==
"All")
881 priorityCustomTriggerList_[currentPriority].doLoop = setDoLoop;
883 if(modifyType ==
"Arm Trigger" || modifyType ==
"All")
886 priorityCustomTriggerList_[currentPriority].isArmed = setIsArmed;
889 if(currentPriority != setPriority)
892 priorityCustomTriggerList_.insert(
893 priorityCustomTriggerList_.begin() + setPriority,
894 priorityCustomTriggerList_[currentPriority]);
897 if(currentPriority >= setPriority)
900 priorityCustomTriggerList_.erase(priorityCustomTriggerList_.begin() +
903 if(currentPriority < setPriority)
907 __SUP_COUT__ <<
"Modified '" << modifyType <<
"' custom count: "
909 priorityCustomTriggerList_[setPriority].needleSubstrings, {
'*'})
910 <<
" now w/action: " << priorityCustomTriggerList_[setPriority].action
911 <<
" and at priority: " << setPriority << __E__;
917 void ConsoleSupervisor::loadCustomCountList()
920 __SUP_COUT__ <<
"loadCustomCountList() from "
921 << USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME << __E__;
923 FILE* fp = fopen((USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME).c_str(),
"r");
926 __SUP_COUT__ <<
"Ignoring missing Custom Count list file at path: "
927 << (USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME) << __E__;
930 priorityCustomTriggerList_.clear();
937 size_t triggerOnCount = 0;
939 bool isArmed =
false;
940 while(fgets(line, 1000, fp))
946 line[strlen(line) - 1] =
'\0';
956 priority = std::stoi(line);
958 triggerOnCount = std::stoi(line);
960 doLoop = std::stoi(line) > 0 ? true :
false;
963 isArmed = std::stoi(line) > 0 ? true :
false;
964 __SUP_COUTTV__(needle);
965 __SUP_COUTTV__(priority);
966 __SUP_COUTTV__(action);
967 __SUP_COUTTV__(triggerOnCount);
968 __SUP_COUTTV__(doLoop);
969 __SUP_COUTTV__(isArmed);
972 CONSOLE_MISSED_NEEDLE)
973 addCustomTriggeredAction(
974 CONSOLE_MISSED_NEEDLE,
"System Message", 0, 1,
false,
true);
975 addCustomTriggeredAction(
976 needle, action, priority, triggerOnCount, doLoop, isArmed);
985 void ConsoleSupervisor::saveCustomCountList()
987 __SUP_COUT__ <<
"saveCustomCountList()" << __E__;
989 FILE* fp = fopen((USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME).c_str(),
"w");
992 __SUP_SS__ <<
"Failed to create Custom Count list file at path: "
993 << (USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME) << __E__;
996 unsigned int priority = 0;
997 for(
auto& customCount : priorityCustomTriggerList_)
1002 fprintf(fp,
"%s\n", customCount.action.c_str());
1003 fprintf(fp,
"%d\n", priority);
1004 fprintf(fp,
"%zu\n", customCount.triggerOnCount);
1005 fprintf(fp,
"%s\n", customCount.doLoop ?
"1" :
"0");
1006 fprintf(fp,
"%s\n", customCount.isArmed ?
"1" :
"0");
1013 void ConsoleSupervisor::defaultPage(xgi::Input* , xgi::Output* out)
1017 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
1018 "src='/WebPath/html/Console.html?urn="
1019 << getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
1027 CorePropertySupervisorBase::setSupervisorProperty(
1028 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
1037 cgicc::Cgicc& cgiIn,
1039 const WebUsers::RequestUserInfo& userInfo)
1062 if(requestType ==
"GetConsoleMsgs")
1067 if(lastUpdateCountStr ==
"")
1069 __SUP_COUT_ERR__ <<
"Invalid Parameters! lastUpdateCount="
1070 << lastUpdateCountStr << __E__;
1071 xmlOut.addTextElementToData(
"Error",
1072 "Error - Invalid parameters for GetConsoleMsgs.");
1076 size_t lastUpdateCount = std::stoull(lastUpdateCountStr);
1080 insertMessageRefresh(&xmlOut, lastUpdateCount);
1082 else if(requestType ==
"PrependHistoricMessages")
1084 size_t earliestOnhandMessageCount =
1085 CgiDataUtilities::postDataAsInt(cgiIn,
"earlyCount");
1086 __SUP_COUTV__(earliestOnhandMessageCount);
1087 prependHistoricMessages(&xmlOut, earliestOnhandMessageCount);
1089 else if(requestType ==
"SaveUserPreferences")
1091 int colorIndex = CgiDataUtilities::postDataAsInt(cgiIn,
"colorIndex");
1092 int showSideBar = CgiDataUtilities::postDataAsInt(cgiIn,
"showSideBar");
1093 int noWrap = CgiDataUtilities::postDataAsInt(cgiIn,
"noWrap");
1094 int messageOnly = CgiDataUtilities::postDataAsInt(cgiIn,
"messageOnly");
1095 int hideLineNumers = CgiDataUtilities::postDataAsInt(cgiIn,
"hideLineNumers");
1104 if(userInfo.username_ ==
"")
1106 __SUP_COUT_ERR__ <<
"Invalid user found! user=" << userInfo.username_
1108 xmlOut.addTextElementToData(
"Error",
1109 "Error - InvauserInfo.username_user found.");
1113 std::string fn = (std::string)USER_CONSOLE_PREF_PATH + userInfo.username_ +
"." +
1114 (std::string)USERS_PREFERENCES_FILETYPE;
1117 FILE* fp = fopen(fn.c_str(),
"w");
1121 __THROW__(ss.str() +
"Could not open file: " + fn);
1123 fprintf(fp,
"colorIndex %d\n", colorIndex);
1124 fprintf(fp,
"showSideBar %d\n", showSideBar);
1125 fprintf(fp,
"noWrap %d\n", noWrap);
1126 fprintf(fp,
"messageOnly %d\n", messageOnly);
1127 fprintf(fp,
"hideLineNumers %d\n", hideLineNumers);
1130 else if(requestType ==
"LoadUserPreferences")
1134 unsigned int colorIndex, showSideBar, noWrap, messageOnly, hideLineNumers;
1136 if(userInfo.username_ ==
"")
1138 __SUP_COUT_ERR__ <<
"Invalid user found! user=" << userInfo.username_
1140 xmlOut.addTextElementToData(
"Error",
"Error - Invalid user found.");
1144 std::string fn = (std::string)USER_CONSOLE_PREF_PATH + userInfo.username_ +
"." +
1145 (std::string)USERS_PREFERENCES_FILETYPE;
1149 FILE* fp = fopen(fn.c_str(),
"r");
1153 __SUP_COUT__ <<
"Returning defaults." << __E__;
1154 xmlOut.addTextElementToData(
"colorIndex",
"0");
1155 xmlOut.addTextElementToData(
"showSideBar",
"0");
1156 xmlOut.addTextElementToData(
"noWrap",
"1");
1157 xmlOut.addTextElementToData(
"messageOnly",
"0");
1158 xmlOut.addTextElementToData(
"hideLineNumers",
"1");
1161 fscanf(fp,
"%*s %u", &colorIndex);
1162 fscanf(fp,
"%*s %u", &showSideBar);
1163 fscanf(fp,
"%*s %u", &noWrap);
1164 fscanf(fp,
"%*s %u", &messageOnly);
1165 fscanf(fp,
"%*s %u", &hideLineNumers);
1174 sprintf(tmpStr,
"%u", colorIndex);
1175 xmlOut.addTextElementToData(
"colorIndex", tmpStr);
1176 sprintf(tmpStr,
"%u", showSideBar);
1177 xmlOut.addTextElementToData(
"showSideBar", tmpStr);
1178 sprintf(tmpStr,
"%u", noWrap);
1179 xmlOut.addTextElementToData(
"noWrap", tmpStr);
1180 sprintf(tmpStr,
"%u", messageOnly);
1181 xmlOut.addTextElementToData(
"messageOnly", tmpStr);
1182 sprintf(tmpStr,
"%u", hideLineNumers);
1183 xmlOut.addTextElementToData(
"hideLineNumers", tmpStr);
1185 else if(requestType ==
"GetTraceLevels")
1187 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1190 txParameters.
addParameter(
"Request",
"GetTraceLevels");
1198 traceMapToXDAQHostname_.clear();
1200 std::string traceList =
"";
1201 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1202 for(
const auto& appInfo : allTraceApps)
1204 __SUP_COUT__ <<
"Supervisor hostname = " << appInfo.first <<
"/"
1205 << appInfo.second.getId()
1206 <<
" name = " << appInfo.second.getName()
1207 <<
" class = " << appInfo.second.getClass()
1208 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1211 xoap::MessageReference retMsg =
1212 SOAPMessenger::sendWithSOAPReply(appInfo.second.getDescriptor(),
1213 "TRACESupervisorRequest",
1215 SOAPUtilities::receive(retMsg, rxParameters);
1216 __SUP_COUT__ <<
"Received TRACE response: "
1217 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1218 << SOAPUtilities::translate(retMsg) << __E__;
1220 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1222 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1224 << appInfo.first <<
"/" << appInfo.second.getId()
1225 <<
" name = " << appInfo.second.getName()
1226 <<
" class = " << appInfo.second.getClass()
1227 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1230 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1232 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1237 catch(
const xdaq::exception::Exception& e)
1239 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1240 << appInfo.second.getId()
1241 <<
" name = " << appInfo.second.getName() <<
". \n\n"
1242 << e.what() << __E__;
1245 __SUP_COUT_ERR__ << ss.str();
1249 std::vector<std::string> traceHostnameArr;
1250 __COUTTV__(rxParameters.getValue(
"TRACEHostnameList"));
1252 rxParameters.getValue(
"TRACEHostnameList"), traceHostnameArr, {
';'});
1253 for(
const auto& traceHostname : traceHostnameArr)
1255 if(traceHostname ==
"")
1257 traceMapToXDAQHostname_[traceHostname] = appInfo.first;
1265 __COUTTV__(rxParameters.getValue(
"TRACEList"));
1266 traceList += rxParameters.getValue(
"TRACEList");
1269 __SUP_COUT__ <<
"TRACE hostname map received: \n"
1271 __SUP_COUT__ <<
"TRACE List received: \n" << traceList << __E__;
1272 xmlOut.addTextElementToData(
"traceList", traceList);
1274 else if(requestType ==
"SetTraceLevels")
1276 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1278 std::string individualValues =
1285 __SUP_COUTV__(individualValues);
1286 __SUP_COUTV__(setMode);
1288 __SUP_COUTV__(setValueMSB);
1289 __SUP_COUTV__(setValueLSB);
1291 std::map<std::string , std::string > hostToLabelMap;
1293 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1300 std::string modifiedTraceList =
"";
1301 std::string xdaqHostname;
1303 for(
auto& hostLabelsPair : hostToLabelMap)
1307 __SUP_COUTV__(hostLabelsPair.first);
1308 __SUP_COUTV__(hostLabelsPair.second);
1313 xdaqHostname = traceMapToXDAQHostname_.at(hostLabelsPair.first);
1317 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1318 << hostLabelsPair.first <<
"' to xdaq Context hostname."
1320 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1326 __SUP_COUTV__(xdaqHostname);
1328 auto& appInfo = allTraceApps.at(xdaqHostname);
1329 __SUP_COUT__ <<
"Supervisor hostname = " << hostLabelsPair.first <<
"/"
1330 << xdaqHostname <<
":" << appInfo.getId()
1331 <<
" name = " << appInfo.getName()
1332 <<
" class = " << appInfo.getClass()
1333 <<
" hostname = " << appInfo.getHostname() << __E__;
1337 txParameters.
addParameter(
"Request",
"SetTraceLevels");
1338 txParameters.
addParameter(
"IndividualValues", individualValues);
1339 txParameters.
addParameter(
"Host", hostLabelsPair.first);
1341 txParameters.
addParameter(
"Labels", hostLabelsPair.second);
1345 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1346 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1347 SOAPUtilities::receive(retMsg, rxParameters);
1348 __SUP_COUT__ <<
"Received TRACE response: "
1349 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1350 << SOAPUtilities::translate(retMsg) << __E__;
1352 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1354 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1356 << hostLabelsPair.first <<
"/" << appInfo.getId()
1357 <<
" name = " << appInfo.getName()
1358 <<
" class = " << appInfo.getClass()
1359 <<
" hostname = " << appInfo.getHostname() << __E__;
1362 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1364 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1369 catch(
const xdaq::exception::Exception& e)
1371 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1372 << appInfo.getId() <<
" name = " << appInfo.getName()
1374 << e.what() << __E__;
1378 modifiedTraceList +=
1379 ";" + hostLabelsPair.first;
1383 modifiedTraceList += rxParameters.getValue(
"TRACEList");
1387 __SUP_COUT__ <<
"mod'd TRACE List received: \n" << modifiedTraceList << __E__;
1388 xmlOut.addTextElementToData(
"modTraceList", modifiedTraceList);
1390 else if(requestType ==
"GetTriggerStatus")
1392 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1394 txParameters.
addParameter(
"Request",
"GetTriggerStatus");
1401 std::string traceTriggerStatus =
"";
1402 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1403 for(
const auto& appInfo : allTraceApps)
1405 __SUP_COUT__ <<
"Supervisor hostname = " << appInfo.first <<
"/"
1406 << appInfo.second.getId()
1407 <<
" name = " << appInfo.second.getName()
1408 <<
" class = " << appInfo.second.getClass()
1409 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1412 xoap::MessageReference retMsg =
1413 SOAPMessenger::sendWithSOAPReply(appInfo.second.getDescriptor(),
1414 "TRACESupervisorRequest",
1416 SOAPUtilities::receive(retMsg, rxParameters);
1417 __SUP_COUT__ <<
"Received TRACE response: "
1418 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1419 << SOAPUtilities::translate(retMsg) << __E__;
1421 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1423 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1425 << appInfo.first <<
"/" << appInfo.second.getId()
1426 <<
" name = " << appInfo.second.getName()
1427 <<
" class = " << appInfo.second.getClass()
1428 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1431 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1433 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1438 catch(
const xdaq::exception::Exception& e)
1440 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1441 << appInfo.second.getId()
1442 <<
" name = " << appInfo.second.getName() <<
". \n\n"
1443 << e.what() << __E__;
1447 traceTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1450 __SUP_COUT__ <<
"TRACE Trigger Status received: \n"
1451 << traceTriggerStatus << __E__;
1452 xmlOut.addTextElementToData(
"traceTriggerStatus", traceTriggerStatus);
1454 else if(requestType ==
"SetTriggerEnable")
1456 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1460 __SUP_COUTV__(hostList);
1462 std::vector<std::string > hosts;
1464 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1471 std::string modifiedTriggerStatus =
"";
1472 std::string xdaqHostname;
1474 for(
auto& host : hosts)
1478 __SUP_COUTV__(host);
1485 xdaqHostname = traceMapToXDAQHostname_.at(host);
1489 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1490 << host <<
"' to xdaq Context hostname." << __E__;
1491 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1497 __SUP_COUTV__(xdaqHostname);
1499 auto& appInfo = allTraceApps.at(xdaqHostname);
1500 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1501 << appInfo.getId() <<
" name = " << appInfo.getName()
1502 <<
" class = " << appInfo.getClass()
1503 <<
" hostname = " << appInfo.getHostname() << __E__;
1507 txParameters.
addParameter(
"Request",
"SetTriggerEnable");
1510 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1511 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1512 SOAPUtilities::receive(retMsg, rxParameters);
1513 __SUP_COUT__ <<
"Received TRACE response: "
1514 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1515 << SOAPUtilities::translate(retMsg) << __E__;
1517 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1519 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1521 << host <<
"/" << appInfo.getId()
1522 <<
" name = " << appInfo.getName()
1523 <<
" class = " << appInfo.getClass()
1524 <<
" hostname = " << appInfo.getHostname() << __E__;
1527 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1529 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1534 catch(
const xdaq::exception::Exception& e)
1536 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1537 << appInfo.getId() <<
" name = " << appInfo.getName()
1539 << e.what() << __E__;
1543 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1546 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1547 << modifiedTriggerStatus << __E__;
1548 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1550 else if(requestType ==
"ResetTRACE")
1552 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1556 __SUP_COUTV__(hostList);
1558 std::vector<std::string > hosts;
1560 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1567 std::string modifiedTriggerStatus =
"";
1568 std::string xdaqHostname;
1570 for(
auto& host : hosts)
1574 __SUP_COUTV__(host);
1581 xdaqHostname = traceMapToXDAQHostname_.at(host);
1585 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1586 << host <<
"' to xdaq Context hostname." << __E__;
1587 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1593 __SUP_COUTV__(xdaqHostname);
1595 auto& appInfo = allTraceApps.at(xdaqHostname);
1596 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1597 << appInfo.getId() <<
" name = " << appInfo.getName()
1598 <<
" class = " << appInfo.getClass()
1599 <<
" hostname = " << appInfo.getHostname() << __E__;
1606 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1607 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1608 SOAPUtilities::receive(retMsg, rxParameters);
1609 __SUP_COUT__ <<
"Received TRACE response: "
1610 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1611 << SOAPUtilities::translate(retMsg) << __E__;
1613 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1615 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1617 << host <<
"/" << appInfo.getId()
1618 <<
" name = " << appInfo.getName()
1619 <<
" class = " << appInfo.getClass()
1620 <<
" hostname = " << appInfo.getHostname() << __E__;
1623 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1625 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1630 catch(
const xdaq::exception::Exception& e)
1632 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1633 << appInfo.getId() <<
" name = " << appInfo.getName()
1635 << e.what() << __E__;
1639 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1642 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1643 << modifiedTriggerStatus << __E__;
1644 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1646 else if(requestType ==
"EnableTRACE")
1648 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1653 __SUP_COUTV__(hostList);
1654 __SUP_COUTV__(enable);
1656 std::vector<std::string > hosts;
1658 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1665 std::string modifiedTriggerStatus =
"";
1666 std::string xdaqHostname;
1668 for(
auto& host : hosts)
1672 __SUP_COUTV__(host);
1679 xdaqHostname = traceMapToXDAQHostname_.at(host);
1683 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1684 << host <<
"' to xdaq Context hostname." << __E__;
1685 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1691 __SUP_COUTV__(xdaqHostname);
1693 auto& appInfo = allTraceApps.at(xdaqHostname);
1694 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1695 << appInfo.getId() <<
" name = " << appInfo.getName()
1696 <<
" class = " << appInfo.getClass()
1697 <<
" hostname = " << appInfo.getHostname() << __E__;
1705 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1706 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1707 SOAPUtilities::receive(retMsg, rxParameters);
1708 __SUP_COUT__ <<
"Received TRACE response: "
1709 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1710 << SOAPUtilities::translate(retMsg) << __E__;
1712 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1714 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1716 << host <<
"/" << appInfo.getId()
1717 <<
" name = " << appInfo.getName()
1718 <<
" class = " << appInfo.getClass()
1719 <<
" hostname = " << appInfo.getHostname() << __E__;
1722 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1724 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1729 catch(
const xdaq::exception::Exception& e)
1731 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1732 << appInfo.getId() <<
" name = " << appInfo.getName()
1734 << e.what() << __E__;
1738 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1741 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1742 << modifiedTriggerStatus << __E__;
1743 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1745 else if(requestType ==
"GetTraceSnapshot")
1747 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1753 __SUP_COUTV__(hostList);
1754 __SUP_COUTV__(filterFor);
1755 __SUP_COUTV__(filterOut);
1757 std::vector<std::string > hosts;
1759 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1767 std::string modifiedTriggerStatus =
"";
1768 std::string xdaqHostname;
1770 for(
auto& host : hosts)
1774 __SUP_COUTV__(host);
1781 xdaqHostname = traceMapToXDAQHostname_.at(host);
1785 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1786 << host <<
"' to xdaq Context hostname." << __E__;
1787 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1793 __SUP_COUTV__(xdaqHostname);
1795 auto& appInfo = allTraceApps.at(xdaqHostname);
1796 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1797 << appInfo.getId() <<
" name = " << appInfo.getName()
1798 <<
" class = " << appInfo.getClass()
1799 <<
" hostname = " << appInfo.getHostname() << __E__;
1808 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1809 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1810 SOAPUtilities::receive(retMsg, rxParameters);
1811 __SUP_COUT__ <<
"Received TRACE response: "
1812 << SOAPUtilities::translate(retMsg).getCommand() << __E__;
1815 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1817 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1819 << host <<
"/" << appInfo.getId()
1820 <<
" name = " << appInfo.getName()
1821 <<
" class = " << appInfo.getClass()
1822 <<
" hostname = " << appInfo.getHostname() << __E__;
1825 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1827 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1832 catch(
const xdaq::exception::Exception& e)
1834 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1835 << appInfo.getId() <<
" name = " << appInfo.getName()
1837 << e.what() << __E__;
1841 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1842 xmlOut.addTextElementToData(
"host", host);
1843 std::string snapshot = rxParameters.getValue(
"TRACESnapshot");
1852 std::string filename =
1853 USER_CONSOLE_SNAPSHOT_PATH +
"snapshot_" + host +
".txt";
1854 __SUP_COUTV__(filename);
1855 FILE* fp = fopen(filename.c_str(),
"w");
1858 __SUP_SS__ <<
"Failed to create snapshot file: " << filename << __E__;
1862 "TRACE Snapshot taken at %s\n",
1865 if(snapshot.size() > 5 && snapshot[2] !=
'i')
1870 " idx us_tod delta pid tid cpu "
1871 " trcname lvl r msg \n");
1873 "----- ---------------- ----------- ------ ------ --- "
1874 "-------------------------------------- --- - "
1875 "--------------------------\n");
1877 fprintf(fp,
"%s", snapshot.c_str());
1882 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1883 << modifiedTriggerStatus << __E__;
1884 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1886 else if(requestType ==
"GetCustomCountsAndActions" ||
1887 requestType ==
"AddCustomCountsAndAction" ||
1888 requestType ==
"ModifyCustomCountsAndAction")
1890 __SUP_COUT__ <<
"requestType " << requestType
1891 <<
" size=" << priorityCustomTriggerList_.size() << __E__;
1896 std::lock_guard<std::mutex> lock(messageMutex_);
1898 if(requestType ==
"AddCustomCountsAndAction" ||
1899 requestType ==
"ModifyCustomCountsAndAction")
1903 uint32_t priority = CgiDataUtilities::postDataAsInt(cgiIn,
"priority");
1906 uint32_t triggerOnCount =
1907 CgiDataUtilities::postDataAsInt(cgiIn,
"triggerOnCount");
1909 CgiDataUtilities::postDataAsInt(cgiIn,
"doLoop") > 0 ? true :
false;
1911 CgiDataUtilities::postDataAsInt(cgiIn,
"isArmed") > 0 ? true :
false;
1913 __SUP_COUTV__(needle);
1914 __SUP_COUTV__(priority);
1915 __SUP_COUTV__(action);
1916 __SUP_COUTV__(triggerOnCount);
1917 __SUP_COUTV__(doLoop);
1918 __SUP_COUTV__(isArmed);
1920 if(requestType ==
"ModifyCustomCountsAndAction")
1924 std::string currentNeedle =
1928 std::vector<std::string> csvNeedles =
1930 for(
size_t i = csvNeedles.size() - 1; i < csvNeedles.size(); --i)
1932 if(csvNeedles[i].size() == 0)
1935 priority = modifyCustomTriggeredAction(
1947 addCustomTriggeredAction(
1948 needle, action, priority, triggerOnCount, doLoop, isArmed);
1950 saveCustomCountList();
1954 size_t untriggeredCount =
1957 for(
const auto& customCount : priorityCustomTriggerList_)
1959 xercesc::DOMElement* customCountParent =
1960 xmlOut.addTextElementToData(
"customCount",
"");
1962 if(customCount.occurrences < untriggeredCount)
1963 untriggeredCount -= customCount.occurrences;
1966 __SUP_SS__ <<
"Impossible custom count; notify admins! "
1967 << customCount.occurrences <<
" > " << untriggeredCount
1979 "count", std::to_string(customCount.occurrences), customCountParent);
1981 "action", customCount.action, customCountParent);
1983 std::to_string(customCount.triggerOnCount),
1986 "doLoop", std::to_string(customCount.doLoop), customCountParent);
1988 "isArmed", std::to_string(customCount.isArmed), customCountParent);
1992 xercesc::DOMElement* customCountParent =
1993 xmlOut.addTextElementToData(
"customCount",
"");
1996 "count", std::to_string(untriggeredCount), customCountParent);
2004 __SUP_SS__ <<
"requestType Request, " << requestType
2005 <<
", not recognized by the Console Supervisor (was it intended for "
2006 "another Supervisor?)."
2021 std::stringstream ss;
2024 CorePropertySupervisorBase::getSupervisorUptime()));
2032 ss <<
", Error #: " << errorCount_;
2033 ss <<
", Warn #: " << warnCount_;
2034 ss <<
", Last Error ("
2038 << (lastErrorMessageTime_ ? StringMacros::encodeURIComponent(lastErrorMessage_)
2040 ss <<
", Last Warn ("
2044 << (lastWarnMessageTime_ ? StringMacros::encodeURIComponent(lastWarnMessage_)
2046 ss <<
", Last Info ("
2050 << (lastInfoMessageTime_ ? StringMacros::encodeURIComponent(lastInfoMessage_)
2052 ss <<
", Info #: " << infoCount_;
2053 ss <<
", First Error ("
2054 << (firstErrorMessageTime_
2058 << (firstErrorMessageTime_ ? StringMacros::encodeURIComponent(firstErrorMessage_)
2060 ss <<
", First Warn ("
2064 << (firstWarnMessageTime_ ? StringMacros::encodeURIComponent(firstWarnMessage_)
2066 ss <<
", First Info ("
2070 << (firstInfoMessageTime_ ? StringMacros::encodeURIComponent(firstInfoMessage_)
2100 const size_t lastUpdateCount)
2104 if(messages_.size() == 0)
2108 if(lastUpdateCount > messages_.back().getCount() && lastUpdateCount != (
size_t)-1)
2110 __SS__ <<
"Invalid lastUpdateCount: " << lastUpdateCount
2111 <<
" messagesArray size = " << messages_.back().getCount() << __E__;
2117 std::lock_guard<std::mutex> lock(messageMutex_);
2119 xmlOut->addTextElementToData(
"last_update_count",
2120 std::to_string(messages_.back().getCount()));
2122 refreshParent_ = xmlOut->addTextElementToData(
"messages",
"");
2124 bool requestOutOfSync =
false;
2125 std::string requestOutOfSyncMsg;
2127 size_t refreshReadPointer = 0;
2128 if(lastUpdateCount != (
size_t)-1)
2130 while(refreshReadPointer < messages_.size() &&
2131 messages_[refreshReadPointer].getCount() <= lastUpdateCount)
2133 ++refreshReadPointer;
2137 if(refreshReadPointer >= messages_.size())
2141 if(messages_.size() - refreshReadPointer > maxClientMessageRequest_)
2147 refreshReadPointer = messages_.size() - maxClientMessageRequest_;
2159 xmlOut->addTextElementToData(
2160 "earliest_update_count",
2161 std::to_string(messages_[refreshReadPointer].getCount()));
2164 for(; refreshReadPointer < messages_.size(); ++refreshReadPointer)
2166 auto msg = messages_[refreshReadPointer];
2167 if(msg.getCount() < lastUpdateCount)
2169 if(!requestOutOfSync)
2171 requestOutOfSync =
true;
2172 __SS__ <<
"Request is out of sync! Message count should be more recent! "
2173 << msg.getCount() <<
" < " << lastUpdateCount << __E__;
2174 requestOutOfSyncMsg = ss.str();
2180 addMessageToResponse(xmlOut, msg);
2184 if(requestOutOfSync)
2185 __SUP_COUT__ << requestOutOfSyncMsg;
2209 void ConsoleSupervisor::prependHistoricMessages(
HttpXmlDocument* xmlOut,
2210 const size_t earliestOnhandMessageCount)
2214 if(messages_.size() == 0)
2218 if(earliestOnhandMessageCount >= messages_.back().getCount())
2221 <<
"Invalid claim from user request of earliest onhand message sequence ID = "
2222 << earliestOnhandMessageCount
2223 <<
". Latest existing sequence ID = " << messages_.back().getCount()
2224 <<
". Was the Console Supervisor restarted?" << __E__;
2230 std::lock_guard<std::mutex> lock(messageMutex_);
2232 refreshParent_ = xmlOut->addTextElementToData(
"messages",
"");
2234 size_t refreshReadPointer = 0;
2235 size_t readCountStart = earliestOnhandMessageCount - maxClientMessageRequest_;
2236 if(readCountStart >= messages_.back().getCount())
2240 while(refreshReadPointer < messages_.size() &&
2241 messages_[refreshReadPointer].getCount() < readCountStart)
2243 ++refreshReadPointer;
2246 if(refreshReadPointer >= messages_.size())
2249 xmlOut->addTextElementToData(
"earliest_update_count",
2250 std::to_string(readCountStart));
2254 for(; refreshReadPointer < messages_.size(); ++refreshReadPointer)
2256 auto msg = messages_[refreshReadPointer];
2257 if(messages_[refreshReadPointer].getCount() >= earliestOnhandMessageCount)
2260 addMessageToResponse(xmlOut, msg);
2271 for(
auto& field : msg.fields)
2273 if(field.first == ConsoleMessageStruct::FieldType::SOURCE)
2275 if(field.first == ConsoleMessageStruct::FieldType::SOURCEID)
2279 if(field.first == ConsoleMessageStruct::FieldType::TIMESTAMP)
2286 "message_" + ConsoleMessageStruct::fieldNames.at(field.first),
2299 "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)