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 and mean 'something "
276 "occurred of which you should be aware.'"
278 __COUT_WARN__ <<
"WARNING messages look like this and mean 'something "
279 "suboptimal occurred and could be fixed.'"
281 __COUT_ERR__ <<
"ERROR messages look like this and mean 'something wrong "
282 "occurred and should be fixed.'"
295 if(selfGeneratedMessageCount)
296 --selfGeneratedMessageCount;
304 std::lock_guard<std::mutex> lock(cs->messageMutex_);
308 while(c < buffer.size())
312 cs->messages_.emplace_back(&(buffer.c_str()[c]),
314 cs->priorityCustomTriggerList_);
315 if(cs->messages_.back().hasCustomTriggerMatchAction())
316 cs->customTriggerActionQueue_.push(
317 cs->messages_.back().getCustomTriggerMatch());
320 if(cs->messages_.back().getLevel() ==
"Error")
322 if(cs->errorCount_ == 0)
324 cs->firstErrorMessageTime_ = time(0);
325 cs->firstErrorMessage_ = cs->messages_.back().getMsg();
328 cs->lastErrorMessageTime_ = time(0);
330 cs->lastErrorMessage_ = cs->messages_.back().getMsg();
332 else if(cs->messages_.back().getLevel() ==
"Warning")
334 if(cs->warnCount_ == 0)
336 cs->firstWarnMessageTime_ = time(0);
337 cs->firstWarnMessage_ = cs->messages_.back().getMsg();
339 cs->lastWarnMessageTime_ = time(0);
341 cs->lastWarnMessage_ = cs->messages_.back().getMsg();
343 else if(cs->messages_.back().getLevel() ==
"Info")
345 if(cs->infoCount_ == 0)
347 cs->firstInfoMessageTime_ = time(0);
348 cs->firstInfoMessage_ = cs->messages_.back().getMsg();
350 cs->lastInfoMessageTime_ = time(0);
352 cs->lastInfoMessage_ = cs->messages_.back().getMsg();
356 newSourceId = cs->messages_.back().getSourceIDAsNumber();
357 newSequenceId = cs->messages_.back().getSequenceIDAsNumber();
364 (newSourceId != -1 &&
365 sourceLastSequenceID.find(newSourceId) !=
368 ((newSequenceId == 0 && sourceLastSequenceID[newSourceId] !=
371 sourceLastSequenceID[newSourceId] + 1))
375 std::stringstream missedSs;
376 missedSs <<
"Console missed "
377 << (newSequenceId - 1) -
378 (sourceLastSequenceID[newSourceId] + 1) + 1
379 <<
" packet(s) [" << sourceLastSequenceID[newSourceId]
380 <<
" -> " << newSequenceId <<
"] from "
381 << cs->messages_.back().getSource() <<
":" << newSourceId
382 <<
"! (uptime: " << cs->getSupervisorUptime() <<
" s)"
384 __SS__ << missedSs.str();
385 std::cout << ss.str();
389 if(cs->getSupervisorUptime() > 20 &&
390 sourceLastSequenceID[newSourceId] !=
395 cs->messages_.emplace_back(
396 CONSOLE_SPECIAL_WARNING + missedSs.str(),
398 cs->priorityCustomTriggerList_);
400 cs->messages_.back().setTime(time(0));
402 if(cs->priorityCustomTriggerList_.size())
404 cs->customTriggerActionQueue_.push(
405 cs->priorityCustomTriggerList_
407 cs->priorityCustomTriggerList_[0]
409 cs->customTriggerActionQueue_.back()
410 .triggeredMessageCountIndex =
411 cs->messages_.back().getCount();
412 cs->messages_.back().setCustomTriggerMatch(
413 cs->customTriggerActionQueue_.back());
419 sourceLastSequenceID[newSourceId] = newSequenceId;
422 while(cs->messages_.size() > 0 &&
423 cs->messages_.size() > cs->maxMessageCount_)
425 if(i < cs->maxMessageCount_ /
427 (cs->messages_[i].getLevel() ==
"Error" ||
428 cs->messages_[i].getLevel() ==
"Warning" ||
429 cs->messages_[i].getLevel() ==
"Info"))
435 cs->messages_.erase(cs->messages_.begin() + i);
438 c += strlen(&(buffer.c_str()[c])) + 1;
452 (heartbeatCount < 60 * 5 &&
453 heartbeatCount % 60 == 59))
455 ++selfGeneratedMessageCount;
456 __COUT__ <<
"Console is alive and waiting... (if no messages, next "
457 "heartbeat is in two minutes)"
460 else if(heartbeatCount % (60 * 30) == 59)
462 ++selfGeneratedMessageCount;
463 __COUT__ <<
"Console is alive and waiting a long time... (if no "
464 "messages, next heartbeat is in one hour)"
475 if(i == 120 || selfGeneratedMessageCount == 5)
478 __COUTV__(selfGeneratedMessageCount);
479 __COUT__ <<
"No messages received at Console Supervisor. Exiting Console "
480 "messageFacilityReceiverWorkLoop"
485 if(cs->customTriggerActionQueue_.size() && !cs->customTriggerActionThreadExists_)
487 cs->customTriggerActionThreadExists_ =
true;
491 ConsoleSupervisor::customTriggerActionThread(c);
500 catch(
const std::runtime_error& e)
502 __COUT_ERR__ <<
"Error caught at Console Supervisor thread: " << e.what() << __E__;
506 __COUT_ERR__ <<
"Unknown error caught at Console Supervisor thread." << __E__;
515 __COUT__ <<
"Starting customTriggerActionThread" << __E__;
516 CustomTriggeredAction_t triggeredAction;
522 std::lock_guard<std::mutex> lock(cs->messageMutex_);
523 if(cs->customTriggerActionQueue_.size())
525 triggeredAction = cs->customTriggerActionQueue_.front();
526 cs->customTriggerActionQueue_.pop();
530 if(triggeredAction.action.size())
532 __COUTS__(2) <<
"Handling action '" << triggeredAction.action
533 <<
"' on custom count search string: "
537 cs->doTriggeredAction(triggeredAction);
540 triggeredAction.action =
"";
541 triggeredAction.triggeredMessageCountIndex =
548 catch(
const std::runtime_error& e)
550 __COUT_ERR__ <<
"Error caught at Console Supervisor Action thread: " << e.what()
555 __COUT_ERR__ <<
"Unknown error caught at Console Supervisor Action thread." << __E__;
559 void ConsoleSupervisor::doTriggeredAction(
const CustomTriggeredAction_t& triggeredAction)
561 __SUP_COUT_INFO__ <<
"Launching Triggered Action '" << triggeredAction.action
562 <<
"' fired on custom count search string: "
579 __SUP_SS__ <<
"Unrecognized triggered action '" << triggeredAction.action
580 <<
",' valid actions are "
586 if(triggeredAction.action !=
"Count Only")
587 theRemoteWebUsers_.sendSystemMessage(
589 "In the Console Supervisor, a custom count fired the action '" +
590 triggeredAction.action +
"' on the search string '" +
594 if(triggeredAction.action ==
"Halt")
599 "Console-triggered FSM Halt", 0, 0);
603 theRemoteWebUsers_.sendSystemMessage(
605 "FSM Halt from Console Supervisor Triggered Action has failed!");
607 __SUP_COUTV__(
"FSM Halt triggered from console");
609 else if(triggeredAction.action ==
"Pause")
614 "Console-triggered FSM Pause", 1, 0);
618 theRemoteWebUsers_.sendSystemMessage(
620 "FSM Pause from Console Supervisor Triggered Action has failed!");
622 __SUP_COUTV__(
"FSM Pause triggered from console");
624 else if(triggeredAction.action ==
"Stop")
629 "Console-triggered FSM Stop", 0, 1);
631 catch(
const std::exception& e)
633 theRemoteWebUsers_.sendSystemMessage(
635 "FSM Stop from Console Supervisor Triggered Action has failed!");
637 __SUP_COUTV__(
"FSM Stop triggered from console");
639 else if(triggeredAction.action ==
"Run Script")
641 std::string triggerScriptPath =
"";
642 std::string scriptResult =
"";
645 triggerScriptPath = __ENV__(
"OTS_CUSTOM_TRIGGER_SCRIPT");
646 triggerScriptPath =
"source " + triggerScriptPath;
648 __COUT_INFO__ <<
"The Script " << triggerScriptPath
649 <<
" Was launched, here is the result " << scriptResult;
653 __SS__ <<
"Trigger script path not defined! Please use environment variable "
654 "'OTS_CUSTOM_TRIGGER_SCRIPT' or contact admins."
664 void ConsoleSupervisor::addCustomTriggeredAction(
const std::string& triggerNeedle,
665 const std::string& triggerAction,
667 uint32_t triggerOnCount,
671 __SUP_COUTV__(
"Adding custom triggered action");
672 __SUP_COUTV__(triggerNeedle);
673 __SUP_COUTV__(triggerAction);
674 __SUP_COUTV__(priority);
675 __SUP_COUTV__(triggerOnCount);
676 __SUP_COUTV__(doLoop);
677 __SUP_COUTV__(isArmed);
679 bool allAsterisks =
true;
680 for(
const auto& c : triggerNeedle)
683 allAsterisks =
false;
688 __SUP_SS__ <<
"Illegal empty Search String value for the new Custom Count and "
689 "Action! Please enter a valid Search String (* wildcards are "
690 "allowed, e.g. \"value = * seconds\")."
696 uint32_t currentPriority = -1;
697 for(
const auto& customTrigger : priorityCustomTriggerList_)
703 __SUP_SS__ <<
"Failure! Can not add Custom Count Search String that already "
706 <<
"' already existing at priority = " << currentPriority << __E__;
711 if(priority >= priorityCustomTriggerList_.size())
712 priority = priorityCustomTriggerList_.size();
713 if(priority == 0 && triggerNeedle != CONSOLE_MISSED_NEEDLE)
715 __SUP_SS__ <<
"Illegal priority position of '" << priority
716 <<
"' requested. Please enter a priority value greater than 0. "
717 "Position 0 is reserved for identifying missing messages at the "
718 "Console Supervisor. Note: the action for missing messages, at "
719 "priority 0, may be customized by the user."
723 __SUP_COUTV__(priority);
736 __SUP_SS__ <<
"Unrecognized triggered action '" << triggerAction
737 <<
",' valid actions are "
743 priorityCustomTriggerList_.insert(priorityCustomTriggerList_.begin() + priority,
744 CustomTriggeredAction_t());
751 priorityCustomTriggerList_[priority].needleSubstrings,
754 priorityCustomTriggerList_[priority].action = triggerAction;
755 priorityCustomTriggerList_[priority].triggerOnCount = triggerOnCount;
756 priorityCustomTriggerList_[priority].doLoop = doLoop;
757 priorityCustomTriggerList_[priority].isArmed = isArmed;
759 __SUP_COUT__ <<
"Added custom count: '"
761 priorityCustomTriggerList_[priority].needleSubstrings,
"*")
762 <<
"' at priority: " << priority
763 <<
" triggered every: " << triggerOnCount <<
" occurrences";
765 __SUP_COUT__ <<
" and will loop.";
767 __SUP_COUT__ <<
" and will not loop.";
768 __SUP_COUT__ << __E__;
776 uint32_t ConsoleSupervisor::modifyCustomTriggeredAction(
const std::string& currentNeedle,
777 const std::string& modifyType,
778 const std::string& setNeedle,
779 const std::string& setAction,
780 uint32_t setPriority,
781 uint32_t setTriggerOnCount,
785 __SUP_COUTV__(currentNeedle);
786 __SUP_COUTV__(modifyType);
787 __SUP_COUTV__(setNeedle);
788 __SUP_COUTV__(setAction);
789 __SUP_COUTV__(setPriority);
790 __SUP_COUTV__(setTriggerOnCount);
791 __SUP_COUTV__(setDoLoop);
792 __SUP_COUTV__(setIsArmed);
795 uint32_t currentPriority = -1;
797 for(
const auto& customTrigger : priorityCustomTriggerList_)
808 __SUP_COUTV__(currentPriority);
811 __SUP_SS__ <<
"Attempt to modify Custom Count Search String failed. Could not "
812 "find specified Search String '"
813 << currentNeedle <<
"' in prioritized list." << __E__;
817 if(modifyType ==
"Deletion")
819 if(currentPriority == 0)
821 __SUP_SS__ <<
"Illegal deletion requested of priority position 0. Position 0 "
822 "is reserved for identifying missing messages at the Console "
823 "Supervisor. Note: the action of priority 0 may be customized "
824 "by the user, but it can not be deleted."
829 __SUP_COUT__ <<
"Deleting custom count: "
831 priorityCustomTriggerList_[currentPriority].needleSubstrings,
834 << priorityCustomTriggerList_[currentPriority].action
835 <<
" and priority: " << currentPriority << __E__;
836 priorityCustomTriggerList_.erase(priorityCustomTriggerList_.begin() +
841 if(modifyType ==
"Priority" || modifyType ==
"All")
843 if(setPriority >= priorityCustomTriggerList_.size())
844 setPriority = priorityCustomTriggerList_.size();
845 if(setPriority == 0 && setNeedle != CONSOLE_MISSED_NEEDLE)
847 __SUP_SS__ <<
"Illegal priority position of '" << setPriority
848 <<
"' requested. Position 0 is reserved for identifying missing "
849 "messages at the Console Supervisor. Note: the action of "
850 "priority 0 may be customized by the user."
856 setPriority = currentPriority;
858 if(modifyType ==
"Action" || modifyType ==
"All")
870 __SUP_SS__ <<
"Unrecognized custom count action '" << setAction
871 <<
",' valid actions are "
876 priorityCustomTriggerList_[currentPriority].action = setAction;
879 if(modifyType ==
"Search String" || modifyType ==
"All")
882 priorityCustomTriggerList_[currentPriority].needleSubstrings.clear();
885 priorityCustomTriggerList_[currentPriority].needleSubstrings,
890 if(modifyType ==
"Trigger on Count" || modifyType ==
"All")
893 priorityCustomTriggerList_[currentPriority].triggerOnCount = setTriggerOnCount;
895 if(modifyType ==
"Do Loop" || modifyType ==
"All")
898 priorityCustomTriggerList_[currentPriority].doLoop = setDoLoop;
900 if(modifyType ==
"Arm Trigger" || modifyType ==
"All")
903 priorityCustomTriggerList_[currentPriority].isArmed = setIsArmed;
906 if(currentPriority != setPriority)
909 priorityCustomTriggerList_.insert(
910 priorityCustomTriggerList_.begin() + setPriority,
911 priorityCustomTriggerList_[currentPriority]);
914 if(currentPriority >= setPriority)
917 priorityCustomTriggerList_.erase(priorityCustomTriggerList_.begin() +
920 if(currentPriority < setPriority)
924 __SUP_COUT__ <<
"Modified '" << modifyType <<
"' custom count: "
926 priorityCustomTriggerList_[setPriority].needleSubstrings, {
'*'})
927 <<
" now w/action: " << priorityCustomTriggerList_[setPriority].action
928 <<
" and at priority: " << setPriority << __E__;
934 void ConsoleSupervisor::loadCustomCountList()
937 __SUP_COUT__ <<
"loadCustomCountList() from "
938 << USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME << __E__;
940 FILE* fp = fopen((USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME).c_str(),
"r");
943 __SUP_COUT__ <<
"Ignoring missing Custom Count list file at path: "
944 << (USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME) << __E__;
947 priorityCustomTriggerList_.clear();
954 size_t triggerOnCount = 0;
956 bool isArmed =
false;
957 while(fgets(line, 1000, fp))
963 line[strlen(line) - 1] =
'\0';
973 priority = std::stoi(line);
975 triggerOnCount = std::stoi(line);
977 doLoop = std::stoi(line) > 0 ? true :
false;
980 isArmed = std::stoi(line) > 0 ? true :
false;
981 __SUP_COUTTV__(needle);
982 __SUP_COUTTV__(priority);
983 __SUP_COUTTV__(action);
984 __SUP_COUTTV__(triggerOnCount);
985 __SUP_COUTTV__(doLoop);
986 __SUP_COUTTV__(isArmed);
989 CONSOLE_MISSED_NEEDLE)
990 addCustomTriggeredAction(
991 CONSOLE_MISSED_NEEDLE,
"System Message", 0, 1,
false,
true);
992 addCustomTriggeredAction(
993 needle, action, priority, triggerOnCount, doLoop, isArmed);
1002 void ConsoleSupervisor::saveCustomCountList()
1004 __SUP_COUT__ <<
"saveCustomCountList()" << __E__;
1006 FILE* fp = fopen((USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME).c_str(),
"w");
1009 __SUP_SS__ <<
"Failed to create Custom Count list file at path: "
1010 << (USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME) << __E__;
1013 unsigned int priority = 0;
1014 for(
auto& customCount : priorityCustomTriggerList_)
1019 fprintf(fp,
"%s\n", customCount.action.c_str());
1020 fprintf(fp,
"%d\n", priority);
1021 fprintf(fp,
"%zu\n", customCount.triggerOnCount);
1022 fprintf(fp,
"%s\n", customCount.doLoop ?
"1" :
"0");
1023 fprintf(fp,
"%s\n", customCount.isArmed ?
"1" :
"0");
1030 void ConsoleSupervisor::defaultPage(xgi::Input* , xgi::Output* out)
1034 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
1035 "src='/WebPath/html/Console.html?urn="
1036 << getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
1044 CorePropertySupervisorBase::setSupervisorProperty(
1045 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
1054 cgicc::Cgicc& cgiIn,
1056 const WebUsers::RequestUserInfo& userInfo)
1079 if(requestType ==
"GetConsoleMsgs")
1084 if(lastUpdateCountStr ==
"")
1086 __SUP_COUT_ERR__ <<
"Invalid Parameters! lastUpdateCount="
1087 << lastUpdateCountStr << __E__;
1088 xmlOut.addTextElementToData(
"Error",
1089 "Error - Invalid parameters for GetConsoleMsgs.");
1093 size_t lastUpdateCount = std::stoull(lastUpdateCountStr);
1097 insertMessageRefresh(&xmlOut, lastUpdateCount);
1099 else if(requestType ==
"PrependHistoricMessages")
1101 size_t earliestOnhandMessageCount =
1102 CgiDataUtilities::postDataAsInt(cgiIn,
"earlyCount");
1103 __SUP_COUTV__(earliestOnhandMessageCount);
1104 prependHistoricMessages(&xmlOut, earliestOnhandMessageCount);
1106 else if(requestType ==
"SaveUserPreferences")
1108 int colorIndex = CgiDataUtilities::postDataAsInt(cgiIn,
"colorIndex");
1109 int showSideBar = CgiDataUtilities::postDataAsInt(cgiIn,
"showSideBar");
1110 int noWrap = CgiDataUtilities::postDataAsInt(cgiIn,
"noWrap");
1111 int messageOnly = CgiDataUtilities::postDataAsInt(cgiIn,
"messageOnly");
1112 int hideLineNumers = CgiDataUtilities::postDataAsInt(cgiIn,
"hideLineNumers");
1121 if(userInfo.username_ ==
"")
1123 __SUP_COUT_ERR__ <<
"Invalid user found! user=" << userInfo.username_
1125 xmlOut.addTextElementToData(
"Error",
1126 "Error - InvauserInfo.username_user found.");
1130 std::string fn = (std::string)USER_CONSOLE_PREF_PATH + userInfo.username_ +
"." +
1131 (std::string)USERS_PREFERENCES_FILETYPE;
1134 FILE* fp = fopen(fn.c_str(),
"w");
1138 __THROW__(ss.str() +
"Could not open file: " + fn);
1140 fprintf(fp,
"colorIndex %d\n", colorIndex);
1141 fprintf(fp,
"showSideBar %d\n", showSideBar);
1142 fprintf(fp,
"noWrap %d\n", noWrap);
1143 fprintf(fp,
"messageOnly %d\n", messageOnly);
1144 fprintf(fp,
"hideLineNumers %d\n", hideLineNumers);
1147 else if(requestType ==
"LoadUserPreferences")
1151 unsigned int colorIndex, showSideBar, noWrap, messageOnly, hideLineNumers;
1153 if(userInfo.username_ ==
"")
1155 __SUP_COUT_ERR__ <<
"Invalid user found! user=" << userInfo.username_
1157 xmlOut.addTextElementToData(
"Error",
"Error - Invalid user found.");
1161 std::string fn = (std::string)USER_CONSOLE_PREF_PATH + userInfo.username_ +
"." +
1162 (std::string)USERS_PREFERENCES_FILETYPE;
1166 FILE* fp = fopen(fn.c_str(),
"r");
1170 __SUP_COUT__ <<
"Returning defaults." << __E__;
1171 xmlOut.addTextElementToData(
"colorIndex",
"0");
1172 xmlOut.addTextElementToData(
"showSideBar",
"0");
1173 xmlOut.addTextElementToData(
"noWrap",
"1");
1174 xmlOut.addTextElementToData(
"messageOnly",
"0");
1175 xmlOut.addTextElementToData(
"hideLineNumers",
"1");
1178 fscanf(fp,
"%*s %u", &colorIndex);
1179 fscanf(fp,
"%*s %u", &showSideBar);
1180 fscanf(fp,
"%*s %u", &noWrap);
1181 fscanf(fp,
"%*s %u", &messageOnly);
1182 fscanf(fp,
"%*s %u", &hideLineNumers);
1191 sprintf(tmpStr,
"%u", colorIndex);
1192 xmlOut.addTextElementToData(
"colorIndex", tmpStr);
1193 sprintf(tmpStr,
"%u", showSideBar);
1194 xmlOut.addTextElementToData(
"showSideBar", tmpStr);
1195 sprintf(tmpStr,
"%u", noWrap);
1196 xmlOut.addTextElementToData(
"noWrap", tmpStr);
1197 sprintf(tmpStr,
"%u", messageOnly);
1198 xmlOut.addTextElementToData(
"messageOnly", tmpStr);
1199 sprintf(tmpStr,
"%u", hideLineNumers);
1200 xmlOut.addTextElementToData(
"hideLineNumers", tmpStr);
1202 else if(requestType ==
"GetTraceLevels")
1204 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1207 txParameters.
addParameter(
"Request",
"GetTraceLevels");
1215 traceMapToXDAQHostname_.clear();
1217 std::string traceList =
"";
1218 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1219 for(
const auto& appInfo : allTraceApps)
1221 __SUP_COUT__ <<
"Supervisor hostname = " << appInfo.first <<
"/"
1222 << appInfo.second.getId()
1223 <<
" name = " << appInfo.second.getName()
1224 <<
" class = " << appInfo.second.getClass()
1225 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1228 xoap::MessageReference retMsg =
1229 SOAPMessenger::sendWithSOAPReply(appInfo.second.getDescriptor(),
1230 "TRACESupervisorRequest",
1232 SOAPUtilities::receive(retMsg, rxParameters);
1233 __SUP_COUT__ <<
"Received TRACE response: "
1234 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1235 << SOAPUtilities::translate(retMsg) << __E__;
1237 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1239 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1241 << appInfo.first <<
"/" << appInfo.second.getId()
1242 <<
" name = " << appInfo.second.getName()
1243 <<
" class = " << appInfo.second.getClass()
1244 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1247 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1249 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1254 catch(
const xdaq::exception::Exception& e)
1256 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1257 << appInfo.second.getId()
1258 <<
" name = " << appInfo.second.getName() <<
". \n\n"
1259 << e.what() << __E__;
1262 __SUP_COUT_ERR__ << ss.str();
1266 std::vector<std::string> traceHostnameArr;
1267 __COUTTV__(rxParameters.getValue(
"TRACEHostnameList"));
1269 rxParameters.getValue(
"TRACEHostnameList"), traceHostnameArr, {
';'});
1270 for(
const auto& traceHostname : traceHostnameArr)
1272 if(traceHostname ==
"")
1274 traceMapToXDAQHostname_[traceHostname] = appInfo.first;
1282 __COUTTV__(rxParameters.getValue(
"TRACEList"));
1283 traceList += rxParameters.getValue(
"TRACEList");
1286 __SUP_COUT__ <<
"TRACE hostname map received: \n"
1288 __SUP_COUT__ <<
"TRACE List received: \n" << traceList << __E__;
1289 xmlOut.addTextElementToData(
"traceList", traceList);
1291 else if(requestType ==
"SetTraceLevels")
1293 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1295 std::string individualValues =
1302 __SUP_COUTV__(individualValues);
1303 __SUP_COUTV__(setMode);
1305 __SUP_COUTV__(setValueMSB);
1306 __SUP_COUTV__(setValueLSB);
1308 std::map<std::string , std::string > hostToLabelMap;
1310 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1317 std::string modifiedTraceList =
"";
1318 std::string xdaqHostname;
1320 for(
auto& hostLabelsPair : hostToLabelMap)
1324 __SUP_COUTV__(hostLabelsPair.first);
1325 __SUP_COUTV__(hostLabelsPair.second);
1330 xdaqHostname = traceMapToXDAQHostname_.at(hostLabelsPair.first);
1334 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1335 << hostLabelsPair.first <<
"' to xdaq Context hostname."
1337 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1343 __SUP_COUTV__(xdaqHostname);
1345 auto& appInfo = allTraceApps.at(xdaqHostname);
1346 __SUP_COUT__ <<
"Supervisor hostname = " << hostLabelsPair.first <<
"/"
1347 << xdaqHostname <<
":" << appInfo.getId()
1348 <<
" name = " << appInfo.getName()
1349 <<
" class = " << appInfo.getClass()
1350 <<
" hostname = " << appInfo.getHostname() << __E__;
1354 txParameters.
addParameter(
"Request",
"SetTraceLevels");
1355 txParameters.
addParameter(
"IndividualValues", individualValues);
1356 txParameters.
addParameter(
"Host", hostLabelsPair.first);
1358 txParameters.
addParameter(
"Labels", hostLabelsPair.second);
1362 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1363 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1364 SOAPUtilities::receive(retMsg, rxParameters);
1365 __SUP_COUT__ <<
"Received TRACE response: "
1366 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1367 << SOAPUtilities::translate(retMsg) << __E__;
1369 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1371 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1373 << hostLabelsPair.first <<
"/" << appInfo.getId()
1374 <<
" name = " << appInfo.getName()
1375 <<
" class = " << appInfo.getClass()
1376 <<
" hostname = " << appInfo.getHostname() << __E__;
1379 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1381 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1386 catch(
const xdaq::exception::Exception& e)
1388 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1389 << appInfo.getId() <<
" name = " << appInfo.getName()
1391 << e.what() << __E__;
1395 modifiedTraceList +=
1396 ";" + hostLabelsPair.first;
1400 modifiedTraceList += rxParameters.getValue(
"TRACEList");
1404 __SUP_COUT__ <<
"mod'd TRACE List received: \n" << modifiedTraceList << __E__;
1405 xmlOut.addTextElementToData(
"modTraceList", modifiedTraceList);
1407 else if(requestType ==
"GetTriggerStatus")
1409 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1411 txParameters.
addParameter(
"Request",
"GetTriggerStatus");
1418 std::string traceTriggerStatus =
"";
1419 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1420 for(
const auto& appInfo : allTraceApps)
1422 __SUP_COUT__ <<
"Supervisor hostname = " << appInfo.first <<
"/"
1423 << appInfo.second.getId()
1424 <<
" name = " << appInfo.second.getName()
1425 <<
" class = " << appInfo.second.getClass()
1426 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1429 xoap::MessageReference retMsg =
1430 SOAPMessenger::sendWithSOAPReply(appInfo.second.getDescriptor(),
1431 "TRACESupervisorRequest",
1433 SOAPUtilities::receive(retMsg, rxParameters);
1434 __SUP_COUT__ <<
"Received TRACE response: "
1435 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1436 << SOAPUtilities::translate(retMsg) << __E__;
1438 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1440 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1442 << appInfo.first <<
"/" << appInfo.second.getId()
1443 <<
" name = " << appInfo.second.getName()
1444 <<
" class = " << appInfo.second.getClass()
1445 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1448 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1450 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1455 catch(
const xdaq::exception::Exception& e)
1457 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1458 << appInfo.second.getId()
1459 <<
" name = " << appInfo.second.getName() <<
". \n\n"
1460 << e.what() << __E__;
1464 traceTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1467 __SUP_COUT__ <<
"TRACE Trigger Status received: \n"
1468 << traceTriggerStatus << __E__;
1469 xmlOut.addTextElementToData(
"traceTriggerStatus", traceTriggerStatus);
1471 else if(requestType ==
"SetTriggerEnable")
1473 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1477 __SUP_COUTV__(hostList);
1479 std::vector<std::string > hosts;
1481 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1488 std::string modifiedTriggerStatus =
"";
1489 std::string xdaqHostname;
1491 for(
auto& host : hosts)
1495 __SUP_COUTV__(host);
1502 xdaqHostname = traceMapToXDAQHostname_.at(host);
1506 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1507 << host <<
"' to xdaq Context hostname." << __E__;
1508 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1514 __SUP_COUTV__(xdaqHostname);
1516 auto& appInfo = allTraceApps.at(xdaqHostname);
1517 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1518 << appInfo.getId() <<
" name = " << appInfo.getName()
1519 <<
" class = " << appInfo.getClass()
1520 <<
" hostname = " << appInfo.getHostname() << __E__;
1524 txParameters.
addParameter(
"Request",
"SetTriggerEnable");
1527 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1528 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1529 SOAPUtilities::receive(retMsg, rxParameters);
1530 __SUP_COUT__ <<
"Received TRACE response: "
1531 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1532 << SOAPUtilities::translate(retMsg) << __E__;
1534 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1536 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1538 << host <<
"/" << appInfo.getId()
1539 <<
" name = " << appInfo.getName()
1540 <<
" class = " << appInfo.getClass()
1541 <<
" hostname = " << appInfo.getHostname() << __E__;
1544 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1546 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1551 catch(
const xdaq::exception::Exception& e)
1553 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1554 << appInfo.getId() <<
" name = " << appInfo.getName()
1556 << e.what() << __E__;
1560 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1563 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1564 << modifiedTriggerStatus << __E__;
1565 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1567 else if(requestType ==
"ResetTRACE")
1569 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1573 __SUP_COUTV__(hostList);
1575 std::vector<std::string > hosts;
1577 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1584 std::string modifiedTriggerStatus =
"";
1585 std::string xdaqHostname;
1587 for(
auto& host : hosts)
1591 __SUP_COUTV__(host);
1598 xdaqHostname = traceMapToXDAQHostname_.at(host);
1602 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1603 << host <<
"' to xdaq Context hostname." << __E__;
1604 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1610 __SUP_COUTV__(xdaqHostname);
1612 auto& appInfo = allTraceApps.at(xdaqHostname);
1613 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1614 << appInfo.getId() <<
" name = " << appInfo.getName()
1615 <<
" class = " << appInfo.getClass()
1616 <<
" hostname = " << appInfo.getHostname() << __E__;
1623 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1624 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1625 SOAPUtilities::receive(retMsg, rxParameters);
1626 __SUP_COUT__ <<
"Received TRACE response: "
1627 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1628 << SOAPUtilities::translate(retMsg) << __E__;
1630 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1632 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1634 << host <<
"/" << appInfo.getId()
1635 <<
" name = " << appInfo.getName()
1636 <<
" class = " << appInfo.getClass()
1637 <<
" hostname = " << appInfo.getHostname() << __E__;
1640 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1642 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1647 catch(
const xdaq::exception::Exception& e)
1649 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1650 << appInfo.getId() <<
" name = " << appInfo.getName()
1652 << e.what() << __E__;
1656 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1659 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1660 << modifiedTriggerStatus << __E__;
1661 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1663 else if(requestType ==
"EnableTRACE")
1665 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1670 __SUP_COUTV__(hostList);
1671 __SUP_COUTV__(enable);
1673 std::vector<std::string > hosts;
1675 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1682 std::string modifiedTriggerStatus =
"";
1683 std::string xdaqHostname;
1685 for(
auto& host : hosts)
1689 __SUP_COUTV__(host);
1696 xdaqHostname = traceMapToXDAQHostname_.at(host);
1700 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1701 << host <<
"' to xdaq Context hostname." << __E__;
1702 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1708 __SUP_COUTV__(xdaqHostname);
1710 auto& appInfo = allTraceApps.at(xdaqHostname);
1711 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1712 << appInfo.getId() <<
" name = " << appInfo.getName()
1713 <<
" class = " << appInfo.getClass()
1714 <<
" hostname = " << appInfo.getHostname() << __E__;
1722 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1723 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1724 SOAPUtilities::receive(retMsg, rxParameters);
1725 __SUP_COUT__ <<
"Received TRACE response: "
1726 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1727 << SOAPUtilities::translate(retMsg) << __E__;
1729 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1731 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1733 << host <<
"/" << appInfo.getId()
1734 <<
" name = " << appInfo.getName()
1735 <<
" class = " << appInfo.getClass()
1736 <<
" hostname = " << appInfo.getHostname() << __E__;
1739 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1741 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1746 catch(
const xdaq::exception::Exception& e)
1748 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1749 << appInfo.getId() <<
" name = " << appInfo.getName()
1751 << e.what() << __E__;
1755 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1758 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1759 << modifiedTriggerStatus << __E__;
1760 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1762 else if(requestType ==
"GetTraceSnapshot")
1764 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1770 __SUP_COUTV__(hostList);
1771 __SUP_COUTV__(filterFor);
1772 __SUP_COUTV__(filterOut);
1774 std::vector<std::string > hosts;
1776 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1784 std::string modifiedTriggerStatus =
"";
1785 std::string xdaqHostname;
1787 for(
auto& host : hosts)
1791 __SUP_COUTV__(host);
1798 xdaqHostname = traceMapToXDAQHostname_.at(host);
1802 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1803 << host <<
"' to xdaq Context hostname." << __E__;
1804 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1810 __SUP_COUTV__(xdaqHostname);
1812 auto& appInfo = allTraceApps.at(xdaqHostname);
1813 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1814 << appInfo.getId() <<
" name = " << appInfo.getName()
1815 <<
" class = " << appInfo.getClass()
1816 <<
" hostname = " << appInfo.getHostname() << __E__;
1825 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1826 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1827 SOAPUtilities::receive(retMsg, rxParameters);
1828 __SUP_COUT__ <<
"Received TRACE response: "
1829 << SOAPUtilities::translate(retMsg).getCommand() << __E__;
1832 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1834 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1836 << host <<
"/" << appInfo.getId()
1837 <<
" name = " << appInfo.getName()
1838 <<
" class = " << appInfo.getClass()
1839 <<
" hostname = " << appInfo.getHostname() << __E__;
1842 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1844 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1849 catch(
const xdaq::exception::Exception& e)
1851 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1852 << appInfo.getId() <<
" name = " << appInfo.getName()
1854 << e.what() << __E__;
1858 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1859 xmlOut.addTextElementToData(
"host", host);
1860 std::string snapshot = rxParameters.getValue(
"TRACESnapshot");
1869 std::string filename =
1870 USER_CONSOLE_SNAPSHOT_PATH +
"snapshot_" + host +
".txt";
1871 __SUP_COUTV__(filename);
1872 FILE* fp = fopen(filename.c_str(),
"w");
1875 __SUP_SS__ <<
"Failed to create snapshot file: " << filename << __E__;
1879 "TRACE Snapshot taken at %s\n",
1882 if(snapshot.size() > 5 && snapshot[2] !=
'i')
1887 " idx us_tod delta pid tid cpu "
1888 " trcname lvl r msg \n");
1890 "----- ---------------- ----------- ------ ------ --- "
1891 "-------------------------------------- --- - "
1892 "--------------------------\n");
1894 fprintf(fp,
"%s", snapshot.c_str());
1899 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1900 << modifiedTriggerStatus << __E__;
1901 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1903 else if(requestType ==
"GetCustomCountsAndActions" ||
1904 requestType ==
"AddCustomCountsAndAction" ||
1905 requestType ==
"ModifyCustomCountsAndAction")
1907 __SUP_COUT__ <<
"requestType " << requestType
1908 <<
" size=" << priorityCustomTriggerList_.size() << __E__;
1913 std::lock_guard<std::mutex> lock(messageMutex_);
1915 if(requestType ==
"AddCustomCountsAndAction" ||
1916 requestType ==
"ModifyCustomCountsAndAction")
1920 uint32_t priority = CgiDataUtilities::postDataAsInt(cgiIn,
"priority");
1923 uint32_t triggerOnCount =
1924 CgiDataUtilities::postDataAsInt(cgiIn,
"triggerOnCount");
1926 CgiDataUtilities::postDataAsInt(cgiIn,
"doLoop") > 0 ? true :
false;
1928 CgiDataUtilities::postDataAsInt(cgiIn,
"isArmed") > 0 ? true :
false;
1930 __SUP_COUTV__(needle);
1931 __SUP_COUTV__(priority);
1932 __SUP_COUTV__(action);
1933 __SUP_COUTV__(triggerOnCount);
1934 __SUP_COUTV__(doLoop);
1935 __SUP_COUTV__(isArmed);
1937 if(requestType ==
"ModifyCustomCountsAndAction")
1941 std::string currentNeedle =
1945 std::vector<std::string> csvNeedles =
1947 for(
size_t i = csvNeedles.size() - 1; i < csvNeedles.size(); --i)
1949 if(csvNeedles[i].size() == 0)
1952 priority = modifyCustomTriggeredAction(
1964 addCustomTriggeredAction(
1965 needle, action, priority, triggerOnCount, doLoop, isArmed);
1967 saveCustomCountList();
1971 size_t untriggeredCount =
1974 for(
const auto& customCount : priorityCustomTriggerList_)
1976 xercesc::DOMElement* customCountParent =
1977 xmlOut.addTextElementToData(
"customCount",
"");
1979 if(customCount.occurrences < untriggeredCount)
1980 untriggeredCount -= customCount.occurrences;
1983 __SUP_SS__ <<
"Impossible custom count; notify admins! "
1984 << customCount.occurrences <<
" > " << untriggeredCount
1996 "count", std::to_string(customCount.occurrences), customCountParent);
1998 "action", customCount.action, customCountParent);
2000 std::to_string(customCount.triggerOnCount),
2003 "doLoop", std::to_string(customCount.doLoop), customCountParent);
2005 "isArmed", std::to_string(customCount.isArmed), customCountParent);
2009 xercesc::DOMElement* customCountParent =
2010 xmlOut.addTextElementToData(
"customCount",
"");
2013 "count", std::to_string(untriggeredCount), customCountParent);
2021 __SUP_SS__ <<
"requestType Request, " << requestType
2022 <<
", not recognized by the Console Supervisor (was it intended for "
2023 "another Supervisor?)."
2038 std::stringstream ss;
2041 CorePropertySupervisorBase::getSupervisorUptime()));
2049 ss <<
", Errors: " << errorCount_;
2050 ss <<
", Warns: " << warnCount_;
2051 ss <<
", Last Error ("
2055 << (lastErrorMessageTime_ ? StringMacros::encodeURIComponent(lastErrorMessage_)
2057 ss <<
", Last Warn ("
2061 << (lastWarnMessageTime_ ? StringMacros::encodeURIComponent(lastWarnMessage_)
2063 ss <<
", Last Info ("
2067 << (lastInfoMessageTime_ ? StringMacros::encodeURIComponent(lastInfoMessage_)
2069 ss <<
", Info #: " << infoCount_;
2070 ss <<
", First Error ("
2071 << (firstErrorMessageTime_
2075 << (firstErrorMessageTime_ ? StringMacros::encodeURIComponent(firstErrorMessage_)
2077 ss <<
", First Warn ("
2081 << (firstWarnMessageTime_ ? StringMacros::encodeURIComponent(firstWarnMessage_)
2083 ss <<
", First Info ("
2087 << (firstInfoMessageTime_ ? StringMacros::encodeURIComponent(firstInfoMessage_)
2117 const size_t lastUpdateCount)
2121 if(messages_.size() == 0)
2125 if(lastUpdateCount > messages_.back().getCount() && lastUpdateCount != (
size_t)-1)
2127 __SS__ <<
"Invalid lastUpdateCount: " << lastUpdateCount
2128 <<
" messagesArray size = " << messages_.back().getCount() << __E__;
2134 std::lock_guard<std::mutex> lock(messageMutex_);
2136 xmlOut->addTextElementToData(
"last_update_count",
2137 std::to_string(messages_.back().getCount()));
2139 refreshParent_ = xmlOut->addTextElementToData(
"messages",
"");
2141 bool requestOutOfSync =
false;
2142 std::string requestOutOfSyncMsg;
2144 size_t refreshReadPointer = 0;
2145 if(lastUpdateCount != (
size_t)-1)
2147 while(refreshReadPointer < messages_.size() &&
2148 messages_[refreshReadPointer].getCount() <= lastUpdateCount)
2150 ++refreshReadPointer;
2154 if(refreshReadPointer >= messages_.size())
2158 if(messages_.size() - refreshReadPointer > maxClientMessageRequest_)
2164 refreshReadPointer = messages_.size() - maxClientMessageRequest_;
2176 xmlOut->addTextElementToData(
2177 "earliest_update_count",
2178 std::to_string(messages_[refreshReadPointer].getCount()));
2180 std::string messagesJson =
"[";
2183 for(; refreshReadPointer < messages_.size(); ++refreshReadPointer)
2185 auto msg = messages_[refreshReadPointer];
2186 if(msg.getCount() < lastUpdateCount)
2188 if(!requestOutOfSync)
2190 requestOutOfSync =
true;
2191 __SS__ <<
"Request is out of sync! Message count should be more recent! "
2192 << msg.getCount() <<
" < " << lastUpdateCount << __E__;
2193 requestOutOfSyncMsg = ss.str();
2200 addMessageToResponse(messagesJson, msg);
2201 __COUTTV__(messagesJson.size());
2205 messagesJson +=
"]";
2209 if(requestOutOfSync)
2210 __SUP_COUT__ << requestOutOfSyncMsg;
2234 void ConsoleSupervisor::prependHistoricMessages(
HttpXmlDocument* xmlOut,
2235 const size_t earliestOnhandMessageCount)
2239 if(messages_.size() == 0)
2243 if(earliestOnhandMessageCount >= messages_.back().getCount())
2246 <<
"Invalid claim from user request of earliest onhand message sequence ID = "
2247 << earliestOnhandMessageCount
2248 <<
". Latest existing sequence ID = " << messages_.back().getCount()
2249 <<
". Was the Console Supervisor restarted?" << __E__;
2255 std::lock_guard<std::mutex> lock(messageMutex_);
2257 refreshParent_ = xmlOut->addTextElementToData(
"messages",
"");
2259 size_t refreshReadPointer = 0;
2260 size_t readCountStart = earliestOnhandMessageCount - maxClientMessageRequest_;
2261 if(readCountStart >= messages_.back().getCount())
2265 while(refreshReadPointer < messages_.size() &&
2266 messages_[refreshReadPointer].getCount() < readCountStart)
2268 ++refreshReadPointer;
2271 if(refreshReadPointer >= messages_.size())
2274 xmlOut->addTextElementToData(
"earliest_update_count",
2275 std::to_string(readCountStart));
2277 std::string messagesJson =
"[";
2281 for(; refreshReadPointer < messages_.size(); ++refreshReadPointer)
2283 auto msg = messages_[refreshReadPointer];
2284 if(messages_[refreshReadPointer].getCount() >= earliestOnhandMessageCount)
2287 addMessageToResponse(messagesJson, msg);
2291 messagesJson +=
"]";
2302 for(
auto& field : msg.fields)
2304 if(field.first == ConsoleMessageStruct::FieldType::SOURCE)
2306 if(field.first == ConsoleMessageStruct::FieldType::SOURCEID)
2310 if(field.first == ConsoleMessageStruct::FieldType::TIMESTAMP)
2317 "message_" + ConsoleMessageStruct::fieldNames.at(field.first),
2330 "message_Count", std::to_string(msg.getCount()), refreshParent_);
2342 void ConsoleSupervisor::addMessageToResponse(std::string& xmlValue,
2345 if(xmlValue.size() &&
2346 xmlValue[xmlValue.size() - 1] !=
'[')
2351 for(
auto& field : msg.fields)
2353 if(field.first == ConsoleMessageStruct::FieldType::SOURCE)
2355 if(field.first == ConsoleMessageStruct::FieldType::SOURCEID)
2359 if(field.first == ConsoleMessageStruct::FieldType::TIMESTAMP)
2366 ConsoleMessageStruct::FieldType::MSG)
2367 xmlValue +=
"\"" + ConsoleMessageStruct::fieldNames.at(field.first) +
2370 xmlValue +=
"\"" + ConsoleMessageStruct::fieldNames.at(field.first) +
2371 "\":\"" + field.second +
"\",";
2380 xmlValue +=
"\"Level\":\"" + msg.getLevel() +
"\",";
2384 xmlValue +=
"\"Time\":\"" + msg.getTime() +
"\",";
2388 xmlValue +=
"\"Count\":\"" + std::to_string(msg.getCount()) +
"\",";
2392 xmlValue +=
"\"Custom\":\"" +
2394 msg.getCustomTriggerMatch().needleSubstrings, {
'*'})) +
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 escapeString(std::string inString, bool allowWhiteSpace=false)
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)