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)