static void _handleAction(Event_T E, Action_T A) { ASSERT(E); ASSERT(A); E->flag = Handler_Succeeded; if (A->id != Action_Ignored) { /* Alert and mmonit event notification are common actions */ E->flag |= handle_mmonit(E); E->flag |= handle_alert(E); /* In the case that some subhandler failed, enqueue the event for partial reprocessing */ if (E->flag != Handler_Succeeded) { if (Run.eventlist_dir) _queueAdd(E); else LogError("Aborting event\n"); } /* Action event is handled already. For Instance events we don't want actions like stop to be executed to prevent the disabling of system service monitoring */ if (A->id == Action_Alert || E->id == Event_Instance) { return; } else if (A->id == Action_Exec) { if (E->state_changed || (E->state && A->repeat && E->count % A->repeat == 0)) { LogInfo("'%s' exec: %s\n", E->source->name, A->exec->arg[0]); spawn(E->source, A->exec, E); return; } } else { if (E->source->actionratelist && (A->id == Action_Start || A->id == Action_Restart)) E->source->nstart++; if (E->source->mode == Monitor_Passive && (A->id == Action_Start || A->id == Action_Stop || A->id == Action_Restart)) return; control_service(E->source->name, A->id); } } }
bool win32_windowed_app::setup(const win32_windowed_app_setup_params& params) { set_assert_failed_handler([&](const char* file_name, int line_number, const char* expression) { return handle_assert_failed(file_name, line_number, expression); }); set_alert_handler([&](const char* file_name, int line_number, const char* message) { return handle_alert(file_name, line_number, message); }); set_trace_handler([&](const char* file_name, int line_number, bool add_newline, const char* message) { handle_trace(file_name, line_number, add_newline, message); }); TRACE("win32_windowed_app setup..."); params.trace_dump(); ASSERT(s_wnd_proc_context == nullptr); s_wnd_proc_context = this; ASSERT(params.get_hinstance() != nullptr); ASSERT(!params.get_window_class_name().empty()); ASSERT(!params.get_window_caption().empty()); ASSERT(params.get_idle_proc() != nullptr); _setup_params = params; WNDCLASSEX wc = build_wnd_class_ex(params); if (!::RegisterClassEx(&wc)) { ALERT("RegisterClassEx failed : {0}", get_last_win32_error_message()); return false; } DWORD style = WS_OVERLAPPEDWINDOW; if (params.get_is_visible_by_default()) { style |= WS_VISIBLE; } _hwnd = ::CreateWindow( params.get_window_class_name().c_str(), params.get_window_caption().c_str(), style, 0, 0, 0, 0, nullptr, nullptr, params.get_hinstance(), nullptr); if (_hwnd == nullptr) { ALERT("CreateWindow failed : {0}", get_last_win32_error_message()); return false; } _error_dialog.setup(params.get_error_dialog_resources(), _hwnd, params.get_hinstance()); _process_uid = make_date_time_as_utc_now().to_local_time_string("%m_%d_%H_%M_%S"); return true; }
void win32_cli_app::setup(const win32_cli_app_setup_params& params) { _setup_params = params; _error_handle = ::GetStdHandle(STD_ERROR_HANDLE); _output_handle = ::GetStdHandle(STD_OUTPUT_HANDLE); set_assert_failed_handler([&](const char* file_name, int line_number, const char* expression) { return handle_assert_failed(file_name, line_number, expression); }); set_alert_handler([&](const char* file_name, int line_number, const char* message) { return handle_alert(file_name, line_number, message); }); set_trace_handler([&](const char* file_name, int line_number, bool add_newline, const char* message) { handle_trace(file_name, line_number, add_newline, message); }); }
/** * Reprocess the partially handled event queue */ void Event_queue_process() { /* return in the case that the eventqueue is not enabled or empty */ if (! Run.eventlist_dir || (! (Run.flags & Run_HandlerInit) && ! Run.handler_queue[Handler_Alert] && ! Run.handler_queue[Handler_Mmonit])) return; DIR *dir = opendir(Run.eventlist_dir); if (! dir) { if (errno != ENOENT) LogError("Cannot open the directory %s -- %s\n", Run.eventlist_dir, STRERROR); return; } struct dirent *de = readdir(dir); if (de) DEBUG("Processing postponed events queue\n"); Action_T a; NEW(a); EventAction_T ea; NEW(ea); while (de) { int handlers_passed = 0; /* In the case that all handlers failed, skip the further processing in this cycle. Alert handler is currently defined anytime (either explicitly or localhost by default) */ if ( (Run.mmonits && FLAG(Run.handler_flag, Handler_Mmonit) && FLAG(Run.handler_flag, Handler_Alert)) || FLAG(Run.handler_flag, Handler_Alert)) break; char file_name[PATH_MAX]; snprintf(file_name, sizeof(file_name), "%s/%s", Run.eventlist_dir, de->d_name); if (File_isFile(file_name)) { LogInfo("Processing queued event %s\n", file_name); FILE *file = fopen(file_name, "r"); if (! file) { LogError("Queued event processing failed - cannot open the file %s -- %s\n", file_name, STRERROR); goto error1; } size_t size; /* read event structure version */ int *version = file_readQueue(file, &size); if (! version) { LogError("skipping queued event %s - unknown data format\n", file_name); goto error2; } if (size != sizeof(int)) { LogError("Aborting queued event %s - invalid size %lu\n", file_name, (unsigned long)size); goto error3; } if (*version != EVENT_VERSION) { LogError("Aborting queued event %s - incompatible data format version %d\n", file_name, *version); goto error3; } /* read event structure */ Event_T e = file_readQueue(file, &size); if (! e) goto error3; if (size != sizeof(*e)) goto error4; /* read source */ char *service = file_readQueue(file, &size); if (! service) goto error4; if (! (e->source = Util_getService(service))) { LogError("Aborting queued event %s - service %s not found in monitor configuration\n", file_name, service); FREE(service); goto error4; } FREE(service); /* read message */ if (! (e->message = file_readQueue(file, &size))) goto error4; /* read event action */ Action_Type *action = file_readQueue(file, &size); if (! action) goto error5; if (size != sizeof(Action_Type)) goto error6; a->id = *action; switch (e->state) { case State_Succeeded: case State_ChangedNot: ea->succeeded = a; break; case State_Failed: case State_Changed: case State_Init: ea->failed = a; break; default: LogError("Aborting queue event %s -- invalid state: %d\n", file_name, e->state); goto error6; } e->action = ea; /* Retry all remaining handlers */ /* alert */ if (e->flag & Handler_Alert) { if (Run.flags & Run_HandlerInit) Run.handler_queue[Handler_Alert]++; if ((Run.handler_flag & Handler_Alert) != Handler_Alert) { if ( handle_alert(e) != Handler_Alert ) { e->flag &= ~Handler_Alert; Run.handler_queue[Handler_Alert]--; handlers_passed++; } else { LogError("Alert handler failed, retry scheduled for next cycle\n"); Run.handler_flag |= Handler_Alert; } } } /* mmonit */ if (e->flag & Handler_Mmonit) { if (Run.flags & Run_HandlerInit) Run.handler_queue[Handler_Mmonit]++; if ((Run.handler_flag & Handler_Mmonit) != Handler_Mmonit) { if ( handle_mmonit(e) != Handler_Mmonit ) { e->flag &= ~Handler_Mmonit; Run.handler_queue[Handler_Mmonit]--; handlers_passed++; } else { LogError("M/Monit handler failed, retry scheduled for next cycle\n"); Run.handler_flag |= Handler_Mmonit; } } } /* If no error persists, remove it from the queue */ if (e->flag == Handler_Succeeded) { DEBUG("Removing queued event %s\n", file_name); if (unlink(file_name) < 0) LogError("Failed to remove queued event file '%s' -- %s\n", file_name, STRERROR); } else if (handlers_passed > 0) { DEBUG("Updating queued event %s (some handlers passed)\n", file_name); _queueUpdate(e, file_name); } error6: FREE(action); error5: FREE(e->message); error4: FREE(e); error3: FREE(version); error2: fclose(file); } error1: de = readdir(dir); } Run.flags &= ~Run_HandlerInit; closedir(dir); FREE(a); FREE(ea); }