1 #ifndef _ots_ConsoleSupervisor_h_ 
    2 #define _ots_ConsoleSupervisor_h_ 
    4 #include <boost/regex.hpp> 
    5 #include <boost/tokenizer.hpp> 
    6 #include "otsdaq/CoreSupervisors/CoreSupervisorBase.h" 
   27         std::vector<std::string>    needleSubstrings; 
 
   29         size_t                      triggeredMessageCountIndex = -1; 
 
   30         size_t                      occurrences = 0; 
 
   40     xoap::MessageReference      resetConsoleCounts                  (xoap::MessageReference message);
 
   42     virtual void                defaultPage                         (xgi::Input* in, xgi::Output* out) 
override;
 
   43     virtual void                request                             (
const std::string&               requestType,
 
   45                                                                     HttpXmlDocument&                 xmlOut,
 
   46                                                                     const WebUsers::RequestUserInfo& userInfo) 
override;
 
   56     std::atomic<bool>                       customTriggerActionThreadExists_ = 
false;   
 
   62     void                        insertMessageRefresh                (HttpXmlDocument* xmldoc, 
const size_t lastUpdateCount);
 
   63     void                        prependHistoricMessages             (HttpXmlDocument* xmlOut, 
const size_t earliestOnhandMessageCount);
 
   65     void                        addCustomTriggeredAction            (
const std::string& triggerNeedle, 
const std::string& triggerAction, uint32_t priority = -1);
 
   66     uint32_t                    modifyCustomTriggeredAction         (
const std::string& currentNeedle, 
const std::string& modifyType, 
const std::string& setNeedle, 
const std::string& setAction, uint32_t setPriority);
 
   68     void                        loadCustomCountList                 (
void);
 
   69     void                        saveCustomCountList                 (
void);
 
   78             std::vector<CustomTriggeredAction_t>& priorityCustomTriggerList)
 
   81             boost::regex timestamp_regex_(
"(\\d{2}-[^-]*-\\d{4}\\s\\d{2}:\\d{2}:\\d{2})");
 
   82             boost::regex file_line_regex_(
"^\\s*([^:]*\\.[^:]{1,3}):(\\d+)(.*)");
 
   84             boost::char_separator<char> sep(
"|", 
"", boost::keep_empty_tokens);
 
   85             typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
 
   86             tokenizer                                             tokens(msg, sep);
 
   87             tokenizer::iterator                                   it = tokens.begin();
 
   91             while(it != tokens.end() && !boost::regex_search(*it, res, timestamp_regex_))
 
   97             std::string value(res[1].first, res[1].second);
 
   98             strptime(value.c_str(), 
"%d-%b-%Y %H:%M:%S", &tm);
 
  100             fields[FieldType::TIMESTAMP] = std::to_string(mktime(&tm));
 
  105                 if(it != tokens.end() && ++it != tokens.end() )
 
  111             catch(
const std::invalid_argument& e)
 
  115             if(it != tokens.end() && ++it != tokens.end() )
 
  118                 fields[FieldType::HOSTNAME] = *it; 
 
  120             if(it != tokens.end() && ++it != tokens.end() )
 
  124             if(it != tokens.end() && ++it != tokens.end() )
 
  129             if(it != tokens.end() && ++it != tokens.end() )
 
  132                 fields[FieldType::LABEL] = *it;
 
  134             if(it != tokens.end() && ++it != tokens.end() )
 
  137                 fields[FieldType::SOURCE] = *it;
 
  142                 if(it != tokens.end() && ++it != tokens.end() )
 
  145                     fields[FieldType::SOURCEID] = *it;
 
  148             catch(
const std::invalid_argument& e)
 
  152             if(it != tokens.end() && ++it != tokens.end() )
 
  156             if(it != tokens.end() && ++it != tokens.end() )
 
  160             if(it != tokens.end() && ++it != tokens.end() )
 
  163                 fields[FieldType::FILE] = *it;
 
  165             if(it != tokens.end() && ++it != tokens.end() )
 
  168                 fields[FieldType::LINE] = *it;
 
  170             std::ostringstream oss;
 
  172             while(it != tokens.end() && ++it != tokens.end() )
 
  184             fields[FieldType::MSG] = oss.str();
 
  187             for (
auto& field : fields) {
 
  188                 std::cout << 
"Field " << field.second.fieldName << 
": " << field.second.fieldValue
 
  195             for(
auto& triggeredAction : priorityCustomTriggerList)
 
  197                 if(getLabel() == 
"Console") 
break; 
 
  200                 bool foundAll = 
false;
 
  201                 for(
const auto& needleSubstring : triggeredAction.needleSubstrings)
 
  202                     if((pos = getMsg().find(needleSubstring)) == std::string::npos)
 
  216                     triggeredAction.occurrences++; 
 
  217                     customTriggerMatch = triggeredAction;
 
  218                     customTriggerMatch.triggeredMessageCountIndex = getCount();
 
  225         void setCustomTriggerMatch(
const CustomTriggeredAction_t& forcedCustomTriggerMatch) { customTriggerMatch = forcedCustomTriggerMatch; }
 
  226         const CustomTriggeredAction_t& getCustomTriggerMatch()
 const { 
return customTriggerMatch; }
 
  227         bool        hasCustomTriggerMatchAction()
 const { 
return customTriggerMatch.action.size(); }
 
  228         const std::string& getTime()
 const { 
return fields.at(FieldType::TIMESTAMP); }
 
  229         void               setTime(time_t t) { fields[FieldType::TIMESTAMP] = std::to_string(t); }
 
  230         const std::string& getMsg()
 const { 
return fields.at(FieldType::MSG); }
 
  231         const std::string& getLabel()
 const { 
return fields.at(FieldType::LABEL); }
 
  232         const std::string& getLevel()
 const { 
 
  234             if(getMsg().size() > 4)
 
  236                 if(getMsg()[0] == 
'9' && getMsg()[1] == 
':') 
return ConsoleMessageStruct::LABEL_TRACE;
 
  237                 if(getMsg()[0] >= 
'1' && getMsg()[0] <= 
'3' &&
 
  238                     getMsg()[1] >= 
'0' && getMsg()[1] <= 
'9' &&
 
  239                     getMsg()[2] == 
':') 
return ConsoleMessageStruct::LABEL_TRACE_PLUS;
 
  243         const std::string& getFile()
 const { 
return fields.at(FieldType::FILE); }
 
  244         const std::string& getLine()
 const { 
return fields.at(FieldType::LINE); }
 
  246         const std::string& getSourceID()
 const { 
return fields.at(FieldType::SOURCEID); }
 
  247         uint32_t    getSourceIDAsNumber()
 const 
  249             auto val = fields.at(FieldType::SOURCEID);
 
  252                 return std::stoul(val);
 
  256         const std::string& getSource()
 const { 
return fields.at(FieldType::SOURCE); }
 
  257         const std::string& getSequenceID()
 const { 
return fields.at(
FieldType::SEQID); }
 
  258         size_t      getSequenceIDAsNumber()
 const 
  263                 return std::stoul(val);
 
  269         size_t getCount()
 const { 
return countStamp; } 
 
  287         mutable std::unordered_map<
FieldType, std::string > fields;
 
  288         static const std::map<
FieldType, std::string > fieldNames;
 
  294         static const std::string LABEL_TRACE, LABEL_TRACE_PLUS;
 
  300     std::deque<ConsoleMessageStruct> messages_;
 
  301     std::mutex                       messageMutex_;
 
  302     size_t messageCount_;  
 
  303     size_t maxMessageCount_, maxClientMessageRequest_;
 
  305     std::map<std::string , std::string >
 
  306                                             traceMapToXDAQHostname_;
 
  309     xercesc::DOMElement*                    refreshParent_;
 
  311     std::vector<CustomTriggeredAction_t>        priorityCustomTriggerList_;
 
  312     std::queue<CustomTriggeredAction_t>         customTriggerActionQueue_;  
 
  315     size_t          errorCount_ = 0, warnCount_ = 0, infoCount_ = 0;
 
  316     std::string     lastErrorMessage_, lastWarnMessage_, lastInfoMessage_, firstErrorMessage_, firstWarnMessage_, firstInfoMessage_;
 
  317     time_t          lastErrorMessageTime_ = 0, lastWarnMessageTime_ = 0, lastInfoMessageTime_ = 0, firstErrorMessageTime_ = 0, firstWarnMessageTime_ = 0, firstInfoMessageTime_ = 0;
 
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
 
ConsoleMessageStruct(const std::string &msg, const size_t count, std::vector< CustomTriggeredAction_t > &priorityCustomTriggerList)