artdaq_mfextensions  v1_06_02
ma_condition.cpp
1 #include "ErrorHandler/MessageAnalyzer/ma_condition.h"
2 #include "ErrorHandler/MessageAnalyzer/ma_parse.h"
3 
4 using namespace novadaq::errorhandler;
5 
6 ma_condition::ma_condition(std::string const& desc, std::string const& sev, std::vector<std::string> const& sources, std::vector<std::string> const& categories, std::string const& regex, std::string const& test, bool persistent_cond, int occur, bool at_least, int timespan, bool per_source, bool per_target, int target_group, ma_timing_events& events)
7  : description_(desc)
8  , severity_(get_sev_from_string(sev))
9  , srcs_str()
10  , e_srcs()
11  , any_src(false)
12  , cats_str()
13  , e_cats()
14  , any_cat(false)
15  , match_type(MATCH_REGEX)
16  , regex_str(regex)
17  , e(regex)
18  , test_expr()
19  , tc(at_least ? occur : occur + 1)
20  , at_least_(at_least)
21  , ts(timespan)
22  , ps(per_source)
23  , pt(per_target)
24  , t_group(target_group)
25  , persistent_(persistent_cond)
26  , hitmap()
27  , events(events)
28  , sev_()
29  , src_()
30  , tgt_()
31  , cat_()
32  , bdy_()
33  , what_()
34  , last_sev_()
35  , last_src_()
36  , last_tgt_()
37  , last_cat_()
38  , last_bdy_()
39  , last_what_()
40  , notify_on_source()
41  , notify_on_target()
42  , notify_on_status()
43  , catched_messages(0)
44 {
45  // parse sources
46  std::vector<std::string>::const_iterator it = sources.begin();
47  while (it != sources.end())
48  {
49  if (*it == "*")
50  {
51  any_src = true;
52  e_srcs.clear();
53  srcs_str = "any, ";
54  break;
55  }
56  e_srcs.push_back(regex_t(*it));
57  srcs_str.append(*it).append(", ");
58  ++it;
59  }
60 
61  // remove the last ", "
62  srcs_str.resize(srcs_str.size() - 2);
63 
64  // parse categories
65  it = categories.begin();
66  while (it != categories.end())
67  {
68  if (*it == "*")
69  {
70  any_cat = true;
71  e_cats.clear();
72  cats_str = "any, ";
73  break;
74  }
75  e_cats.push_back(regex_t(*it));
76  cats_str.append(*it).append(", ");
77  ++it;
78  }
79 
80  // remove the last ", "
81  cats_str.resize(cats_str.size() - 2);
82 
83  // regex or contains?
84  if (regex.empty() || (regex.compare("*") == 0))
85  match_type = MATCH_ANY;
86  else
87  match_type = MATCH_REGEX;
88 
89  // test functions
90  if (!parse_condition_test(test, test_expr))
91  throw std::runtime_error("condition test function parse failed");
92 }
93 
94 void ma_condition::reset()
95 {
96  hitmap.reset();
97  catched_messages = 0;
98 }
99 
100 void ma_condition::init()
101 {
102  hitmap.set_parent(this);
103 }
104 
105 bool ma_condition::match(qt_mf_msg const& msg, conds_t& status, conds_t& source, conds_t& target)
106 {
107  extract_fields(msg);
108 
109  // filtering conditions
110  if (sev_ < severity_) return false;
111  if (!match_srcs()) return false;
112  if (!match_cats()) return false;
113 
114  // match condition
115  if (!match_body()) return false;
116 
117  // update fields after passing the match condition
118  update_fields();
119 
120  // test condition
121  if (!match_test()) return false;
122 
123  // register to hitmap
124  unsigned int result = hitmap.capture(msg, src_, tgt_, what_);
125 
126  TLOG(TLVL_DEBUG) << "cond::match() result = " << result << " src = " << src_;
127 
128  // update reaction_start list
129  if (result & STATUS_CHANGE) status.push_back(this);
130  if (result & SOURCE_CHANGE) source.push_back(this);
131  if (result & TARGET_CHANGE) target.push_back(this);
132 
133  //if (result & STATUS_CHANGE) update_fields();
134 
135  ++catched_messages;
136 
137  return true;
138 }
139 
140 bool ma_condition::event(size_t src, size_t tgt, time_t t, conds_t& status)
141 {
142  if (hitmap.event(src, tgt, t))
143  {
144  // we have a status flip
145  status.push_back(this);
146  return true;
147  }
148 
149  return false;
150 }
151 
152 void ma_condition::extract_fields(qt_mf_msg const& msg)
153 {
154  sev_ = msg.sev();
155  get_source_from_msg(src_, msg);
156  cat_ = msg.cat().toStdString();
157  bdy_ = msg.text(false).toStdString();
158 }
159 
160 void ma_condition::update_fields()
161 {
162  last_sev_ = sev_;
163  last_src_ = src_;
164  last_tgt_ = tgt_;
165  last_cat_ = cat_;
166  last_bdy_ = bdy_;
167  last_what_ = what_;
168 }
169 
170 bool ma_condition::match_srcs()
171 {
172  if (any_src) return true;
173 
174  size_t imax = e_srcs.size();
175 
176  for (size_t i = 0; i < imax; ++i)
177  {
178  if (boost::regex_match(src_, what_, e_srcs[i])) return true;
179  }
180 
181  return false;
182 }
183 
184 bool ma_condition::match_cats()
185 {
186  if (any_cat) return true;
187 
188  size_t imax = e_cats.size();
189 
190  for (size_t i = 0; i < imax; ++i)
191  {
192  if (boost::regex_match(cat_, what_, e_cats[i])) return true;
193  }
194 
195  return false;
196 }
197 
198 bool ma_condition::match_body()
199 {
200  if (match_type == MATCH_ANY)
201  return true;
202 
203  if (boost::regex_search(bdy_, what_, e))
204  {
205  if (pt) // per_target, now extract the target string
206  {
207  if (t_group > what_.size())
208  throw std::runtime_error("match_body: target group does not exit");
209 
210  tgt_ = std::string(what_[t_group].first, what_[t_group].second);
211  }
212 
213  return true;
214  }
215 
216  return false;
217 }
218 
219 bool ma_condition::match_test()
220 {
221  return test_expr.evaluate(this);
222 }
Qt wrapper around MessageFacility message
Definition: qt_mf_msg.hh:37
sev_code_t sev() const
Get the severity of the message
Definition: qt_mf_msg.hh:76
QString const & text(bool mode) const
Get the text of the message
Definition: qt_mf_msg.hh:66
QString const & cat() const
Get the category of the message
Definition: qt_mf_msg.hh:86