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)"
60 const std::string ConsoleSupervisor::ConsoleMessageStruct::LABEL_TRACE =
"TRACE";
61 const std::string ConsoleSupervisor::ConsoleMessageStruct::LABEL_TRACE_PLUS =
"TRACE+";
64 ConsoleSupervisor::ConsoleMessageStruct::fieldNames({
65 {FieldType::TIMESTAMP,
"Timestamp"},
66 {FieldType::SEQID,
"SequenceID"},
67 {FieldType::LEVEL,
"Level"},
68 {FieldType::LABEL,
"Label"},
69 {FieldType::SOURCEID,
"SourceID"},
70 {FieldType::HOSTNAME,
"Hostname"},
71 {FieldType::SOURCE,
"Source"},
72 {FieldType::FILE,
"File"},
73 {FieldType::LINE,
"Line"},
74 {FieldType::MSG,
"Msg"},
78 ConsoleSupervisor::ConsoleSupervisor(xdaq::ApplicationStub* stub)
79 : CoreSupervisorBase(stub)
81 , maxMessageCount_(100000)
82 , maxClientMessageRequest_(500)
84 __SUP_COUT__ <<
"Constructor started." << __E__;
89 mkdir(((std::string)USER_CONSOLE_PREF_PATH).c_str(), 0755);
90 mkdir(((std::string)USER_CONSOLE_SNAPSHOT_PATH).c_str(), 0755);
93 this, &ConsoleSupervisor::resetConsoleCounts,
"ResetConsoleCounts", XDAQ_NS_URI);
105 loadCustomCountList();
106 if(priorityCustomTriggerList_.size() ==
109 addCustomTriggeredAction(CONSOLE_MISSED_NEEDLE,
"System Message");
116 __SUP_COUT__ <<
"Constructor complete." << __E__;
121 ConsoleSupervisor::~ConsoleSupervisor(
void) { destroy(); }
123 void ConsoleSupervisor::init(
void)
128 ConsoleSupervisor::messageFacilityReceiverWorkLoop(cs);
135 void ConsoleSupervisor::destroy(
void)
141 xoap::MessageReference ConsoleSupervisor::resetConsoleCounts(
142 xoap::MessageReference )
144 __COUT_INFO__ <<
"Resetting Console Error/Warn/Info counts and preparing for new "
150 std::lock_guard<std::mutex> lock(messageMutex_);
152 firstErrorMessageTime_ = 0;
153 lastErrorMessageTime_ = 0;
155 firstWarnMessageTime_ = 0;
156 lastWarnMessageTime_ = 0;
158 firstInfoMessageTime_ = 0;
159 lastInfoMessageTime_ = 0;
161 return SOAPUtilities::makeSOAPMessageReference(
"Done");
171 __COUT__ <<
"Starting workloop based on config file: " << QUIET_CFG_FILE << __E__;
173 std::string configFile = QUIET_CFG_FILE;
174 FILE* fp = fopen(configFile.c_str(),
"r");
177 __SS__ <<
"File with port info could not be loaded: " << QUIET_CFG_FILE << __E__;
178 __COUT__ <<
"\n" << ss.str();
185 sscanf(tmp,
"%*s %d", &myport);
189 sscanf(tmp,
"%*s %s", myip);
192 ReceiverSocket rsock(myip, myport);
195 rsock.initialize(0x1400000 );
201 std::lock_guard<std::mutex> lock(cs->messageMutex_);
207 __SS__ <<
"FATAL Console error. Could not initialize socket on port "
209 <<
". Perhaps the port is already in use? Check for multiple stale "
210 "instances of otsdaq processes, or notify admins."
211 <<
" Multiple instances of otsdaq on the same node should be "
212 "possible, but port numbers must be unique."
218 __SS__ <<
"FATAL Console error. Could not initialize socket on port " << myport
219 <<
". Perhaps it is already in use? Exiting Console receive loop."
221 __COUT__ << ss.str();
223 cs->messages_.emplace_back(CONSOLE_SPECIAL_ERROR + ss.str(),
225 cs->priorityCustomTriggerList_);
227 cs->messages_.back().setTime(time(0));
228 if(cs->messages_.size() > cs->maxMessageCount_)
230 cs->messages_.erase(cs->messages_.begin());
238 int heartbeatCount = 0;
239 int selfGeneratedMessageCount = 0;
241 std::map<unsigned int, unsigned int> sourceLastSequenceID;
244 long long newSourceId;
245 uint32_t newSequenceId;
249 __COUT__ <<
"DEBUG messages look like this." << __E__;
258 buffer, 1 , 0 ,
false ) !=
262 if(buffer.size() == 1)
270 __COUT__ <<
"Console has first message." << __E__;
274 __COUT_INFO__ <<
"INFO messages look like this." << __E__;
275 __COUT_WARN__ <<
"WARNING messages look like this." << __E__;
276 __COUT_ERR__ <<
"ERROR messages look like this." << __E__;
288 if(selfGeneratedMessageCount)
289 --selfGeneratedMessageCount;
297 std::lock_guard<std::mutex> lock(cs->messageMutex_);
301 while(c < buffer.size())
305 cs->messages_.emplace_back(&(buffer.c_str()[c]),
307 cs->priorityCustomTriggerList_);
308 if(cs->messages_.back().hasCustomTriggerMatchAction())
309 cs->customTriggerActionQueue_.push(
310 cs->messages_.back().getCustomTriggerMatch());
313 if(cs->messages_.back().getLevel() ==
"Error")
315 if(cs->errorCount_ == 0)
317 cs->firstErrorMessageTime_ = time(0);
318 cs->firstErrorMessage_ = cs->messages_.back().getMsg();
321 cs->lastErrorMessageTime_ = time(0);
323 cs->lastErrorMessage_ = cs->messages_.back().getMsg();
325 else if(cs->messages_.back().getLevel() ==
"Warning")
327 if(cs->warnCount_ == 0)
329 cs->firstWarnMessageTime_ = time(0);
330 cs->firstWarnMessage_ = cs->messages_.back().getMsg();
332 cs->lastWarnMessageTime_ = time(0);
334 cs->lastWarnMessage_ = cs->messages_.back().getMsg();
336 else if(cs->messages_.back().getLevel() ==
"Info")
338 if(cs->infoCount_ == 0)
340 cs->firstInfoMessageTime_ = time(0);
341 cs->firstInfoMessage_ = cs->messages_.back().getMsg();
343 cs->lastInfoMessageTime_ = time(0);
345 cs->lastInfoMessage_ = cs->messages_.back().getMsg();
349 newSourceId = cs->messages_.back().getSourceIDAsNumber();
350 newSequenceId = cs->messages_.back().getSequenceIDAsNumber();
357 (newSourceId != -1 &&
358 sourceLastSequenceID.find(newSourceId) !=
361 ((newSequenceId == 0 && sourceLastSequenceID[newSourceId] !=
364 sourceLastSequenceID[newSourceId] + 1))
368 std::stringstream missedSs;
369 missedSs <<
"Console missed "
370 << (newSequenceId - 1) -
371 (sourceLastSequenceID[newSourceId] + 1) + 1
372 <<
" packet(s) from " << cs->messages_.back().getSource()
374 __SS__ << missedSs.str();
375 std::cout << ss.str();
378 cs->messages_.emplace_back(CONSOLE_SPECIAL_WARNING + missedSs.str(),
380 cs->priorityCustomTriggerList_);
382 cs->messages_.back().setTime(time(0));
384 if(cs->priorityCustomTriggerList_.size())
386 cs->customTriggerActionQueue_.push(
387 cs->priorityCustomTriggerList_
389 cs->priorityCustomTriggerList_[0]
391 cs->customTriggerActionQueue_.back().triggeredMessageCountIndex =
392 cs->messages_.back().getCount();
393 cs->messages_.back().setCustomTriggerMatch(
394 cs->customTriggerActionQueue_.back());
399 sourceLastSequenceID[newSourceId] = newSequenceId;
401 while(cs->messages_.size() > 0 &&
402 cs->messages_.size() > cs->maxMessageCount_)
404 cs->messages_.erase(cs->messages_.begin());
407 c += strlen(&(buffer.c_str()[c])) + 1;
421 (heartbeatCount < 60 * 5 &&
422 heartbeatCount % 60 == 59))
424 ++selfGeneratedMessageCount;
425 __COUT__ <<
"Console is alive and waiting... (if no messages, next "
426 "heartbeat is in two minutes)"
429 else if(heartbeatCount % (60 * 30) == 59)
431 ++selfGeneratedMessageCount;
432 __COUT__ <<
"Console is alive and waiting a long time... (if no "
433 "messages, next heartbeat is in one hour)"
444 if(i == 120 || selfGeneratedMessageCount == 5)
447 __COUTV__(selfGeneratedMessageCount);
448 __COUT__ <<
"No messages received at Console Supervisor. Exiting Console "
449 "messageFacilityReceiverWorkLoop"
454 if(cs->customTriggerActionQueue_.size() && !cs->customTriggerActionThreadExists_)
456 cs->customTriggerActionThreadExists_ =
true;
460 ConsoleSupervisor::customTriggerActionThread(c);
469 catch(
const std::runtime_error& e)
471 __COUT_ERR__ <<
"Error caught at Console Supervisor thread: " << e.what() << __E__;
475 __COUT_ERR__ <<
"Unknown error caught at Console Supervisor thread." << __E__;
484 __COUT__ <<
"Starting customTriggerActionThread" << __E__;
485 CustomTriggeredAction_t triggeredAction;
491 std::lock_guard<std::mutex> lock(cs->messageMutex_);
492 if(cs->customTriggerActionQueue_.size())
494 triggeredAction = cs->customTriggerActionQueue_.front();
495 cs->customTriggerActionQueue_.pop();
499 if(triggeredAction.action.size())
501 __COUT_TYPE__(TLVL_DEBUG + 2)
502 << __COUT_HDR__ <<
"Handling action '" << triggeredAction.action
503 <<
"' on custom count search string: "
504 << StringMacros::vectorToString(triggeredAction.needleSubstrings, {
'*'})
506 cs->doTriggeredAction(triggeredAction);
509 triggeredAction.action =
"";
510 triggeredAction.triggeredMessageCountIndex =
517 catch(
const std::runtime_error& e)
519 __COUT_ERR__ <<
"Error caught at Console Supervisor Action thread: " << e.what()
524 __COUT_ERR__ <<
"Unknown error caught at Console Supervisor Action thread." << __E__;
528 void ConsoleSupervisor::doTriggeredAction(
const CustomTriggeredAction_t& triggeredAction)
530 __SUP_COUT_INFO__ <<
"Launching Triggered Action '" << triggeredAction.action
531 <<
"' fired on custom count search string: "
532 << StringMacros::vectorToString(triggeredAction.needleSubstrings,
547 __SUP_SS__ <<
"Unrecognized triggered action '" << triggeredAction.action
548 <<
",' valid actions are "
554 if(triggeredAction.action !=
"Count Only")
555 theRemoteWebUsers_.sendSystemMessage(
557 "In the Console Supervisor, a custom count fired the action '" +
558 triggeredAction.action +
"' on the search string '" +
559 StringMacros::vectorToString(triggeredAction.needleSubstrings, {
'*'}) +
562 if(triggeredAction.action ==
"Halt")
566 else if(triggeredAction.action ==
"Stop")
570 else if(triggeredAction.action ==
"Pause")
579 void ConsoleSupervisor::addCustomTriggeredAction(
const std::string& triggerNeedle,
580 const std::string& triggerAction,
583 __SUP_COUTV__(triggerNeedle);
585 bool allAsterisks =
true;
586 for(
const auto& c : triggerNeedle)
589 allAsterisks =
false;
594 __SUP_SS__ <<
"Illegal empty Search String value for the new Custom Count and "
595 "Action! Please enter a valid Search String (* wildcards are "
596 "allowed, e.g. \"value = * seconds\")."
602 uint32_t currentPriority = -1;
603 for(
const auto& customTrigger : priorityCustomTriggerList_)
606 if(StringMacros::vectorToString(customTrigger.needleSubstrings, {
'*'}) ==
609 __SUP_SS__ <<
"Failure! Can not add Custom Count Search String that already "
612 <<
"' already existing at priority = " << currentPriority << __E__;
617 __SUP_COUTV__(triggerAction);
618 __SUP_COUTV__(priority);
619 if(priority >= priorityCustomTriggerList_.size())
620 priority = priorityCustomTriggerList_.size();
621 if(priority == 0 && triggerNeedle != CONSOLE_MISSED_NEEDLE)
623 __SUP_SS__ <<
"Illegal priority position of '" << priority
624 <<
"' requested. Please enter a priority value greater than 0. "
625 "Position 0 is reserved for identifying missing messages at the "
626 "Console Supervisor. Note: the action for missing messages, at "
627 "priority 0, may be customized by the user."
642 __SUP_SS__ <<
"Unrecognized triggered action '" << triggerAction
643 <<
",' valid actions are "
649 priorityCustomTriggerList_.insert(priorityCustomTriggerList_.begin() + priority,
650 CustomTriggeredAction_t());
655 StringMacros::getVectorFromString(
657 priorityCustomTriggerList_[priority].needleSubstrings,
660 priorityCustomTriggerList_[priority].action = triggerAction;
662 __SUP_COUT__ <<
"Added custom count: "
663 << (StringMacros::vectorToString(
664 priorityCustomTriggerList_[priority].needleSubstrings))
665 <<
" at priority: " << priority << __E__;
673 uint32_t ConsoleSupervisor::modifyCustomTriggeredAction(
const std::string& currentNeedle,
674 const std::string& modifyType,
675 const std::string& setNeedle,
676 const std::string& setAction,
677 uint32_t setPriority)
679 __SUP_COUTV__(currentNeedle);
680 __SUP_COUTV__(modifyType);
681 __SUP_COUTV__(setNeedle);
682 __SUP_COUTV__(setAction);
683 __SUP_COUTV__(setPriority);
686 uint32_t currentPriority = -1;
688 for(
const auto& customTrigger : priorityCustomTriggerList_)
691 if(StringMacros::vectorToString(customTrigger.needleSubstrings, {
'*'}) ==
699 __SUP_COUTV__(currentPriority);
702 __SUP_SS__ <<
"Attempt to modify Custom Count Search String failed. Could not "
703 "find specified Search String '"
704 << currentNeedle <<
"' in prioritized list." << __E__;
708 if(modifyType ==
"Deletion")
710 if(currentPriority == 0)
712 __SUP_SS__ <<
"Illegal deletion requested of priority position 0. Position 0 "
713 "is reserved for identifying missing messages at the Console "
714 "Supervisor. Note: the action of priority 0 may be customized "
715 "by the user, but it can not be deleted."
720 __SUP_COUT__ <<
"Deleting custom count: "
721 << StringMacros::vectorToString(
722 priorityCustomTriggerList_[currentPriority].needleSubstrings,
725 << priorityCustomTriggerList_[currentPriority].action
726 <<
" and priority: " << currentPriority << __E__;
727 priorityCustomTriggerList_.erase(priorityCustomTriggerList_.begin() +
732 if(modifyType ==
"Priority" || modifyType ==
"All")
734 if(setPriority >= priorityCustomTriggerList_.size())
735 setPriority = priorityCustomTriggerList_.size();
736 if(setPriority == 0 && setNeedle != CONSOLE_MISSED_NEEDLE)
738 __SUP_SS__ <<
"Illegal priority position of '" << setPriority
739 <<
"' requested. Position 0 is reserved for identifying missing "
740 "messages at the Console Supervisor. Note: the action of "
741 "priority 0 may be customized by the user."
747 setPriority = currentPriority;
749 if(modifyType ==
"Action" || modifyType ==
"All")
761 __SUP_SS__ <<
"Unrecognized custom count action '" << setAction
762 <<
",' valid actions are "
767 priorityCustomTriggerList_[currentPriority].action = setAction;
770 if(modifyType ==
"Search String" || modifyType ==
"All")
773 priorityCustomTriggerList_[currentPriority].needleSubstrings.clear();
774 StringMacros::getVectorFromString(
776 priorityCustomTriggerList_[currentPriority].needleSubstrings,
781 if(currentPriority != setPriority)
784 priorityCustomTriggerList_.insert(
785 priorityCustomTriggerList_.begin() + setPriority,
786 priorityCustomTriggerList_[currentPriority]);
789 if(currentPriority >= setPriority)
792 priorityCustomTriggerList_.erase(priorityCustomTriggerList_.begin() +
795 if(currentPriority < setPriority)
799 __SUP_COUT__ <<
"Modified '" << modifyType <<
"' custom count: "
800 << StringMacros::vectorToString(
801 priorityCustomTriggerList_[setPriority].needleSubstrings, {
'*'})
802 <<
" now w/action: " << priorityCustomTriggerList_[setPriority].action
803 <<
" and at priority: " << setPriority << __E__;
809 void ConsoleSupervisor::loadCustomCountList()
811 __SUP_COUT__ <<
"loadCustomCountList() from "
812 << USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME << __E__;
814 FILE* fp = fopen((USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME).c_str(),
"r");
817 __SUP_COUT__ <<
"Ignoring missing Custom Count list file at path: "
818 << (USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME) << __E__;
821 priorityCustomTriggerList_.clear();
826 while(fgets(line, 1000, fp))
830 line[strlen(line) - 1] =
'\0';
836 __SUP_COUTTV__(needle);
837 __SUP_COUTTV__(line);
840 CONSOLE_MISSED_NEEDLE)
841 addCustomTriggeredAction(CONSOLE_MISSED_NEEDLE,
"System Message");
842 addCustomTriggeredAction(needle, line);
852 void ConsoleSupervisor::saveCustomCountList()
854 __SUP_COUT__ <<
"saveCustomCountList()" << __E__;
856 FILE* fp = fopen((USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME).c_str(),
"w");
859 __SUP_SS__ <<
"Failed to create Custom Count list file at path: "
860 << (USER_CONSOLE_PREF_PATH + CUSTOM_COUNT_LIST_FILENAME) << __E__;
863 for(
auto& customCount : priorityCustomTriggerList_)
866 (StringMacros::vectorToString(customCount.needleSubstrings, {
'*'}) +
"\n")
868 fprintf(fp, (customCount.action +
"\n").c_str());
874 void ConsoleSupervisor::defaultPage(xgi::Input* , xgi::Output* out)
878 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
879 "src='/WebPath/html/Console.html?urn="
880 << getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
888 CorePropertySupervisorBase::setSupervisorProperty(
889 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
899 HttpXmlDocument& xmlOut,
900 const WebUsers::RequestUserInfo& userInfo)
923 if(requestType ==
"GetConsoleMsgs")
926 std::string lastUpdateCountStr = CgiDataUtilities::postData(cgiIn,
"lcount");
928 if(lastUpdateCountStr ==
"")
930 __SUP_COUT_ERR__ <<
"Invalid Parameters! lastUpdateCount="
931 << lastUpdateCountStr << __E__;
932 xmlOut.addTextElementToData(
"Error",
933 "Error - Invalid parameters for GetConsoleMsgs.");
937 size_t lastUpdateCount = std::stoull(lastUpdateCountStr);
941 insertMessageRefresh(&xmlOut, lastUpdateCount);
943 else if(requestType ==
"PrependHistoricMessages")
945 size_t earliestOnhandMessageCount =
946 CgiDataUtilities::postDataAsInt(cgiIn,
"earlyCount");
947 __SUP_COUTV__(earliestOnhandMessageCount);
948 prependHistoricMessages(&xmlOut, earliestOnhandMessageCount);
950 else if(requestType ==
"SaveUserPreferences")
952 int colorIndex = CgiDataUtilities::postDataAsInt(cgiIn,
"colorIndex");
953 int showSideBar = CgiDataUtilities::postDataAsInt(cgiIn,
"showSideBar");
954 int noWrap = CgiDataUtilities::postDataAsInt(cgiIn,
"noWrap");
955 int messageOnly = CgiDataUtilities::postDataAsInt(cgiIn,
"messageOnly");
956 int hideLineNumers = CgiDataUtilities::postDataAsInt(cgiIn,
"hideLineNumers");
965 if(userInfo.username_ ==
"")
967 __SUP_COUT_ERR__ <<
"Invalid user found! user=" << userInfo.username_
969 xmlOut.addTextElementToData(
"Error",
970 "Error - InvauserInfo.username_user found.");
974 std::string fn = (std::string)USER_CONSOLE_PREF_PATH + userInfo.username_ +
"." +
975 (std::string)USERS_PREFERENCES_FILETYPE;
978 FILE* fp = fopen(fn.c_str(),
"w");
982 __THROW__(ss.str() +
"Could not open file: " + fn);
984 fprintf(fp,
"colorIndex %d\n", colorIndex);
985 fprintf(fp,
"showSideBar %d\n", showSideBar);
986 fprintf(fp,
"noWrap %d\n", noWrap);
987 fprintf(fp,
"messageOnly %d\n", messageOnly);
988 fprintf(fp,
"hideLineNumers %d\n", hideLineNumers);
991 else if(requestType ==
"LoadUserPreferences")
995 unsigned int colorIndex, showSideBar, noWrap, messageOnly, hideLineNumers;
997 if(userInfo.username_ ==
"")
999 __SUP_COUT_ERR__ <<
"Invalid user found! user=" << userInfo.username_
1001 xmlOut.addTextElementToData(
"Error",
"Error - Invalid user found.");
1005 std::string fn = (std::string)USER_CONSOLE_PREF_PATH + userInfo.username_ +
"." +
1006 (std::string)USERS_PREFERENCES_FILETYPE;
1010 FILE* fp = fopen(fn.c_str(),
"r");
1014 __SUP_COUT__ <<
"Returning defaults." << __E__;
1015 xmlOut.addTextElementToData(
"colorIndex",
"0");
1016 xmlOut.addTextElementToData(
"showSideBar",
"0");
1017 xmlOut.addTextElementToData(
"noWrap",
"1");
1018 xmlOut.addTextElementToData(
"messageOnly",
"0");
1019 xmlOut.addTextElementToData(
"hideLineNumers",
"1");
1022 fscanf(fp,
"%*s %u", &colorIndex);
1023 fscanf(fp,
"%*s %u", &showSideBar);
1024 fscanf(fp,
"%*s %u", &noWrap);
1025 fscanf(fp,
"%*s %u", &messageOnly);
1026 fscanf(fp,
"%*s %u", &hideLineNumers);
1035 sprintf(tmpStr,
"%u", colorIndex);
1036 xmlOut.addTextElementToData(
"colorIndex", tmpStr);
1037 sprintf(tmpStr,
"%u", showSideBar);
1038 xmlOut.addTextElementToData(
"showSideBar", tmpStr);
1039 sprintf(tmpStr,
"%u", noWrap);
1040 xmlOut.addTextElementToData(
"noWrap", tmpStr);
1041 sprintf(tmpStr,
"%u", messageOnly);
1042 xmlOut.addTextElementToData(
"messageOnly", tmpStr);
1043 sprintf(tmpStr,
"%u", hideLineNumers);
1044 xmlOut.addTextElementToData(
"hideLineNumers", tmpStr);
1046 else if(requestType ==
"GetTraceLevels")
1048 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1050 SOAPParameters txParameters;
1051 txParameters.addParameter(
"Request",
"GetTraceLevels");
1053 SOAPParameters rxParameters;
1054 rxParameters.addParameter(
"Command");
1055 rxParameters.addParameter(
"Error");
1056 rxParameters.addParameter(
"TRACEHostnameList");
1057 rxParameters.addParameter(
"TRACEList");
1059 traceMapToXDAQHostname_.clear();
1061 std::string traceList =
"";
1062 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1063 for(
const auto& appInfo : allTraceApps)
1065 __SUP_COUT__ <<
"Supervisor hostname = " << appInfo.first <<
"/"
1066 << appInfo.second.getId()
1067 <<
" name = " << appInfo.second.getName()
1068 <<
" class = " << appInfo.second.getClass()
1069 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1072 xoap::MessageReference retMsg =
1073 SOAPMessenger::sendWithSOAPReply(appInfo.second.getDescriptor(),
1074 "TRACESupervisorRequest",
1076 SOAPUtilities::receive(retMsg, rxParameters);
1077 __SUP_COUT__ <<
"Received TRACE response: "
1078 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1079 << SOAPUtilities::translate(retMsg) << __E__;
1081 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1083 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1085 << appInfo.first <<
"/" << appInfo.second.getId()
1086 <<
" name = " << appInfo.second.getName()
1087 <<
" class = " << appInfo.second.getClass()
1088 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1091 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1093 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1098 catch(
const xdaq::exception::Exception& e)
1100 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1101 << appInfo.second.getId()
1102 <<
" name = " << appInfo.second.getName() <<
". \n\n"
1103 << e.what() << __E__;
1106 __SUP_COUT_ERR__ << ss.str();
1110 std::vector<std::string> traceHostnameArr;
1111 __COUTTV__(rxParameters.getValue(
"TRACEHostnameList"));
1112 StringMacros::getVectorFromString(
1113 rxParameters.getValue(
"TRACEHostnameList"), traceHostnameArr, {
';'});
1114 for(
const auto& traceHostname : traceHostnameArr)
1116 if(traceHostname ==
"")
1118 traceMapToXDAQHostname_[traceHostname] = appInfo.first;
1126 __COUTTV__(rxParameters.getValue(
"TRACEList"));
1127 traceList += rxParameters.getValue(
"TRACEList");
1130 __SUP_COUT__ <<
"TRACE hostname map received: \n"
1131 << StringMacros::mapToString(traceMapToXDAQHostname_) << __E__;
1132 __SUP_COUT__ <<
"TRACE List received: \n" << traceList << __E__;
1133 xmlOut.addTextElementToData(
"traceList", traceList);
1135 else if(requestType ==
"SetTraceLevels")
1137 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1139 std::string individualValues =
1140 CgiDataUtilities::postData(cgiIn,
"individualValues");
1141 std::string hostLabelMap = CgiDataUtilities::postData(cgiIn,
"hostLabelMap");
1142 std::string setMode = CgiDataUtilities::postData(cgiIn,
"setMode");
1143 std::string setValueMSB = CgiDataUtilities::postData(cgiIn,
"setValueMSB");
1144 std::string setValueLSB = CgiDataUtilities::postData(cgiIn,
"setValueLSB");
1146 __SUP_COUTV__(individualValues);
1147 __SUP_COUTV__(setMode);
1149 __SUP_COUTV__(setValueMSB);
1150 __SUP_COUTV__(setValueLSB);
1152 std::map<std::string , std::string > hostToLabelMap;
1154 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1156 SOAPParameters rxParameters;
1157 rxParameters.addParameter(
"Command");
1158 rxParameters.addParameter(
"Error");
1159 rxParameters.addParameter(
"TRACEList");
1161 std::string modifiedTraceList =
"";
1162 std::string xdaqHostname;
1163 StringMacros::getMapFromString(hostLabelMap, hostToLabelMap, {
';'}, {
':'});
1164 for(
auto& hostLabelsPair : hostToLabelMap)
1168 __SUP_COUTV__(hostLabelsPair.first);
1169 __SUP_COUTV__(hostLabelsPair.second);
1174 xdaqHostname = traceMapToXDAQHostname_.at(hostLabelsPair.first);
1178 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1179 << hostLabelsPair.first <<
"' to xdaq Context hostname."
1181 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1182 <<
"): " << StringMacros::mapToString(traceMapToXDAQHostname_)
1187 __SUP_COUTV__(xdaqHostname);
1189 auto& appInfo = allTraceApps.at(xdaqHostname);
1190 __SUP_COUT__ <<
"Supervisor hostname = " << hostLabelsPair.first <<
"/"
1191 << xdaqHostname <<
":" << appInfo.getId()
1192 <<
" name = " << appInfo.getName()
1193 <<
" class = " << appInfo.getClass()
1194 <<
" hostname = " << appInfo.getHostname() << __E__;
1197 SOAPParameters txParameters;
1198 txParameters.addParameter(
"Request",
"SetTraceLevels");
1199 txParameters.addParameter(
"IndividualValues", individualValues);
1200 txParameters.addParameter(
"Host", hostLabelsPair.first);
1201 txParameters.addParameter(
"SetMode", setMode);
1202 txParameters.addParameter(
"Labels", hostLabelsPair.second);
1203 txParameters.addParameter(
"SetValueMSB", setValueMSB);
1204 txParameters.addParameter(
"SetValueLSB", setValueLSB);
1206 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1207 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1208 SOAPUtilities::receive(retMsg, rxParameters);
1209 __SUP_COUT__ <<
"Received TRACE response: "
1210 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1211 << SOAPUtilities::translate(retMsg) << __E__;
1213 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1215 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1217 << hostLabelsPair.first <<
"/" << appInfo.getId()
1218 <<
" name = " << appInfo.getName()
1219 <<
" class = " << appInfo.getClass()
1220 <<
" hostname = " << appInfo.getHostname() << __E__;
1223 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1225 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1230 catch(
const xdaq::exception::Exception& e)
1232 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1233 << appInfo.getId() <<
" name = " << appInfo.getName()
1235 << e.what() << __E__;
1239 modifiedTraceList +=
1240 ";" + hostLabelsPair.first;
1244 modifiedTraceList += rxParameters.getValue(
"TRACEList");
1248 __SUP_COUT__ <<
"mod'd TRACE List received: \n" << modifiedTraceList << __E__;
1249 xmlOut.addTextElementToData(
"modTraceList", modifiedTraceList);
1251 else if(requestType ==
"GetTriggerStatus")
1253 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1254 SOAPParameters txParameters;
1255 txParameters.addParameter(
"Request",
"GetTriggerStatus");
1257 SOAPParameters rxParameters;
1258 rxParameters.addParameter(
"Command");
1259 rxParameters.addParameter(
"Error");
1260 rxParameters.addParameter(
"TRACETriggerStatus");
1262 std::string traceTriggerStatus =
"";
1263 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1264 for(
const auto& appInfo : allTraceApps)
1266 __SUP_COUT__ <<
"Supervisor hostname = " << appInfo.first <<
"/"
1267 << appInfo.second.getId()
1268 <<
" name = " << appInfo.second.getName()
1269 <<
" class = " << appInfo.second.getClass()
1270 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1273 xoap::MessageReference retMsg =
1274 SOAPMessenger::sendWithSOAPReply(appInfo.second.getDescriptor(),
1275 "TRACESupervisorRequest",
1277 SOAPUtilities::receive(retMsg, rxParameters);
1278 __SUP_COUT__ <<
"Received TRACE response: "
1279 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1280 << SOAPUtilities::translate(retMsg) << __E__;
1282 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1284 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1286 << appInfo.first <<
"/" << appInfo.second.getId()
1287 <<
" name = " << appInfo.second.getName()
1288 <<
" class = " << appInfo.second.getClass()
1289 <<
" hostname = " << appInfo.second.getHostname() << __E__;
1292 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1294 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1299 catch(
const xdaq::exception::Exception& e)
1301 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1302 << appInfo.second.getId()
1303 <<
" name = " << appInfo.second.getName() <<
". \n\n"
1304 << e.what() << __E__;
1308 traceTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1311 __SUP_COUT__ <<
"TRACE Trigger Status received: \n"
1312 << traceTriggerStatus << __E__;
1313 xmlOut.addTextElementToData(
"traceTriggerStatus", traceTriggerStatus);
1315 else if(requestType ==
"SetTriggerEnable")
1317 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1319 std::string hostList = CgiDataUtilities::postData(cgiIn,
"hostList");
1321 __SUP_COUTV__(hostList);
1323 std::vector<std::string > hosts;
1325 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1327 SOAPParameters rxParameters;
1328 rxParameters.addParameter(
"Command");
1329 rxParameters.addParameter(
"Error");
1330 rxParameters.addParameter(
"TRACETriggerStatus");
1332 std::string modifiedTriggerStatus =
"";
1333 std::string xdaqHostname;
1334 StringMacros::getVectorFromString(hostList, hosts, {
';'});
1335 for(
auto& host : hosts)
1339 __SUP_COUTV__(host);
1346 xdaqHostname = traceMapToXDAQHostname_.at(host);
1350 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1351 << host <<
"' to xdaq Context hostname." << __E__;
1352 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1353 <<
"): " << StringMacros::mapToString(traceMapToXDAQHostname_)
1358 __SUP_COUTV__(xdaqHostname);
1360 auto& appInfo = allTraceApps.at(xdaqHostname);
1361 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1362 << appInfo.getId() <<
" name = " << appInfo.getName()
1363 <<
" class = " << appInfo.getClass()
1364 <<
" hostname = " << appInfo.getHostname() << __E__;
1367 SOAPParameters txParameters;
1368 txParameters.addParameter(
"Request",
"SetTriggerEnable");
1369 txParameters.addParameter(
"Host", host);
1371 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1372 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1373 SOAPUtilities::receive(retMsg, rxParameters);
1374 __SUP_COUT__ <<
"Received TRACE response: "
1375 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1376 << SOAPUtilities::translate(retMsg) << __E__;
1378 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1380 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1382 << host <<
"/" << appInfo.getId()
1383 <<
" name = " << appInfo.getName()
1384 <<
" class = " << appInfo.getClass()
1385 <<
" hostname = " << appInfo.getHostname() << __E__;
1388 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1390 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1395 catch(
const xdaq::exception::Exception& e)
1397 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1398 << appInfo.getId() <<
" name = " << appInfo.getName()
1400 << e.what() << __E__;
1404 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1407 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1408 << modifiedTriggerStatus << __E__;
1409 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1411 else if(requestType ==
"ResetTRACE")
1413 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1415 std::string hostList = CgiDataUtilities::postData(cgiIn,
"hostList");
1417 __SUP_COUTV__(hostList);
1419 std::vector<std::string > hosts;
1421 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1423 SOAPParameters rxParameters;
1424 rxParameters.addParameter(
"Command");
1425 rxParameters.addParameter(
"Error");
1426 rxParameters.addParameter(
"TRACETriggerStatus");
1428 std::string modifiedTriggerStatus =
"";
1429 std::string xdaqHostname;
1430 StringMacros::getVectorFromString(hostList, hosts, {
';'});
1431 for(
auto& host : hosts)
1435 __SUP_COUTV__(host);
1442 xdaqHostname = traceMapToXDAQHostname_.at(host);
1446 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1447 << host <<
"' to xdaq Context hostname." << __E__;
1448 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1449 <<
"): " << StringMacros::mapToString(traceMapToXDAQHostname_)
1454 __SUP_COUTV__(xdaqHostname);
1456 auto& appInfo = allTraceApps.at(xdaqHostname);
1457 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1458 << appInfo.getId() <<
" name = " << appInfo.getName()
1459 <<
" class = " << appInfo.getClass()
1460 <<
" hostname = " << appInfo.getHostname() << __E__;
1463 SOAPParameters txParameters;
1464 txParameters.addParameter(
"Request",
"ResetTRACE");
1465 txParameters.addParameter(
"Host", host);
1467 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1468 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1469 SOAPUtilities::receive(retMsg, rxParameters);
1470 __SUP_COUT__ <<
"Received TRACE response: "
1471 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1472 << SOAPUtilities::translate(retMsg) << __E__;
1474 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1476 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1478 << host <<
"/" << appInfo.getId()
1479 <<
" name = " << appInfo.getName()
1480 <<
" class = " << appInfo.getClass()
1481 <<
" hostname = " << appInfo.getHostname() << __E__;
1484 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1486 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1491 catch(
const xdaq::exception::Exception& e)
1493 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1494 << appInfo.getId() <<
" name = " << appInfo.getName()
1496 << e.what() << __E__;
1500 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1503 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1504 << modifiedTriggerStatus << __E__;
1505 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1507 else if(requestType ==
"EnableTRACE")
1509 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1511 std::string hostList = CgiDataUtilities::postData(cgiIn,
"hostList");
1512 std::string enable = CgiDataUtilities::postData(cgiIn,
"enable");
1514 __SUP_COUTV__(hostList);
1515 __SUP_COUTV__(enable);
1517 std::vector<std::string > hosts;
1519 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1521 SOAPParameters rxParameters;
1522 rxParameters.addParameter(
"Command");
1523 rxParameters.addParameter(
"Error");
1524 rxParameters.addParameter(
"TRACETriggerStatus");
1526 std::string modifiedTriggerStatus =
"";
1527 std::string xdaqHostname;
1528 StringMacros::getVectorFromString(hostList, hosts, {
';'});
1529 for(
auto& host : hosts)
1533 __SUP_COUTV__(host);
1540 xdaqHostname = traceMapToXDAQHostname_.at(host);
1544 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1545 << host <<
"' to xdaq Context hostname." << __E__;
1546 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1547 <<
"): " << StringMacros::mapToString(traceMapToXDAQHostname_)
1552 __SUP_COUTV__(xdaqHostname);
1554 auto& appInfo = allTraceApps.at(xdaqHostname);
1555 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1556 << appInfo.getId() <<
" name = " << appInfo.getName()
1557 <<
" class = " << appInfo.getClass()
1558 <<
" hostname = " << appInfo.getHostname() << __E__;
1561 SOAPParameters txParameters;
1562 txParameters.addParameter(
"Request",
"EnableTRACE");
1563 txParameters.addParameter(
"Host", host);
1564 txParameters.addParameter(
"SetEnable", enable);
1566 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1567 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1568 SOAPUtilities::receive(retMsg, rxParameters);
1569 __SUP_COUT__ <<
"Received TRACE response: "
1570 << SOAPUtilities::translate(retMsg).getCommand() <<
" ==> "
1571 << SOAPUtilities::translate(retMsg) << __E__;
1573 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1575 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1577 << host <<
"/" << appInfo.getId()
1578 <<
" name = " << appInfo.getName()
1579 <<
" class = " << appInfo.getClass()
1580 <<
" hostname = " << appInfo.getHostname() << __E__;
1583 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1585 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1590 catch(
const xdaq::exception::Exception& e)
1592 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1593 << appInfo.getId() <<
" name = " << appInfo.getName()
1595 << e.what() << __E__;
1599 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1602 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1603 << modifiedTriggerStatus << __E__;
1604 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1606 else if(requestType ==
"GetTraceSnapshot")
1608 __SUP_COUT__ <<
"requestType " << requestType << __E__;
1610 std::string hostList = CgiDataUtilities::postData(cgiIn,
"hostList");
1611 std::string filterFor = CgiDataUtilities::postData(cgiIn,
"filterFor");
1612 std::string filterOut = CgiDataUtilities::postData(cgiIn,
"filterOut");
1614 __SUP_COUTV__(hostList);
1615 __SUP_COUTV__(filterFor);
1616 __SUP_COUTV__(filterOut);
1618 std::vector<std::string > hosts;
1620 auto& allTraceApps = allSupervisorInfo_.getAllTraceControllerSupervisorInfo();
1622 SOAPParameters rxParameters;
1623 rxParameters.addParameter(
"Command");
1624 rxParameters.addParameter(
"Error");
1625 rxParameters.addParameter(
"TRACETriggerStatus");
1626 rxParameters.addParameter(
"TRACESnapshot");
1628 std::string modifiedTriggerStatus =
"";
1629 std::string xdaqHostname;
1630 StringMacros::getVectorFromString(hostList, hosts, {
';'});
1631 for(
auto& host : hosts)
1635 __SUP_COUTV__(host);
1642 xdaqHostname = traceMapToXDAQHostname_.at(host);
1646 __SUP_SS__ <<
"Could not find the translation from TRACE hostname '"
1647 << host <<
"' to xdaq Context hostname." << __E__;
1648 ss <<
"Here is the existing map (size=" << traceMapToXDAQHostname_.size()
1649 <<
"): " << StringMacros::mapToString(traceMapToXDAQHostname_)
1654 __SUP_COUTV__(xdaqHostname);
1656 auto& appInfo = allTraceApps.at(xdaqHostname);
1657 __SUP_COUT__ <<
"Supervisor hostname = " << host <<
"/" << xdaqHostname <<
":"
1658 << appInfo.getId() <<
" name = " << appInfo.getName()
1659 <<
" class = " << appInfo.getClass()
1660 <<
" hostname = " << appInfo.getHostname() << __E__;
1663 SOAPParameters txParameters;
1664 txParameters.addParameter(
"Request",
"GetSnapshot");
1665 txParameters.addParameter(
"Host", host);
1666 txParameters.addParameter(
"FilterForCSV", filterFor);
1667 txParameters.addParameter(
"FilterOutCSV", filterOut);
1669 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1670 appInfo.getDescriptor(),
"TRACESupervisorRequest", txParameters);
1671 SOAPUtilities::receive(retMsg, rxParameters);
1672 __SUP_COUT__ <<
"Received TRACE response: "
1673 << SOAPUtilities::translate(retMsg).getCommand() << __E__;
1676 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1678 __SUP_SS__ <<
"Unrecognized command at destination TRACE Supervisor "
1680 << host <<
"/" << appInfo.getId()
1681 <<
" name = " << appInfo.getName()
1682 <<
" class = " << appInfo.getClass()
1683 <<
" hostname = " << appInfo.getHostname() << __E__;
1686 else if(SOAPUtilities::translate(retMsg).getCommand() ==
"TRACEFault")
1688 __SUP_SS__ <<
"Error received: " << rxParameters.getValue(
"Error")
1693 catch(
const xdaq::exception::Exception& e)
1695 __SUP_SS__ <<
"Error transmitting request to TRACE Supervisor LID = "
1696 << appInfo.getId() <<
" name = " << appInfo.getName()
1698 << e.what() << __E__;
1702 modifiedTriggerStatus += rxParameters.getValue(
"TRACETriggerStatus");
1703 xmlOut.addTextElementToData(
"host", host);
1704 std::string snapshot = rxParameters.getValue(
"TRACESnapshot");
1713 std::string filename =
1714 USER_CONSOLE_SNAPSHOT_PATH +
"snapshot_" + host +
".txt";
1715 __SUP_COUTV__(filename);
1716 FILE* fp = fopen(filename.c_str(),
"w");
1719 __SUP_SS__ <<
"Failed to create snapshot file: " << filename << __E__;
1723 "TRACE Snapshot taken at %s\n",
1724 StringMacros::getTimestampString().c_str());
1726 if(snapshot.size() > 5 && snapshot[2] !=
'i')
1731 " idx us_tod delta pid tid cpu "
1732 " trcname lvl r msg \n");
1734 "----- ---------------- ----------- ------ ------ --- "
1735 "-------------------------------------- --- - "
1736 "--------------------------\n");
1738 fprintf(fp,
"%s", snapshot.c_str());
1743 __SUP_COUT__ <<
"mod'd TRACE Trigger Status received: \n"
1744 << modifiedTriggerStatus << __E__;
1745 xmlOut.addTextElementToData(
"modTriggerStatus", modifiedTriggerStatus);
1747 else if(requestType ==
"GetCustomCountsAndActions" ||
1748 requestType ==
"AddCustomCountsAndAction" ||
1749 requestType ==
"ModifyCustomCountsAndAction")
1751 __SUP_COUT__ <<
"requestType " << requestType
1752 <<
" size=" << priorityCustomTriggerList_.size() << __E__;
1757 std::lock_guard<std::mutex> lock(messageMutex_);
1759 if(requestType ==
"AddCustomCountsAndAction" ||
1760 requestType ==
"ModifyCustomCountsAndAction")
1762 std::string needle = StringMacros::decodeURIComponent(
1763 CgiDataUtilities::postData(cgiIn,
"needle"));
1764 uint32_t priority = CgiDataUtilities::postDataAsInt(cgiIn,
"priority");
1765 std::string action = StringMacros::decodeURIComponent(
1766 CgiDataUtilities::postData(cgiIn,
"action"));
1768 __SUP_COUTV__(needle);
1769 __SUP_COUTV__(priority);
1770 __SUP_COUTV__(action);
1772 if(requestType ==
"ModifyCustomCountsAndAction")
1774 std::string buttonDo = StringMacros::decodeURIComponent(
1775 CgiDataUtilities::postData(cgiIn,
"buttonDo"));
1776 std::string currentNeedle =
1777 CgiDataUtilities::postData(cgiIn,
"currentNeedle");
1780 std::vector<std::string> csvNeedles =
1781 StringMacros::getVectorFromString(currentNeedle, {
','});
1782 for(
size_t i = csvNeedles.size() - 1; i < csvNeedles.size(); --i)
1784 if(csvNeedles[i].size() == 0)
1787 priority = modifyCustomTriggeredAction(
1788 StringMacros::decodeURIComponent(csvNeedles[i]),
1796 addCustomTriggeredAction(needle, action, priority);
1798 saveCustomCountList();
1802 size_t untriggeredCount =
1805 for(
const auto& customCount : priorityCustomTriggerList_)
1807 xercesc::DOMElement* customCountParent =
1808 xmlOut.addTextElementToData(
"customCount",
"");
1810 if(customCount.occurrences < untriggeredCount)
1811 untriggeredCount -= customCount.occurrences;
1814 __SUP_SS__ <<
"Impossible custom count; notify admins! "
1815 << customCount.occurrences <<
" > " << untriggeredCount
1817 << StringMacros::vectorToString(customCount.needleSubstrings,
1822 xmlOut.addTextElementToParent(
1824 StringMacros::vectorToString(customCount.needleSubstrings, {
'*'}),
1826 xmlOut.addTextElementToParent(
1827 "count", std::to_string(customCount.occurrences), customCountParent);
1828 xmlOut.addTextElementToParent(
1829 "action", customCount.action, customCountParent);
1833 xercesc::DOMElement* customCountParent =
1834 xmlOut.addTextElementToData(
"customCount",
"");
1835 xmlOut.addTextElementToParent(
"needle",
"< Untriggered >", customCountParent);
1836 xmlOut.addTextElementToParent(
1837 "count", std::to_string(untriggeredCount), customCountParent);
1838 xmlOut.addTextElementToParent(
"action",
"Count Only", customCountParent);
1843 __SUP_SS__ <<
"requestType Request, " << requestType <<
", not recognized."
1858 std::stringstream ss;
1860 << StringMacros::encodeURIComponent(StringMacros::getTimeDurationString(
1861 CorePropertySupervisorBase::getSupervisorUptime()));
1869 ss <<
", Error #: " << errorCount_;
1870 ss <<
", Warn #: " << warnCount_;
1871 ss <<
", Last Error ("
1872 << (lastErrorMessageTime_ ? StringMacros::getTimestampString(lastErrorMessageTime_)
1875 << (lastErrorMessageTime_ ? StringMacros::encodeURIComponent(lastErrorMessage_)
1877 ss <<
", Last Warn ("
1878 << (lastWarnMessageTime_ ? StringMacros::getTimestampString(lastWarnMessageTime_)
1881 << (lastWarnMessageTime_ ? StringMacros::encodeURIComponent(lastWarnMessage_)
1883 ss <<
", Last Info ("
1884 << (lastInfoMessageTime_ ? StringMacros::getTimestampString(lastInfoMessageTime_)
1887 << (lastInfoMessageTime_ ? StringMacros::encodeURIComponent(lastInfoMessage_)
1889 ss <<
", Info #: " << infoCount_;
1890 ss <<
", First Error ("
1891 << (firstErrorMessageTime_
1892 ? StringMacros::getTimestampString(firstErrorMessageTime_)
1895 << (firstErrorMessageTime_ ? StringMacros::encodeURIComponent(firstErrorMessage_)
1897 ss <<
", First Warn ("
1898 << (firstWarnMessageTime_ ? StringMacros::getTimestampString(firstWarnMessageTime_)
1901 << (firstWarnMessageTime_ ? StringMacros::encodeURIComponent(firstWarnMessage_)
1903 ss <<
", First Info ("
1904 << (firstInfoMessageTime_ ? StringMacros::getTimestampString(firstInfoMessageTime_)
1907 << (firstInfoMessageTime_ ? StringMacros::encodeURIComponent(firstInfoMessage_)
1936 void ConsoleSupervisor::insertMessageRefresh(HttpXmlDocument* xmlOut,
1937 const size_t lastUpdateCount)
1941 if(messages_.size() == 0)
1945 if(lastUpdateCount > messages_.back().getCount() && lastUpdateCount != (
size_t)-1)
1947 __SS__ <<
"Invalid lastUpdateCount: " << lastUpdateCount
1948 <<
" messagesArray size = " << messages_.back().getCount() << __E__;
1954 std::lock_guard<std::mutex> lock(messageMutex_);
1956 xmlOut->addTextElementToData(
"last_update_count",
1957 std::to_string(messages_.back().getCount()));
1959 refreshParent_ = xmlOut->addTextElementToData(
"messages",
"");
1961 bool requestOutOfSync =
false;
1962 std::string requestOutOfSyncMsg;
1964 size_t refreshReadPointer = 0;
1965 if(lastUpdateCount != (
size_t)-1)
1967 while(refreshReadPointer < messages_.size() &&
1968 messages_[refreshReadPointer].getCount() <= lastUpdateCount)
1970 ++refreshReadPointer;
1974 if(refreshReadPointer >= messages_.size())
1978 if(messages_.size() - refreshReadPointer > maxClientMessageRequest_)
1984 refreshReadPointer = messages_.size() - maxClientMessageRequest_;
1996 xmlOut->addTextElementToData(
1997 "earliest_update_count",
1998 std::to_string(messages_[refreshReadPointer].getCount()));
2001 for(; refreshReadPointer < messages_.size(); ++refreshReadPointer)
2003 auto msg = messages_[refreshReadPointer];
2004 if(msg.getCount() < lastUpdateCount)
2006 if(!requestOutOfSync)
2008 requestOutOfSync =
true;
2009 __SS__ <<
"Request is out of sync! Message count should be more recent! "
2010 << msg.getCount() <<
" < " << lastUpdateCount << __E__;
2011 requestOutOfSyncMsg = ss.str();
2017 addMessageToResponse(xmlOut, msg);
2021 if(requestOutOfSync)
2022 __SUP_COUT__ << requestOutOfSyncMsg;
2046 void ConsoleSupervisor::prependHistoricMessages(HttpXmlDocument* xmlOut,
2047 const size_t earliestOnhandMessageCount)
2051 if(messages_.size() == 0)
2055 if(earliestOnhandMessageCount >= messages_.back().getCount())
2058 <<
"Invalid claim from user request of earliest onhand message sequence ID = "
2059 << earliestOnhandMessageCount
2060 <<
". Latest existing sequence ID = " << messages_.back().getCount()
2061 <<
". Was the Console Supervisor restarted?" << __E__;
2067 std::lock_guard<std::mutex> lock(messageMutex_);
2069 refreshParent_ = xmlOut->addTextElementToData(
"messages",
"");
2071 size_t refreshReadPointer = 0;
2072 size_t readCountStart = earliestOnhandMessageCount - maxClientMessageRequest_;
2073 if(readCountStart >= messages_.back().getCount())
2077 while(refreshReadPointer < messages_.size() &&
2078 messages_[refreshReadPointer].getCount() < readCountStart)
2080 ++refreshReadPointer;
2083 if(refreshReadPointer >= messages_.size())
2086 xmlOut->addTextElementToData(
"earliest_update_count",
2087 std::to_string(readCountStart));
2091 for(; refreshReadPointer < messages_.size(); ++refreshReadPointer)
2093 auto msg = messages_[refreshReadPointer];
2094 if(messages_[refreshReadPointer].getCount() >= earliestOnhandMessageCount)
2097 addMessageToResponse(xmlOut, msg);
2104 void ConsoleSupervisor::addMessageToResponse(HttpXmlDocument* xmlOut,
2108 for(
auto& field : msg.fields)
2110 if(field.first == ConsoleMessageStruct::FieldType::SOURCE)
2112 if(field.first == ConsoleMessageStruct::FieldType::SOURCEID)
2116 if(field.first == ConsoleMessageStruct::FieldType::TIMESTAMP)
2122 xmlOut->addTextElementToParent(
2123 "message_" + ConsoleMessageStruct::fieldNames.at(field.first),
2129 xmlOut->addTextElementToParent(
"message_Level", msg.getLevel(), refreshParent_);
2132 xmlOut->addTextElementToParent(
"message_Time", msg.getTime(), refreshParent_);
2135 xmlOut->addTextElementToParent(
2136 "message_Count", std::to_string(msg.getCount()), refreshParent_);
2139 xmlOut->addTextElementToParent(
2141 StringMacros::vectorToString(msg.getCustomTriggerMatch().needleSubstrings, {
'*'}),
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
@ SEQID
sequence ID is incrementing number independent from each source