172 std::cout <<
"=== Alert Notifiers Example ===" << std::endl;
173 std::cout << std::endl;
176 const std::string temp_dir =
"/tmp/alert_notifiers_example";
177 std::filesystem::create_directories(temp_dir);
182 std::cout <<
"1. Alert Formatters" << std::endl;
183 std::cout <<
" -----------------" << std::endl;
188 alert_severity::critical,
195 std::cout <<
" JSON format:" << std::endl;
196 std::cout <<
" " << json_fmt.
format(sample) << std::endl;
197 std::cout << std::endl;
201 std::cout <<
" Text format:" << std::endl;
202 std::cout <<
" " << text_fmt.
format(sample) << std::endl;
203 std::cout << std::endl;
208 std::cout <<
"2. Log Notifier" << std::endl;
209 std::cout <<
" -------------" << std::endl;
211 auto log_notifier_ptr = std::make_shared<log_notifier>(
"system_logger");
213 std::cout <<
" Notifier name: " << log_notifier_ptr->name() << std::endl;
214 std::cout <<
" Ready: " << (log_notifier_ptr->is_ready() ?
"yes" :
"no") << std::endl;
217 std::cout <<
" Sending alert to log notifier..." << std::endl;
218 if (
auto result = log_notifier_ptr->notify(sample); result.is_ok()) {
219 std::cout <<
" Alert logged successfully" << std::endl;
221 std::cout <<
" Failed to log alert: " << result.error().message << std::endl;
223 std::cout << std::endl;
228 std::cout <<
"3. File Notifier" << std::endl;
229 std::cout <<
" --------------" << std::endl;
231 std::string alert_log_path = temp_dir +
"/alerts.log";
232 auto file_notifier_ptr = std::make_shared<file_notifier>(
234 std::make_shared<text_alert_formatter>()
237 std::cout <<
" Notifier name: " << file_notifier_ptr->name() << std::endl;
238 std::cout <<
" Output file: " << alert_log_path << std::endl;
241 std::vector<alert> alerts_to_log = {
247 for (
const auto& a : alerts_to_log) {
248 if (
auto result = file_notifier_ptr->notify(a); !result.is_ok()) {
249 std::cout <<
" Failed to write alert: " << result.error().message << std::endl;
253 std::cout <<
" Wrote " << alerts_to_log.size() <<
" alerts to file" << std::endl;
256 std::cout <<
" File contents:" << std::endl;
257 std::ifstream file(alert_log_path);
259 while (std::getline(file, line)) {
260 std::cout <<
" " << line << std::endl;
262 std::cout << std::endl;
267 std::cout <<
"4. Webhook Notifier Configuration" << std::endl;
268 std::cout <<
" -------------------------------" << std::endl;
271 webhook_cfg.
url =
"https://hooks.example.com/alerts";
272 webhook_cfg.
method =
"POST";
278 webhook_cfg.
add_header(
"Authorization",
"Bearer token-xxx")
279 .
add_header(
"X-Alert-Source",
"monitoring-system");
281 std::cout <<
" URL: " << webhook_cfg.
url << std::endl;
282 std::cout <<
" Method: " << webhook_cfg.
method << std::endl;
283 std::cout <<
" Timeout: " << webhook_cfg.
timeout.count() <<
"ms" << std::endl;
284 std::cout <<
" Max retries: " << webhook_cfg.
max_retries << std::endl;
285 std::cout <<
" Headers:" << std::endl;
286 for (
const auto& [key, value] : webhook_cfg.
headers) {
287 std::cout <<
" " << key <<
": " << value << std::endl;
289 std::cout << std::endl;
292 auto webhook_notifier_ptr = std::make_shared<webhook_notifier>(
294 std::make_shared<json_alert_formatter>()
297 std::cout <<
" Notifier name: " << webhook_notifier_ptr->name() << std::endl;
298 std::cout <<
" Ready: " << (webhook_notifier_ptr->is_ready() ?
"yes" :
"no")
299 <<
" (no HTTP sender configured)" << std::endl;
302 int http_call_count = 0;
303 webhook_notifier_ptr->set_http_sender(
304 [&http_call_count](
const std::string& url,
305 const std::string& method,
306 const std::unordered_map<std::string, std::string>& headers,
307 const std::string& body) -> kcenon::common::VoidResult {
309 std::cout <<
" [MOCK HTTP] " << method <<
" " << url << std::endl;
310 std::cout <<
" [MOCK HTTP] Headers: " << headers.size() << std::endl;
311 std::cout <<
" [MOCK HTTP] Body length: " << body.length() <<
" chars" << std::endl;
312 return kcenon::common::ok();
316 std::cout <<
" Ready after setting HTTP sender: "
317 << (webhook_notifier_ptr->is_ready() ?
"yes" :
"no") << std::endl;
320 std::cout <<
" Testing webhook notification:" << std::endl;
321 if (
auto result = webhook_notifier_ptr->notify(sample); result.is_ok()) {
322 std::cout <<
" Webhook notification sent (HTTP calls: " << http_call_count <<
")" << std::endl;
324 std::cout << std::endl;
329 std::cout <<
"5. Callback Notifier" << std::endl;
330 std::cout <<
" ------------------" << std::endl;
332 size_t callback_count = 0;
333 auto callback_notifier_ptr = std::make_shared<callback_notifier>(
335 [&callback_count](
const alert& a) {
337 std::cout <<
" [CALLBACK] Received: " << a.
name
342 callback_count += group.size();
343 std::cout <<
" [CALLBACK GROUP] Received group: " << group.group_key
344 <<
" (" << group.size() <<
" alerts)" << std::endl;
348 std::cout <<
" Testing callback notifier:" << std::endl;
349 callback_notifier_ptr->notify(sample);
350 std::cout <<
" Callbacks executed: " << callback_count << std::endl;
351 std::cout << std::endl;
356 std::cout <<
"6. Multi Notifier (Multiple Targets)" << std::endl;
357 std::cout <<
" -----------------------------------" << std::endl;
359 auto multi = std::make_shared<multi_notifier>(
"multi_channel");
362 auto log_child = std::make_shared<log_notifier>(
"log_child");
363 auto stats_child = std::make_shared<statistics_notifier>(
"stats_child");
364 auto console_child = std::make_shared<console_color_notifier>(
"console_child");
366 multi->add_notifier(log_child);
367 multi->add_notifier(stats_child);
368 multi->add_notifier(console_child);
370 std::cout <<
" Added 3 child notifiers to multi_channel" << std::endl;
371 std::cout <<
" Sending alert to all channels:" << std::endl;
373 if (
auto result = multi->notify(sample); result.is_ok()) {
374 std::cout <<
" All notifiers succeeded" << std::endl;
376 std::cout <<
" Some notifiers failed: " << result.error().message << std::endl;
378 std::cout << std::endl;
383 std::cout <<
"7. Buffered Notifier (Batching)" << std::endl;
384 std::cout <<
" -----------------------------" << std::endl;
386 auto inner_notifier = std::make_shared<statistics_notifier>(
"buffered_inner");
387 auto buffered = std::make_shared<buffered_notifier>(
393 std::cout <<
" Buffer size: 5, flush interval: 10s" << std::endl;
394 std::cout <<
" Sending alerts (will buffer until size reached):" << std::endl;
396 for (
int i = 1; i <= 7; ++i) {
398 "buffered_alert_" + std::to_string(i),
399 alert_severity::warning,
401 static_cast<double>(i * 10)
404 std::cout <<
" Sent alert " << i <<
", pending: " << buffered->pending_count() << std::endl;
408 std::cout <<
" Forcing flush of remaining alerts..." << std::endl;
410 std::cout <<
" Pending after flush: " << buffered->pending_count() << std::endl;
412 inner_notifier->print_statistics();
413 std::cout << std::endl;
418 std::cout <<
"8. Routing Notifier (Conditional Routing)" << std::endl;
419 std::cout <<
" ---------------------------------------" << std::endl;
421 auto router = std::make_shared<routing_notifier>(
"alert_router");
424 auto critical_notifier = std::make_shared<console_color_notifier>(
"critical_channel");
425 auto warning_notifier = std::make_shared<console_color_notifier>(
"warning_channel");
426 auto default_notifier = std::make_shared<console_color_notifier>(
"default_channel");
429 router->route_by_severity(alert_severity::critical, critical_notifier);
430 router->route_by_severity(alert_severity::emergency, critical_notifier);
431 router->route_by_severity(alert_severity::warning, warning_notifier);
432 router->set_default_route(default_notifier);
434 std::cout <<
" Routing rules configured:" << std::endl;
435 std::cout <<
" - critical/emergency -> critical_channel" << std::endl;
436 std::cout <<
" - warning -> warning_channel" << std::endl;
437 std::cout <<
" - default -> default_channel" << std::endl;
438 std::cout << std::endl;
440 std::cout <<
" Testing routing with different severities:" << std::endl;
442 std::vector<alert> routing_tests = {
443 create_sample_alert(
"critical_alert", alert_severity::critical, alert_state::firing, 99.0),
448 for (
const auto& a : routing_tests) {
449 std::cout <<
" Routing '" << a.
name <<
"' (severity: "
453 std::cout << std::endl;
456 std::cout <<
" Adding label-based routing:" << std::endl;
457 auto ops_notifier = std::make_shared<console_color_notifier>(
"ops_team_channel");
458 router->route_by_label(
"team",
"ops", ops_notifier);
460 auto ops_alert =
create_sample_alert(
"ops_alert", alert_severity::info, alert_state::firing, 60.0,
"ops");
461 std::cout <<
" Routing alert with team=ops:" << std::endl;
462 router->notify(ops_alert);
463 std::cout << std::endl;
468 std::cout <<
"9. Custom Notifier Implementation" << std::endl;
469 std::cout <<
" -------------------------------" << std::endl;
472 auto stats = std::make_shared<statistics_notifier>(
"alert_statistics");
475 std::vector<alert> stat_alerts = {
483 for (
const auto& a : stat_alerts) {
487 stats->print_statistics();
488 std::cout << std::endl;
493 std::cout <<
"10. Alert Group Notification" << std::endl;
494 std::cout <<
" -------------------------" << std::endl;
505 std::cout <<
" Group: " << group.
group_key << std::endl;
506 std::cout <<
" Alerts: " << group.
size() << std::endl;
508 std::cout << std::endl;
511 std::cout <<
" JSON formatted group:" << std::endl;
512 std::cout <<
" " << json_fmt.
format_group(group) << std::endl;
513 std::cout << std::endl;
516 auto group_stats = std::make_shared<statistics_notifier>(
"group_stats");
517 group_stats->notify_group(group);
518 group_stats->print_statistics();
519 std::cout << std::endl;
524 std::cout <<
"11. Error Handling" << std::endl;
525 std::cout <<
" ---------------" << std::endl;
529 fail_cfg.
url =
"https://failing.example.com/alerts";
533 auto failing_webhook = std::make_shared<webhook_notifier>(fail_cfg);
536 failing_webhook->set_http_sender(
537 [&retry_count](
const std::string& ,
539 const std::unordered_map<std::string, std::string>& ,
540 const std::string& ) -> kcenon::common::VoidResult {
542 std::cout <<
" HTTP attempt " << retry_count <<
" - simulating failure" << std::endl;
543 return kcenon::common::VoidResult::err(500,
"Simulated server error");
547 std::cout <<
" Testing webhook with simulated failures:" << std::endl;
548 auto fail_result = failing_webhook->notify(sample);
549 if (!fail_result.is_ok()) {
550 std::cout <<
" Expected failure after " << retry_count <<
" attempts: "
551 << fail_result.error().message << std::endl;
553 std::cout << std::endl;
558 std::cout <<
"12. Cleanup" << std::endl;
559 std::cout <<
" -------" << std::endl;
562 std::filesystem::remove_all(temp_dir);
563 std::cout <<
" Removed temporary directory: " << temp_dir << std::endl;
564 std::cout << std::endl;
566 std::cout <<
"=== Alert Notifiers Example Completed ===" << std::endl;
567 std::cout << std::endl;
568 std::cout <<
"Notifiers demonstrated:" << std::endl;
569 std::cout <<
" - LogNotifier (built-in logging)" << std::endl;
570 std::cout <<
" - FileNotifier (file-based alerts)" << std::endl;
571 std::cout <<
" - WebhookNotifier (HTTP webhooks)" << std::endl;
572 std::cout <<
" - CallbackNotifier (custom callbacks)" << std::endl;
573 std::cout <<
" - MultiNotifier (multiple targets)" << std::endl;
574 std::cout <<
" - BufferedNotifier (batching)" << std::endl;
575 std::cout <<
" - RoutingNotifier (conditional routing)" << std::endl;
576 std::cout <<
" - Custom implementations (color console, statistics)" << std::endl;
577 std::cout <<
" - Alert formatters (JSON, text)" << std::endl;