132 std::cout <<
"=== Alert Triggers Example ===" << std::endl;
133 std::cout << std::endl;
138 std::cout <<
"1. Threshold Triggers" << std::endl;
139 std::cout <<
" -------------------" << std::endl;
148 auto equal_50 = std::make_shared<threshold_trigger>(
149 50.0, comparison_operator::equal, 0.5);
150 auto not_equal_100 = std::make_shared<threshold_trigger>(
151 100.0, comparison_operator::not_equal);
153 std::cout <<
" Testing threshold triggers with various values:" << std::endl;
154 std::cout << std::endl;
156 std::vector<double> test_values = {5.0, 10.0, 20.0, 50.0, 50.3, 80.0, 85.0, 90.0, 100.0};
158 for (
double val : test_values) {
159 std::cout <<
" Value: " << val << std::endl;
160 print_eval_result(
"above(80)", val, above_80->evaluate(val), above_80->description());
166 std::cout << std::endl;
172 std::cout <<
"2. Range Triggers" << std::endl;
173 std::cout <<
" ---------------" << std::endl;
178 std::cout <<
" Range triggers test [40, 60]:" << std::endl;
179 std::cout << std::endl;
181 std::vector<double> range_values = {30.0, 40.0, 50.0, 60.0, 70.0};
182 for (
double val : range_values) {
184 in_range_40_60->description());
186 out_of_range_40_60->description());
187 std::cout << std::endl;
193 std::cout <<
"3. Rate of Change Trigger" << std::endl;
194 std::cout <<
" -----------------------" << std::endl;
197 auto rate_increasing = std::make_shared<rate_of_change_trigger>(
200 rate_of_change_trigger::rate_direction::increasing,
205 auto rate_decreasing = std::make_shared<rate_of_change_trigger>(
208 rate_of_change_trigger::rate_direction::decreasing,
213 auto rate_either = std::make_shared<rate_of_change_trigger>(
216 rate_of_change_trigger::rate_direction::either,
220 std::cout <<
" Simulating rapidly increasing values:" << std::endl;
223 std::vector<double> increasing_values = {10.0, 15.0, 25.0, 40.0, 60.0, 85.0};
224 for (
size_t i = 0; i < increasing_values.size(); ++i) {
225 double val = increasing_values[i];
226 bool triggered = rate_increasing->evaluate(val);
227 std::cout <<
" Sample " << (i + 1) <<
": value=" << val
228 <<
" | Rate trigger: " << (triggered ?
"YES" :
"NO") << std::endl;
229 std::this_thread::sleep_for(100ms);
231 std::cout << std::endl;
234 rate_decreasing->reset();
235 std::cout <<
" Simulating rapidly decreasing values:" << std::endl;
237 std::vector<double> decreasing_values = {100.0, 95.0, 85.0, 70.0, 50.0, 25.0};
238 for (
size_t i = 0; i < decreasing_values.size(); ++i) {
239 double val = decreasing_values[i];
240 bool triggered = rate_decreasing->evaluate(val);
241 std::cout <<
" Sample " << (i + 1) <<
": value=" << val
242 <<
" | Rate trigger: " << (triggered ?
"YES" :
"NO") << std::endl;
243 std::this_thread::sleep_for(100ms);
245 std::cout << std::endl;
250 std::cout <<
"4. Anomaly Trigger (Statistical)" << std::endl;
251 std::cout <<
" ------------------------------" << std::endl;
254 auto anomaly_trigger_ptr = std::make_shared<anomaly_trigger>(
260 std::cout <<
" Building baseline with normal values (around 50):" << std::endl;
263 std::random_device rd;
264 std::mt19937 gen(rd());
265 std::normal_distribution<> normal_dist(50.0, 5.0);
268 for (
int i = 0; i < 15; ++i) {
269 double val = normal_dist(gen);
270 bool triggered = anomaly_trigger_ptr->evaluate(val);
271 std::cout <<
" Sample " << (i + 1) <<
": value=" << std::fixed
272 << std::setprecision(1) << val
273 <<
" | Anomaly: " << (triggered ?
"YES" :
"NO") << std::endl;
276 std::cout << std::endl;
277 std::cout <<
" Current baseline - Mean: " << std::fixed << std::setprecision(2)
278 << anomaly_trigger_ptr->current_mean()
279 <<
", StdDev: " << anomaly_trigger_ptr->current_stddev() << std::endl;
280 std::cout << std::endl;
283 std::cout <<
" Introducing anomalous values:" << std::endl;
284 std::vector<double> anomalous_values = {80.0, 20.0, 100.0, 52.0};
285 for (
double val : anomalous_values) {
286 bool triggered = anomaly_trigger_ptr->evaluate(val);
287 std::cout <<
" Value: " << val <<
" | Anomaly: " << (triggered ?
"YES" :
"NO")
288 <<
" (>" << (anomaly_trigger_ptr->current_stddev() * 2)
289 <<
" from mean " << anomaly_trigger_ptr->current_mean() <<
")" << std::endl;
291 std::cout << std::endl;
296 std::cout <<
"5. Composite Triggers (AND/OR/NOT)" << std::endl;
297 std::cout <<
" --------------------------------" << std::endl;
314 auto xor_trigger = std::make_shared<composite_trigger>(
315 composite_operation::XOR,
316 std::vector<std::shared_ptr<alert_trigger>>{cpu_high, memory_high}
319 std::cout <<
" Composite trigger descriptions:" << std::endl;
320 std::cout <<
" - ALL (AND): " << all_high->description() << std::endl;
321 std::cout <<
" - ANY (OR): " << any_high->description() << std::endl;
322 std::cout <<
" - NOT: " << cpu_not_high->description() << std::endl;
323 std::cout <<
" - XOR: " << xor_trigger->description() << std::endl;
324 std::cout << std::endl;
333 std::vector<TestCase> composite_tests = {
340 std::cout <<
" Testing composite triggers:" << std::endl;
341 for (
const auto& tc : composite_tests) {
342 std::cout <<
" CPU=" << tc.cpu <<
", Memory=" << tc.memory
343 <<
", Disk=" << tc.disk << std::endl;
346 std::vector<double> values = {tc.cpu, tc.memory, tc.disk};
349 bool all_result = all_high->evaluate_multi(values);
350 bool any_result = any_high->evaluate_multi(values);
351 bool not_result = cpu_not_high->evaluate(tc.cpu);
352 bool xor_result = xor_trigger->evaluate_multi({tc.cpu, tc.memory});
354 std::cout <<
" ALL: " << (all_result ?
"YES" :
"NO")
355 <<
" | ANY: " << (any_result ?
"YES" :
"NO")
356 <<
" | NOT(cpu>80): " << (not_result ?
"YES" :
"NO")
357 <<
" | XOR(cpu,mem): " << (xor_result ?
"YES" :
"NO") << std::endl;
359 std::cout << std::endl;
364 std::cout <<
"6. Delta Trigger (Change Detection)" << std::endl;
365 std::cout <<
" ----------------------------------" << std::endl;
368 auto delta_absolute = std::make_shared<delta_trigger>(10.0,
true);
371 auto delta_positive = std::make_shared<delta_trigger>(5.0,
false);
373 std::cout <<
" Testing delta triggers with sequential values:" << std::endl;
374 std::vector<double> delta_values = {50.0, 52.0, 55.0, 70.0, 68.0, 55.0};
376 for (
size_t i = 0; i < delta_values.size(); ++i) {
377 double val = delta_values[i];
378 bool abs_triggered = delta_absolute->evaluate(val);
379 bool pos_triggered = delta_positive->evaluate(val);
381 std::cout <<
" Value: " << val;
383 std::cout <<
" (delta=" << (val - delta_values[i-1]) <<
")";
385 std::cout <<
" | Absolute(>10): " << (abs_triggered ?
"YES" :
"NO")
386 <<
" | Positive(>5): " << (pos_triggered ?
"YES" :
"NO") << std::endl;
388 std::cout << std::endl;
393 std::cout <<
"7. Absent Trigger (Missing Data)" << std::endl;
394 std::cout <<
" ------------------------------" << std::endl;
397 auto absent_trigger_ptr = std::make_shared<absent_trigger>(200ms);
399 std::cout <<
" " << absent_trigger_ptr->description() << std::endl;
400 std::cout <<
" Simulating data with gaps:" << std::endl;
403 for (
int i = 0; i < 3; ++i) {
404 bool triggered = absent_trigger_ptr->evaluate(100.0);
405 std::cout <<
" Evaluation " << (i + 1) <<
" (immediate): "
406 << (triggered ?
"ABSENT" :
"present") << std::endl;
407 std::this_thread::sleep_for(50ms);
411 std::cout <<
" ... waiting 300ms (simulating data gap) ..." << std::endl;
412 std::this_thread::sleep_for(300ms);
414 bool after_gap = absent_trigger_ptr->evaluate(100.0);
415 std::cout <<
" Evaluation after gap: " << (after_gap ?
"ABSENT" :
"present") << std::endl;
416 std::cout << std::endl;
421 std::cout <<
"8. Custom Trigger Implementations" << std::endl;
422 std::cout <<
" -------------------------------" << std::endl;
425 auto periodic = std::make_shared<periodic_trigger>(3);
426 std::cout <<
" Periodic trigger: " << periodic->description() << std::endl;
428 for (
int i = 1; i <= 9; ++i) {
429 bool triggered = periodic->evaluate(0);
430 std::cout <<
" Evaluation " << i <<
": " << (triggered ?
"FIRE" :
"-") << std::endl;
432 std::cout << std::endl;
435 auto ma_trigger = std::make_shared<moving_average_trigger>(5, 60.0);
436 std::cout <<
" Moving average trigger: " << ma_trigger->description() << std::endl;
438 std::vector<double> ma_values = {50.0, 55.0, 60.0, 65.0, 70.0, 75.0, 80.0};
439 for (
size_t i = 0; i < ma_values.size(); ++i) {
440 double val = ma_values[i];
441 bool triggered = ma_trigger->evaluate(val);
442 std::cout <<
" Value: " << val <<
" | MA(5)=" << std::fixed << std::setprecision(1)
443 << ma_trigger->current_average()
444 <<
" | Triggered: " << (triggered ?
"YES" :
"NO") << std::endl;
446 std::cout << std::endl;
451 std::cout <<
"9. Using Triggers with Alert Rules" << std::endl;
452 std::cout <<
" ---------------------------------" << std::endl;
455 alert_rule complex_rule(
"complex_system_alert");
479 if (
auto result = complex_rule.
validate(); result.is_ok()) {
480 std::cout <<
" Rule '" << complex_rule.
name() <<
"' validated successfully" << std::endl;
481 std::cout <<
" Trigger type: " << complex_rule.
trigger()->type_name() << std::endl;
482 std::cout <<
" Description: " << complex_rule.
trigger()->description() << std::endl;
484 std::cout << std::endl;
489 std::cout <<
"=== Alert Triggers Example Completed ===" << std::endl;
490 std::cout << std::endl;
491 std::cout <<
"Triggers demonstrated:" << std::endl;
492 std::cout <<
" - ThresholdTrigger (>, >=, <, <=, ==, !=)" << std::endl;
493 std::cout <<
" - RangeTrigger (in_range, out_of_range)" << std::endl;
494 std::cout <<
" - RateOfChangeTrigger (increasing, decreasing, either)" << std::endl;
495 std::cout <<
" - AnomalyTrigger (statistical deviation)" << std::endl;
496 std::cout <<
" - CompositeTrigger (AND, OR, XOR, NOT)" << std::endl;
497 std::cout <<
" - DeltaTrigger (change detection)" << std::endl;
498 std::cout <<
" - AbsentTrigger (missing data)" << std::endl;
499 std::cout <<
" - Custom triggers (periodic, moving average)" << std::endl;