bool ServiceGroup::EvaluateObjectRule(const Service::Ptr& service, const ConfigItem::Ptr& group) { String group_name = group->GetName(); CONTEXT("Evaluating rule for group '" + group_name + "'"); Host::Ptr host = service->GetHost(); ScriptFrame frame; if (group->GetScope()) group->GetScope()->CopyTo(frame.Locals); frame.Locals->Set("host", host); frame.Locals->Set("service", service); if (!group->GetFilter()->Evaluate(frame).GetValue().ToBool()) return false; Log(LogDebug, "ServiceGroup") << "Assigning membership for group '" << group_name << "' to service '" << service->GetName() << "'"; Array::Ptr groups = service->GetGroups(); groups->Add(group_name); return true; }
void NagiosCheckTask::ScriptFunc(const ScriptTask::Ptr& task, const vector<Value>& arguments) { if (arguments.size() < 1) throw_exception(invalid_argument("Missing argument: Service must be specified.")); Value vservice = arguments[0]; if (!vservice.IsObjectType<DynamicObject>()) throw_exception(invalid_argument("Argument must be a config object.")); Service::Ptr service = static_cast<Service::Ptr>(vservice); String checkCommand = service->GetCheckCommand(); vector<Dictionary::Ptr> macroDicts; macroDicts.push_back(service->GetMacros()); macroDicts.push_back(service->GetHost()->GetMacros()); macroDicts.push_back(IcingaApplication::GetInstance()->GetMacros()); String command = MacroProcessor::ResolveMacros(checkCommand, macroDicts); Process::Ptr process = boost::make_shared<Process>(command); NagiosCheckTask ct(task, process); ct.m_Result = boost::make_shared<Dictionary>(); ct.m_Result->Set("schedule_start", Utility::GetTime()); process->Start(boost::bind(&NagiosCheckTask::ProcessFinishedHandler, ct)); }
bool ServiceGroup::EvaluateObjectRule(const Service::Ptr service, const ObjectRule& rule) { DebugInfo di = rule.GetDebugInfo(); std::ostringstream msgbuf; msgbuf << "Evaluating 'object' rule (" << di << ")"; CONTEXT(msgbuf.str()); Host::Ptr host = service->GetHost(); Dictionary::Ptr locals = make_shared<Dictionary>(); locals->Set("host", host); locals->Set("service", service); if (!rule.EvaluateFilter(locals)) return false; std::ostringstream msgbuf2; msgbuf2 << "Assigning membership for group '" << rule.GetName() << "' to service '" << service->GetName() << "' for rule " << di; Log(LogDebug, "icinga", msgbuf2.str()); String group_name = rule.GetName(); ServiceGroup::Ptr group = ServiceGroup::GetByName(group_name); if (!group) { Log(LogCritical, "icinga", "Invalid membership assignment. Group '" + group_name + "' does not exist."); return false; } /* assign service group membership */ group->ResolveGroupMembership(service, true); return true; }
Dictionary::Ptr ServiceDbObject::GetConfigFields(void) const { Dictionary::Ptr fields = make_shared<Dictionary>(); Service::Ptr service = static_pointer_cast<Service>(GetObject()); Host::Ptr host = service->GetHost(); fields->Set("host_object_id", host); fields->Set("display_name", service->GetDisplayName()); fields->Set("check_command_object_id", service->GetCheckCommand()); fields->Set("check_command_args", Empty); fields->Set("eventhandler_command_object_id", service->GetEventCommand()); fields->Set("eventhandler_command_args", Empty); fields->Set("notification_timeperiod_object_id", Notification::GetByName(CompatUtility::GetCheckableNotificationNotificationPeriod(service))); fields->Set("check_timeperiod_object_id", service->GetCheckPeriod()); fields->Set("failure_prediction_options", Empty); fields->Set("check_interval", CompatUtility::GetCheckableCheckInterval(service)); fields->Set("retry_interval", CompatUtility::GetCheckableRetryInterval(service)); fields->Set("max_check_attempts", service->GetMaxCheckAttempts()); fields->Set("first_notification_delay", Empty); fields->Set("notification_interval", CompatUtility::GetCheckableNotificationNotificationInterval(service)); fields->Set("notify_on_warning", CompatUtility::GetCheckableNotifyOnWarning(service)); fields->Set("notify_on_unknown", CompatUtility::GetCheckableNotifyOnUnknown(service)); fields->Set("notify_on_critical", CompatUtility::GetCheckableNotifyOnCritical(service)); fields->Set("notify_on_recovery", CompatUtility::GetCheckableNotifyOnRecovery(service)); fields->Set("notify_on_flapping", CompatUtility::GetCheckableNotifyOnFlapping(service)); fields->Set("notify_on_downtime", CompatUtility::GetCheckableNotifyOnDowntime(service)); fields->Set("stalk_on_ok", 0); fields->Set("stalk_on_warning", 0); fields->Set("stalk_on_unknown", 0); fields->Set("stalk_on_critical", 0); fields->Set("is_volatile", CompatUtility::GetCheckableIsVolatile(service)); fields->Set("flap_detection_enabled", CompatUtility::GetCheckableFlapDetectionEnabled(service)); fields->Set("flap_detection_on_ok", Empty); fields->Set("flap_detection_on_warning", Empty); fields->Set("flap_detection_on_unknown", Empty); fields->Set("flap_detection_on_critical", Empty); fields->Set("low_flap_threshold", CompatUtility::GetCheckableLowFlapThreshold(service)); fields->Set("high_flap_threshold", CompatUtility::GetCheckableHighFlapThreshold(service)); fields->Set("process_performance_data", CompatUtility::GetCheckableProcessPerformanceData(service)); fields->Set("freshness_checks_enabled", CompatUtility::GetCheckableFreshnessChecksEnabled(service)); fields->Set("freshness_threshold", CompatUtility::GetCheckableFreshnessThreshold(service)); fields->Set("passive_checks_enabled", CompatUtility::GetCheckablePassiveChecksEnabled(service)); fields->Set("event_handler_enabled", CompatUtility::GetCheckableEventHandlerEnabled(service)); fields->Set("active_checks_enabled", CompatUtility::GetCheckableActiveChecksEnabled(service)); fields->Set("retain_status_information", Empty); fields->Set("retain_nonstatus_information", Empty); fields->Set("notifications_enabled", CompatUtility::GetCheckableNotificationsEnabled(service)); fields->Set("obsess_over_service", Empty); fields->Set("failure_prediction_enabled", Empty); fields->Set("notes", service->GetNotes()); fields->Set("notes_url", service->GetNotesUrl()); fields->Set("action_url", service->GetActionUrl()); fields->Set("icon_image", service->GetIconImage()); fields->Set("icon_image_alt", service->GetIconImageAlt()); return fields; }
void OpenTsdbWriter::CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr) { CONTEXT("Processing check result for '" + checkable->GetName() + "'"); if (!IcingaApplication::GetInstance()->GetEnablePerfdata() || !checkable->GetEnablePerfdata()) return; Service::Ptr service = dynamic_pointer_cast<Service>(checkable); Host::Ptr host; if (service) host = service->GetHost(); else host = static_pointer_cast<Host>(checkable); String metric; std::map<String, String> tags; String escaped_hostName = EscapeTag(host->GetName()); tags["host"] = escaped_hostName; double ts = cr->GetExecutionEnd(); if (service) { String serviceName = service->GetShortName(); String escaped_serviceName = EscapeMetric(serviceName); metric = "icinga.service." + escaped_serviceName; SendMetric(metric + ".state", tags, service->GetState(), ts); } else { metric = "icinga.host"; SendMetric(metric + ".state", tags, host->GetState(), ts); } SendMetric(metric + ".state_type", tags, checkable->GetStateType(), ts); SendMetric(metric + ".reachable", tags, checkable->IsReachable(), ts); SendMetric(metric + ".downtime_depth", tags, checkable->GetDowntimeDepth(), ts); SendMetric(metric + ".acknowledgement", tags, checkable->GetAcknowledgement(), ts); SendPerfdata(metric, tags, cr, ts); metric = "icinga.check"; if (service) { tags["type"] = "service"; String serviceName = service->GetShortName(); String escaped_serviceName = EscapeTag(serviceName); tags["service"] = escaped_serviceName; } else { tags["type"] = "host"; } SendMetric(metric + ".current_attempt", tags, checkable->GetCheckAttempt(), ts); SendMetric(metric + ".max_check_attempts", tags, checkable->GetMaxCheckAttempts(), ts); SendMetric(metric + ".latency", tags, cr->CalculateLatency(), ts); SendMetric(metric + ".execution_time", tags, cr->CalculateExecutionTime(), ts); }
DbObject::Ptr DbObject::GetOrCreateByObject(const ConfigObject::Ptr& object) { boost::mutex::scoped_lock lock(GetStaticMutex()); DbObject::Ptr dbobj = object->GetExtension("DbObject"); if (dbobj) return dbobj; DbType::Ptr dbtype = DbType::GetByName(object->GetType()->GetName()); if (!dbtype) return DbObject::Ptr(); Service::Ptr service; String name1, name2; service = dynamic_pointer_cast<Service>(object); if (service) { Host::Ptr host = service->GetHost(); name1 = service->GetHost()->GetName(); name2 = service->GetShortName(); } else { if (object->GetType() == ConfigType::GetByName("CheckCommand") || object->GetType() == ConfigType::GetByName("EventCommand") || object->GetType() == ConfigType::GetByName("NotificationCommand")) { Command::Ptr command = dynamic_pointer_cast<Command>(object); name1 = CompatUtility::GetCommandName(command); } else name1 = object->GetName(); } dbobj = dbtype->GetOrCreateObjectByName(name1, name2); dbobj->SetObject(object); object->SetExtension("DbObject", dbobj); return dbobj; }
DbObject::Ptr DbObject::GetOrCreateByObject(const DynamicObject::Ptr& object) { DbObject::Ptr dbobj = static_pointer_cast<DbObject>(object->GetExtension("DbObject")); if (dbobj) return dbobj; DbType::Ptr dbtype = DbType::GetByName(object->GetType()->GetName()); if (!dbtype) return DbObject::Ptr(); Service::Ptr service; String name1, name2; service = dynamic_pointer_cast<Service>(object); if (service) { Host::Ptr host = service->GetHost(); if (!host) return DbObject::Ptr(); name1 = service->GetHost()->GetName(); name2 = service->GetShortName(); } else { name1 = object->GetName(); } dbobj = dbtype->GetOrCreateObjectByName(name1, name2); { ObjectLock olock(object); dbobj->SetObject(object); object->SetExtension("DbObject", dbobj); } return dbobj; }
Value ServicesTable::IconImageExpandedAccessor(const Value& row) { Service::Ptr service = static_cast<Service::Ptr>(row); if (!service) return Empty; MacroProcessor::ResolverList resolvers { { "service", service }, { "host", service->GetHost() }, { "icinga", IcingaApplication::GetInstance() } }; return MacroProcessor::ResolveMacros(service->GetIconImage(), resolvers); }
Object::Ptr ServicesTable::HostAccessor(const Value& row, const Column::ObjectAccessor& parentObjectAccessor) { Value service; if (parentObjectAccessor) service = parentObjectAccessor(row, LivestatusGroupByNone, Empty); else service = row; Service::Ptr svc = static_cast<Service::Ptr>(service); if (!svc) return nullptr; return svc->GetHost(); }
void StatusDataWriter::DumpServiceStatus(std::ostream& fp, const Service::Ptr& service) { Host::Ptr host = service->GetHost(); fp << "servicestatus {" "\n" "\t" "host_name=" << host->GetName() << "\n" "\t" "service_description=" << service->GetShortName() << "\n"; { ObjectLock olock(service); DumpCheckableStatusAttrs(fp, service); } fp << "\t" "}" "\n" "\n"; DumpDowntimes(fp, service); DumpComments(fp, service); }
void GraphiteWriter::CheckResultHandler(const Service::Ptr& service, const CheckResult::Ptr& cr) { if (!IcingaApplication::GetInstance()->GetEnablePerfdata() || !service->GetEnablePerfdata()) return; /* TODO: sanitize host and service names */ String hostName = service->GetHost()->GetName(); String serviceName = service->GetShortName(); SanitizeMetric(hostName); SanitizeMetric(serviceName); String prefix = "icinga." + hostName + "." + serviceName; /* basic metrics */ SendMetric(prefix, "current_attempt", service->GetCheckAttempt()); SendMetric(prefix, "max_check_attempts", service->GetMaxCheckAttempts()); SendMetric(prefix, "state_type", service->GetStateType()); SendMetric(prefix, "state", service->GetState()); SendMetric(prefix, "latency", Service::CalculateLatency(cr)); SendMetric(prefix, "execution_time", Service::CalculateExecutionTime(cr)); Value pdv = cr->GetPerformanceData(); if (!pdv.IsObjectType<Dictionary>()) return; Dictionary::Ptr perfdata = pdv; ObjectLock olock(perfdata); BOOST_FOREACH(const Dictionary::Pair& kv, perfdata) { double valueNum; if (!kv.second.IsObjectType<PerfdataValue>()) valueNum = kv.second; else valueNum = static_cast<PerfdataValue::Ptr>(kv.second)->GetValue(); String escaped_key = kv.first; SanitizeMetric(escaped_key); boost::algorithm::replace_all(escaped_key, "::", "."); SendMetric(prefix, escaped_key, valueNum); }
void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification, const User::Ptr& user, const CheckResult::Ptr& cr, int itype, const String& author, const String& comment) { NotificationCommand::Ptr commandObj = notification->GetNotificationCommand(); NotificationType type = static_cast<NotificationType>(itype); Service::Ptr service = notification->GetService(); Value raw_command = commandObj->GetCommandLine(); StaticMacroResolver::Ptr notificationMacroResolver = make_shared<StaticMacroResolver>(); notificationMacroResolver->Add("NOTIFICATIONTYPE", Notification::NotificationTypeToString(type)); notificationMacroResolver->Add("NOTIFICATIONAUTHOR", author); notificationMacroResolver->Add("NOTIFICATIONAUTHORNAME", author); notificationMacroResolver->Add("NOTIFICATIONCOMMENT", comment); std::vector<MacroResolver::Ptr> resolvers; resolvers.push_back(user); resolvers.push_back(notificationMacroResolver); resolvers.push_back(notification); resolvers.push_back(service); resolvers.push_back(service->GetHost()); resolvers.push_back(commandObj); resolvers.push_back(IcingaApplication::GetInstance()); Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, cr, Utility::EscapeShellCmd, commandObj->GetEscapeMacros()); Dictionary::Ptr envMacros = make_shared<Dictionary>(); Array::Ptr export_macros = commandObj->GetExportMacros(); if (export_macros) { BOOST_FOREACH(const String& macro, export_macros) { String value; if (!MacroProcessor::ResolveMacro(macro, resolvers, cr, &value)) { Log(LogWarning, "icinga", "export_macros for notification '" + notification->GetName() + "' refers to unknown macro '" + macro + "'"); continue; } envMacros->Set(macro, value); } }
void PerfdataWriter::CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr) { CONTEXT("Writing performance data for object '" + checkable->GetName() + "'"); if (!IcingaApplication::GetInstance()->GetEnablePerfdata() || !checkable->GetEnablePerfdata()) return; Service::Ptr service = dynamic_pointer_cast<Service>(checkable); Host::Ptr host; if (service) host = service->GetHost(); else host = static_pointer_cast<Host>(checkable); MacroProcessor::ResolverList resolvers; if (service) resolvers.push_back(std::make_pair("service", service)); resolvers.push_back(std::make_pair("host", host)); resolvers.push_back(std::make_pair("icinga", IcingaApplication::GetInstance())); if (service) { String line = MacroProcessor::ResolveMacros(GetServiceFormatTemplate(), resolvers, cr, NULL, &PerfdataWriter::EscapeMacroMetric); { ObjectLock olock(this); if (!m_ServiceOutputFile.good()) return; m_ServiceOutputFile << line << "\n"; } } else { String line = MacroProcessor::ResolveMacros(GetHostFormatTemplate(), resolvers, cr, NULL, &PerfdataWriter::EscapeMacroMetric); { ObjectLock olock(this); if (!m_HostOutputFile.good()) return; m_HostOutputFile << line << "\n"; } } }
void PerfdataWriter::CheckResultHandler(const Service::Ptr& service, const Dictionary::Ptr& cr) { Host::Ptr host = service->GetHost(); if (!host) return; std::vector<MacroResolver::Ptr> resolvers; resolvers.push_back(service); resolvers.push_back(host); resolvers.push_back(IcingaApplication::GetInstance()); String line = MacroProcessor::ResolveMacros(GetFormatTemplate(), resolvers, cr); ObjectLock olock(this); if (!m_OutputFile.good()) return; m_OutputFile << line << "\n"; }
Dictionary::Ptr ServiceDbObject::GetConfigFields(void) const { Dictionary::Ptr fields = boost::make_shared<Dictionary>(); Service::Ptr service = static_pointer_cast<Service>(GetObject()); Host::Ptr host = service->GetHost(); if (!host) return Dictionary::Ptr(); Dictionary::Ptr attrs; { ObjectLock olock(service); attrs = CompatUtility::GetServiceConfigAttributes(service); } fields->Set("host_object_id", host); fields->Set("display_name", service->GetDisplayName()); fields->Set("check_command_object_id", service->GetCheckCommand()); fields->Set("check_command_args", Empty); fields->Set("eventhandler_command_object_id", service->GetEventCommand()); fields->Set("eventhandler_command_args", Empty); fields->Set("notification_timeperiod_object_id", Notification::GetByName(attrs->Get("notification_period"))); fields->Set("check_timeperiod_object_id", service->GetCheckPeriod()); fields->Set("failure_prediction_options", Empty); fields->Set("check_interval", attrs->Get("check_interval")); fields->Set("retry_interval", attrs->Get("retry_interval")); fields->Set("max_check_attempts", attrs->Get("max_check_attempts")); fields->Set("first_notification_delay", Empty); fields->Set("notification_interval", attrs->Get("notification_interval")); fields->Set("notify_on_warning", attrs->Get("notify_on_warning")); fields->Set("notify_on_unknown", attrs->Get("notify_on_unknown")); fields->Set("notify_on_critical", attrs->Get("notify_on_critical")); fields->Set("notify_on_recovery", attrs->Get("notify_on_recovery")); fields->Set("notify_on_flapping", attrs->Get("notify_on_flapping")); fields->Set("notify_on_downtime", attrs->Get("notify_on_downtime")); fields->Set("stalk_on_ok", 0); fields->Set("stalk_on_warning", 0); fields->Set("stalk_on_unknown", 0); fields->Set("stalk_on_critical", 0); fields->Set("is_volatile", attrs->Get("is_volatile")); fields->Set("flap_detection_enabled", attrs->Get("flap_detection_enabled")); fields->Set("flap_detection_on_ok", Empty); fields->Set("flap_detection_on_warning", Empty); fields->Set("flap_detection_on_unknown", Empty); fields->Set("flap_detection_on_critical", Empty); fields->Set("low_flap_threshold", attrs->Get("low_flap_threshold")); fields->Set("high_flap_threshold", attrs->Get("high_flap_threshold")); fields->Set("process_performance_data", attrs->Get("process_performance_data")); fields->Set("freshness_checks_enabled", attrs->Get("freshness_checks_enabled")); fields->Set("freshness_threshold", Empty); fields->Set("passive_checks_enabled", attrs->Get("passive_checks_enabled")); fields->Set("event_handler_enabled", attrs->Get("event_handler_enabled")); fields->Set("active_checks_enabled", attrs->Get("active_checks_enabled")); fields->Set("retain_status_information", Empty); fields->Set("retain_nonstatus_information", Empty); fields->Set("notifications_enabled", attrs->Get("notifications_enabled")); fields->Set("obsess_over_service", Empty); fields->Set("failure_prediction_enabled", Empty); fields->Set("notes", attrs->Get("notes")); fields->Set("notes_url", attrs->Get("notes_url")); fields->Set("action_url", attrs->Get("action_url")); fields->Set("icon_image", attrs->Get("icon_image")); fields->Set("icon_image_alt", attrs->Get("icon_image_alt")); return fields; }
void StatusDataWriter::DumpServiceObject(std::ostream& fp, const Service::Ptr& service) { Host::Ptr host = service->GetHost(); { ObjectLock olock(service); fp << "define service {" "\n" "\t" "host_name" "\t" << host->GetName() << "\n" "\t" "service_description" "\t" << service->GetShortName() << "\n" "\t" "display_name" "\t" << service->GetDisplayName() << "\n" "\t" "check_interval" "\t" << (service->GetCheckInterval() / 60.0) << "\n" "\t" "retry_interval" "\t" << (service->GetRetryInterval() / 60.0) << "\n" "\t" "max_check_attempts" "\t" << service->GetMaxCheckAttempts() << "\n" "\t" "active_checks_enabled" "\t" << Convert::ToLong(service->GetEnableActiveChecks()) << "\n" "\t" "passive_checks_enabled" "\t" << Convert::ToLong(service->GetEnablePassiveChecks()) << "\n" "\t" "flap_detection_enabled" "\t" << Convert::ToLong(service->GetEnableFlapping()) << "\n" "\t" "is_volatile" "\t" << Convert::ToLong(service->GetVolatile()) << "\n" "\t" "notifications_enabled" "\t" << Convert::ToLong(service->GetEnableNotifications()) << "\n" "\t" "notification_options" "\t" << GetNotificationOptions(service) << "\n" "\t" "notification_interval" "\t" << CompatUtility::GetCheckableNotificationNotificationInterval(service) << "\n" "\t" "notification_period" "\t" << "" << "\n" "\t" "event_handler_enabled" "\t" << Convert::ToLong(service->GetEnableEventHandler()) << "\n"; CheckCommand::Ptr checkcommand = service->GetCheckCommand(); if (checkcommand) fp << "\t" "check_command" "\t" << CompatUtility::GetCommandName(checkcommand) << "!" << CompatUtility::GetCheckableCommandArgs(service)<< "\n"; EventCommand::Ptr eventcommand = service->GetEventCommand(); if (eventcommand && service->GetEnableEventHandler()) fp << "\t" "event_handler" "\t" << CompatUtility::GetCommandName(eventcommand) << "\n"; TimePeriod::Ptr checkPeriod = service->GetCheckPeriod(); if (checkPeriod) fp << "\t" "check_period" "\t" << checkPeriod->GetName() << "\n"; fp << "\t" "contacts" "\t"; DumpNameList(fp, CompatUtility::GetCheckableNotificationUsers(service)); fp << "\n"; fp << "\t" "contact_groups" "\t"; DumpNameList(fp, CompatUtility::GetCheckableNotificationUserGroups(service)); fp << "\n"; String notes = service->GetNotes(); String notes_url = service->GetNotesUrl(); String action_url = service->GetActionUrl(); String icon_image = service->GetIconImage(); String icon_image_alt = service->GetIconImageAlt(); fp << "\t" "initial_state" "\t" "o" "\n" "\t" "low_flap_threshold" "\t" << service->GetFlappingThresholdLow() << "\n" "\t" "high_flap_threshold" "\t" << service->GetFlappingThresholdHigh() << "\n" "\t" "process_perf_data" "\t" << Convert::ToLong(service->GetEnablePerfdata()) << "\n" "\t" "check_freshness" << "\t" "1" "\n"; if (!notes.IsEmpty()) fp << "\t" "notes" "\t" << notes << "\n"; if (!notes_url.IsEmpty()) fp << "\t" "notes_url" "\t" << notes_url << "\n"; if (!action_url.IsEmpty()) fp << "\t" "action_url" "\t" << action_url << "\n"; if (!icon_image.IsEmpty()) fp << "\t" "icon_image" "\t" << icon_image << "\n"; if (!icon_image_alt.IsEmpty()) fp << "\t" "icon_image_alt" "\t" << icon_image_alt << "\n"; } fp << "\t" "service_groups" "\t"; bool first = true; Array::Ptr groups = service->GetGroups(); if (groups) { ObjectLock olock(groups); for (const String& name : groups) { ServiceGroup::Ptr sg = ServiceGroup::GetByName(name); if (sg) { if (!first) fp << ","; else first = false; fp << sg->GetName(); } } } fp << "\n"; DumpCustomAttributes(fp, service); fp << "\t" "}" "\n" "\n"; }
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") */ }