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