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;
31 size_t triggerOnCount = 1;
44 xoap::MessageReference resetConsoleCounts (xoap::MessageReference message);
46 virtual void defaultPage (xgi::Input* in, xgi::Output* out)
override;
47 virtual void request (
const std::string& requestType,
50 const WebUsers::RequestUserInfo& userInfo)
override;
60 std::atomic<bool> customTriggerActionThreadExists_ =
false;
66 void insertMessageRefresh (
HttpXmlDocument* xmldoc,
const size_t lastUpdateCount);
67 void prependHistoricMessages (
HttpXmlDocument* xmlOut,
const size_t earliestOnhandMessageCount);
69 void addCustomTriggeredAction (
const std::string& triggerNeedle,
70 const std::string& triggerAction,
71 uint32_t priority = -1,
72 uint32_t triggerOnCount = 1,
74 bool isArmed =
false);
75 uint32_t modifyCustomTriggeredAction (
const std::string& currentNeedle,
76 const std::string& modifyType,
77 const std::string& setNeedle,
78 const std::string& setAction,
80 uint32_t setTriggerOnCount,
84 void loadCustomCountList (
void);
85 void saveCustomCountList (
void);
94 std::vector<CustomTriggeredAction_t>& priorityCustomTriggerList)
97 boost::regex timestamp_regex_(
"(\\d{2}-[^-]*-\\d{4}\\s\\d{2}:\\d{2}:\\d{2})");
98 boost::regex file_line_regex_(
"^\\s*([^:]*\\.[^:]{1,3}):(\\d+)(.*)");
100 boost::char_separator<char> sep(
"|",
"", boost::keep_empty_tokens);
101 typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
102 tokenizer tokens(msg, sep);
103 tokenizer::iterator it = tokens.begin();
107 while(it != tokens.end() && !boost::regex_search(*it, res, timestamp_regex_))
113 std::string value(res[1].first, res[1].second);
114 strptime(value.c_str(),
"%d-%b-%Y %H:%M:%S", &tm);
116 fields[FieldType::TIMESTAMP] = std::to_string(mktime(&tm));
121 if(it != tokens.end() && ++it != tokens.end() )
127 catch(
const std::invalid_argument& e)
131 if(it != tokens.end() && ++it != tokens.end() )
134 fields[FieldType::HOSTNAME] = *it;
136 if(it != tokens.end() && ++it != tokens.end() )
140 if(it != tokens.end() && ++it != tokens.end() )
145 if(it != tokens.end() && ++it != tokens.end() )
148 fields[FieldType::LABEL] = *it;
150 if(it != tokens.end() && ++it != tokens.end() )
153 fields[FieldType::SOURCE] = *it;
158 if(it != tokens.end() && ++it != tokens.end() )
161 fields[FieldType::SOURCEID] = *it;
164 catch(
const std::invalid_argument& e)
168 if(it != tokens.end() && ++it != tokens.end() )
172 if(it != tokens.end() && ++it != tokens.end() )
176 if(it != tokens.end() && ++it != tokens.end() )
179 fields[FieldType::FILE] = *it;
181 if(it != tokens.end() && ++it != tokens.end() )
184 fields[FieldType::LINE] = *it;
186 std::ostringstream oss;
188 while(it != tokens.end() && ++it != tokens.end() )
200 fields[FieldType::MSG] = oss.str();
203 for (
auto& field : fields) {
204 std::cout <<
"Field " << field.second.fieldName <<
": " << field.second.fieldValue
211 for(
auto& triggeredAction : priorityCustomTriggerList)
213 if(getLabel() ==
"Console")
break;
216 bool foundAll =
false;
217 for(
const auto& needleSubstring : triggeredAction.needleSubstrings)
218 if((pos = getMsg().find(needleSubstring)) == std::string::npos)
234 triggeredAction.occurrences++;
237 if(!triggeredAction.isArmed)
241 if(triggeredAction.occurrences % triggeredAction.triggerOnCount == 0)
243 customTriggerMatch = triggeredAction;
244 customTriggerMatch.triggeredMessageCountIndex = getCount();
248 if(!triggeredAction.doLoop)
249 triggeredAction.isArmed =
false;
257 void setCustomTriggerMatch(
const CustomTriggeredAction_t& forcedCustomTriggerMatch) { customTriggerMatch = forcedCustomTriggerMatch; }
258 const CustomTriggeredAction_t& getCustomTriggerMatch()
const {
return customTriggerMatch; }
259 bool hasCustomTriggerMatchAction()
const {
return customTriggerMatch.action.size(); }
260 const std::string& getTime()
const {
return fields.at(FieldType::TIMESTAMP); }
261 void setTime(time_t t) { fields[FieldType::TIMESTAMP] = std::to_string(t); }
262 const std::string& getMsg()
const {
return fields.at(FieldType::MSG); }
263 const std::string& getLabel()
const {
return fields.at(FieldType::LABEL); }
264 const std::string& getLevel()
const {
266 if(getMsg().size() > 4)
268 if(getMsg()[0] ==
'9' && getMsg()[1] ==
':')
return ConsoleMessageStruct::LABEL_TRACE;
269 if(getMsg()[0] >=
'1' && getMsg()[0] <=
'3' &&
270 getMsg()[1] >=
'0' && getMsg()[1] <=
'9' &&
271 getMsg()[2] ==
':')
return ConsoleMessageStruct::LABEL_TRACE_PLUS;
275 const std::string& getFile()
const {
return fields.at(FieldType::FILE); }
276 const std::string& getLine()
const {
return fields.at(FieldType::LINE); }
278 const std::string& getSourceID()
const {
return fields.at(FieldType::SOURCEID); }
279 uint32_t getSourceIDAsNumber()
const
281 auto val = fields.at(FieldType::SOURCEID);
284 return std::stoul(val);
288 const std::string& getSource()
const {
return fields.at(FieldType::SOURCE); }
289 const std::string& getSequenceID()
const {
return fields.at(
FieldType::SEQID); }
290 size_t getSequenceIDAsNumber()
const
295 return std::stoul(val);
301 size_t getCount()
const {
return countStamp; }
319 mutable std::unordered_map<
FieldType, std::string > fields;
320 static const std::map<
FieldType, std::string > fieldNames;
326 static const std::string LABEL_TRACE, LABEL_TRACE_PLUS;
332 std::deque<ConsoleMessageStruct> messages_;
333 std::mutex messageMutex_;
334 size_t messageCount_;
335 size_t maxMessageCount_, maxClientMessageRequest_;
337 std::map<std::string , std::string >
338 traceMapToXDAQHostname_;
341 xercesc::DOMElement* refreshParent_;
343 std::vector<CustomTriggeredAction_t> priorityCustomTriggerList_;
344 std::queue<CustomTriggeredAction_t> customTriggerActionQueue_;
347 size_t errorCount_ = 0, warnCount_ = 0, infoCount_ = 0;
348 std::string lastErrorMessage_, lastWarnMessage_, lastInfoMessage_, firstErrorMessage_, firstWarnMessage_, firstInfoMessage_;
349 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)