int CompatUtility::GetCheckableNotificationNotificationNumber(const Checkable::Ptr& checkable) { int notification_number = 0; for (const Notification::Ptr& notification : checkable->GetNotifications()) { if (notification->GetNotificationNumber() > notification_number) notification_number = notification->GetNotificationNumber(); } return notification_number; }
int CompatUtility::GetCheckableNotificationNextNotification(const Checkable::Ptr& checkable) { double next_notification = 0.0; for (const Notification::Ptr& notification : checkable->GetNotifications()) { if (next_notification == 0 || notification->GetNextNotification() < next_notification) next_notification = notification->GetNextNotification(); } return static_cast<int>(next_notification); }
int CompatUtility::GetCheckableNotificationLastNotification(const Checkable::Ptr& checkable) { double last_notification = 0.0; for (const Notification::Ptr& notification : checkable->GetNotifications()) { if (notification->GetLastNotification() > last_notification) last_notification = notification->GetLastNotification(); } return static_cast<int>(last_notification); }
int CompatUtility::GetCheckableInNotificationPeriod(const Checkable::Ptr& checkable) { for (const Notification::Ptr& notification : checkable->GetNotifications()) { TimePeriod::Ptr timeperiod = notification->GetPeriod(); if (!timeperiod || timeperiod->IsInside(Utility::GetTime())) return 1; } return 0; }
int CompatUtility::GetCheckableNotificationStateFilter(const Checkable::Ptr& checkable) { unsigned long notification_state_filter = 0; for (const Notification::Ptr& notification : checkable->GetNotifications()) { ObjectLock olock(notification); notification_state_filter |= notification->GetStateFilter(); } return notification_state_filter; }
std::set<UserGroup::Ptr> CompatUtility::GetCheckableNotificationUserGroups(const Checkable::Ptr& checkable) { std::set<UserGroup::Ptr> usergroups; /* Service -> Notifications -> UserGroups */ for (const Notification::Ptr& notification : checkable->GetNotifications()) { ObjectLock olock(notification); for (const UserGroup::Ptr& ug : notification->GetUserGroups()) { usergroups.insert(ug); } } return usergroups; }
String CompatUtility::GetCheckableNotificationNotificationOptions(const Checkable::Ptr& checkable) { Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); unsigned long notification_type_filter = 0; unsigned long notification_state_filter = 0; for (const Notification::Ptr& notification : checkable->GetNotifications()) { notification_type_filter |= notification->GetTypeFilter(); notification_state_filter |= notification->GetStateFilter(); } std::vector<String> notification_options; /* notification state filters */ if (service) { if (notification_state_filter & ServiceWarning) { notification_options.push_back("w"); } if (notification_state_filter & ServiceUnknown) { notification_options.push_back("u"); } if (notification_state_filter & ServiceCritical) { notification_options.push_back("c"); } } else { if (notification_state_filter & HostDown) { notification_options.push_back("d"); } } /* notification type filters */ if (notification_type_filter & NotificationRecovery) { notification_options.push_back("r"); } if ((notification_type_filter & NotificationFlappingStart) || (notification_type_filter & NotificationFlappingEnd)) { notification_options.push_back("f"); } if ((notification_type_filter & NotificationDowntimeStart) || (notification_type_filter & NotificationDowntimeEnd) || (notification_type_filter & NotificationDowntimeRemoved)) { notification_options.push_back("s"); } return boost::algorithm::join(notification_options, ","); }
double CompatUtility::GetCheckableNotificationNotificationInterval(const Checkable::Ptr& checkable) { double notification_interval = -1; for (const Notification::Ptr& notification : checkable->GetNotifications()) { if (notification_interval == -1 || notification->GetInterval() < notification_interval) notification_interval = notification->GetInterval(); } if (notification_interval == -1) notification_interval = 60; return notification_interval / 60.0; }
Dictionary::Ptr ApiActions::DelayNotification(const ConfigObject::Ptr& object, const Dictionary::Ptr& params) { Checkable::Ptr checkable = static_pointer_cast<Checkable>(object); if (!checkable) return ApiActions::CreateResult(404, "Cannot delay notifications for non-existent object"); if (!params->Contains("timestamp")) return ApiActions::CreateResult(403, "A timestamp is required to delay notifications"); BOOST_FOREACH(const Notification::Ptr& notification, checkable->GetNotifications()) { notification->SetNextNotification(HttpUtility::GetLastParameter(params, "timestamp")); } return ApiActions::CreateResult(200, "Successfully delayed notifications for object '" + checkable->GetName() + "'."); }
std::set<User::Ptr> CompatUtility::GetCheckableNotificationUsers(const Checkable::Ptr& checkable) { /* Service -> Notifications -> (Users + UserGroups -> Users) */ std::set<User::Ptr> allUsers; std::set<User::Ptr> users; for (const Notification::Ptr& notification : checkable->GetNotifications()) { ObjectLock olock(notification); users = notification->GetUsers(); std::copy(users.begin(), users.end(), std::inserter(allUsers, allUsers.begin())); for (const UserGroup::Ptr& ug : notification->GetUserGroups()) { std::set<User::Ptr> members = ug->GetMembers(); std::copy(members.begin(), members.end(), std::inserter(allUsers, allUsers.begin())); } } return allUsers; }
void StateHistTable::UpdateLogEntries(const Dictionary::Ptr& log_entry_attrs, int line_count, int lineno, const AddRowFunction& addRowFn) { unsigned int time = log_entry_attrs->Get("time"); String host_name = log_entry_attrs->Get("host_name"); String service_description = log_entry_attrs->Get("service_description"); unsigned long state = log_entry_attrs->Get("state"); int log_type = log_entry_attrs->Get("log_type"); String state_type = log_entry_attrs->Get("state_type"); //SOFT, HARD, STARTED, STOPPED, ... String log_line = log_entry_attrs->Get("message"); /* use message from log table */ Checkable::Ptr checkable; if (service_description.IsEmpty()) checkable = Host::GetByName(host_name); else checkable = Service::GetByNamePair(host_name, service_description); /* invalid log line for state history */ if (!checkable) return; Array::Ptr state_hist_service_states; Dictionary::Ptr state_hist_bag; unsigned long query_part = m_TimeUntil - m_TimeFrom; /* insert new service states array with values if not existing */ if (m_CheckablesCache.find(checkable) == m_CheckablesCache.end()) { /* create new values */ state_hist_service_states = make_shared<Array>(); state_hist_bag = make_shared<Dictionary>(); Service::Ptr service = dynamic_pointer_cast<Service>(checkable); Host::Ptr host; if (service) host = service->GetHost(); else host = static_pointer_cast<Host>(checkable); state_hist_bag->Set("host_name", host->GetName()); if (service) state_hist_bag->Set("service_description", service->GetShortName()); state_hist_bag->Set("state", state); state_hist_bag->Set("in_downtime", 0); state_hist_bag->Set("in_host_downtime", 0); state_hist_bag->Set("in_notification_period", 1); // assume "always" state_hist_bag->Set("is_flapping", 0); state_hist_bag->Set("time", time); state_hist_bag->Set("lineno", lineno); state_hist_bag->Set("log_output", log_line); /* complete line */ state_hist_bag->Set("from", time); /* starting at current timestamp */ state_hist_bag->Set("until", time); /* will be updated later on state change */ state_hist_bag->Set("query_part", query_part); /* required for _part calculations */ state_hist_service_states->Add(state_hist_bag); Log(LogDebug, "StateHistTable", "statehist: Adding new object '" + checkable->GetName() + "' to services cache."); } else { state_hist_service_states = m_CheckablesCache[checkable]; state_hist_bag = state_hist_service_states->Get(state_hist_service_states->GetLength()-1); /* fetch latest state from history */ /* state duration */ /* determine service notifications notification_period and compare against current timestamp */ bool in_notification_period = true; String notification_period_name; BOOST_FOREACH(const Notification::Ptr& notification, checkable->GetNotifications()) { TimePeriod::Ptr notification_period = notification->GetPeriod(); if (notification_period) { if (notification_period->IsInside(static_cast<double>(time))) in_notification_period = true; else in_notification_period = false; notification_period_name = notification_period->GetName(); // last one wins } else in_notification_period = true; // assume "always" } /* check for state changes, flapping & downtime start/end */ switch (log_type) { case LogEntryTypeHostAlert: case LogEntryTypeHostInitialState: case LogEntryTypeHostCurrentState: case LogEntryTypeServiceAlert: case LogEntryTypeServiceInitialState: case LogEntryTypeServiceCurrentState: if (state != state_hist_bag->Get("state")) { /* 1. seal old state_hist_bag */ state_hist_bag->Set("until", time); /* add until record for duration calculation */ /* 2. add new state_hist_bag */ Dictionary::Ptr state_hist_bag_new = make_shared<Dictionary>(); state_hist_bag_new->Set("host_name", state_hist_bag->Get("host_name")); state_hist_bag_new->Set("service_description", state_hist_bag->Get("service_description")); state_hist_bag_new->Set("state", state); state_hist_bag_new->Set("in_downtime", state_hist_bag->Get("in_downtime")); // keep value from previous state! state_hist_bag_new->Set("in_host_downtime", state_hist_bag->Get("in_host_downtime")); // keep value from previous state! state_hist_bag_new->Set("in_notification_period", (in_notification_period ? 1 : 0)); state_hist_bag_new->Set("notification_period", notification_period_name); state_hist_bag_new->Set("is_flapping", state_hist_bag->Get("is_flapping")); // keep value from previous state! state_hist_bag_new->Set("time", time); state_hist_bag_new->Set("lineno", lineno); state_hist_bag_new->Set("log_output", log_line); /* complete line */ state_hist_bag_new->Set("from", time); /* starting at current timestamp */ state_hist_bag_new->Set("until", time + 1); /* will be updated later */ state_hist_bag_new->Set("query_part", query_part); state_hist_service_states->Add(state_hist_bag_new); Log(LogDebug, "StateHistTable", "statehist: State change detected for object '" + checkable->GetName() + "' in '" + log_line + "'."); } break; case LogEntryTypeHostFlapping: case LogEntryTypeServiceFlapping: if (state_type == "STARTED") state_hist_bag->Set("is_flapping", 1); else if (state_type == "STOPPED" || state_type == "DISABLED") state_hist_bag->Set("is_flapping", 0); break; break; case LogEntryTypeHostDowntimeAlert: case LogEntryTypeServiceDowntimeAlert: if (state_type == "STARTED") { state_hist_bag->Set("in_downtime", 1); if (log_type == LogEntryTypeHostDowntimeAlert) state_hist_bag->Set("in_host_downtime", 1); } else if (state_type == "STOPPED" || state_type == "CANCELLED") { state_hist_bag->Set("in_downtime", 0); if (log_type == LogEntryTypeHostDowntimeAlert) state_hist_bag->Set("in_host_downtime", 0); } break; default: //nothing to update break; } } m_CheckablesCache[checkable] = state_hist_service_states; /* TODO find a way to directly call addRowFn() - right now m_ServicesCache depends on historical lines ("already seen service") */ }