void ElasticsearchWriter::NotificationSentToAllUsersHandlerInternal(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const std::set<User::Ptr>& users, NotificationType type, const CheckResult::Ptr& cr, const String& author, const String& text) { AssertOnWorkQueue(); CONTEXT("Elasticwriter processing notification to all users '" + checkable->GetName() + "'"); Log(LogDebug, "ElasticsearchWriter") << "Processing notification for '" << checkable->GetName() << "'"; Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); String notificationTypeString = Notification::NotificationTypeToString(type); Dictionary::Ptr fields = new Dictionary(); if (service) { fields->Set("service", service->GetShortName()); fields->Set("state", service->GetState()); fields->Set("last_state", service->GetLastState()); fields->Set("last_hard_state", service->GetLastHardState()); } else { fields->Set("state", host->GetState()); fields->Set("last_state", host->GetLastState()); fields->Set("last_hard_state", host->GetLastHardState()); } fields->Set("host", host->GetName()); ArrayData userNames; for (const User::Ptr& user : users) { userNames.push_back(user->GetName()); } fields->Set("users", new Array(std::move(userNames))); fields->Set("notification_type", notificationTypeString); fields->Set("author", author); fields->Set("text", text); CheckCommand::Ptr commandObj = checkable->GetCheckCommand(); if (commandObj) fields->Set("check_command", commandObj->GetName()); double ts = Utility::GetTime(); if (cr) { AddCheckResult(fields, checkable, cr); ts = cr->GetExecutionEnd(); } Enqueue(checkable, "notification", fields, ts); }
Dictionary::Ptr ApiActions::ProcessCheckResult(const ConfigObject::Ptr& object, const Dictionary::Ptr& params) { Checkable::Ptr checkable = static_pointer_cast<Checkable>(object); if (!checkable) return ApiActions::CreateResult(404, "Cannot process passive check result for non-existent object."); if (!checkable->GetEnablePassiveChecks()) return ApiActions::CreateResult(403, "Passive checks are disabled for object '" + checkable->GetName() + "'."); Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); if (!params->Contains("exit_status")) return ApiActions::CreateResult(403, "Parameter 'exit_status' is required."); int exitStatus = HttpUtility::GetLastParameter(params, "exit_status"); ServiceState state; if (!service) { if (exitStatus == 0) state = ServiceOK; else if (exitStatus == 1) state = ServiceCritical; else return ApiActions::CreateResult(403, "Invalid 'exit_status' for Host " + checkable->GetName() + "."); } else { state = PluginUtility::ExitStatusToState(exitStatus); } if (!params->Contains("plugin_output")) return ApiActions::CreateResult(403, "Parameter 'plugin_output' is required"); CheckResult::Ptr cr = new CheckResult(); cr->SetOutput(HttpUtility::GetLastParameter(params, "plugin_output")); cr->SetState(state); cr->SetCheckSource(HttpUtility::GetLastParameter(params, "check_source")); cr->SetPerformanceData(params->Get("performance_data")); cr->SetCommand(params->Get("check_command")); checkable->ProcessCheckResult(cr); /* Reschedule the next check. The side effect of this is that for as long * as we receive passive results for a service we won't execute any * active checks. */ checkable->SetNextCheck(Utility::GetTime() + checkable->GetCheckInterval()); return ApiActions::CreateResult(200, "Successfully processed check result for object '" + checkable->GetName() + "'."); }
Dictionary::Ptr ApiActions::AddComment(const ConfigObject::Ptr& object, const Dictionary::Ptr& params) { Checkable::Ptr checkable = static_pointer_cast<Checkable>(object); if (!checkable) return ApiActions::CreateResult(404, "Cannot add comment for non-existent object"); if (!params->Contains("author") || !params->Contains("comment")) return ApiActions::CreateResult(403, "Comments require author and comment."); String commentName = Comment::AddComment(checkable, CommentUser, HttpUtility::GetLastParameter(params, "author"), HttpUtility::GetLastParameter(params, "comment"), 0); Comment::Ptr comment = Comment::GetByName(commentName); Dictionary::Ptr additional = new Dictionary(); additional->Set("name", commentName); additional->Set("legacy_id", comment->GetLegacyId()); return ApiActions::CreateResult(200, "Successfully added comment '" + commentName + "' for object '" + checkable->GetName() + "'.", additional); }
void ElasticsearchWriter::Enqueue(const Checkable::Ptr& checkable, const String& type, const Dictionary::Ptr& fields, double ts) { /* Atomically buffer the data point. */ boost::mutex::scoped_lock lock(m_DataBufferMutex); /* Format the timestamps to dynamically select the date datatype inside the index. */ fields->Set("@timestamp", FormatTimestamp(ts)); fields->Set("timestamp", FormatTimestamp(ts)); String eventType = m_EventPrefix + type; fields->Set("type", eventType); /* Every payload needs a line describing the index. * We do it this way to avoid problems with a near full queue. */ String indexBody = "{\"index\": {} }\n"; String fieldsBody = JsonEncode(fields); Log(LogDebug, "ElasticsearchWriter") << "Checkable '" << checkable->GetName() << "' adds to metric list: '" << fieldsBody << "'."; m_DataBuffer.emplace_back(indexBody + fieldsBody); /* Flush if we've buffered too much to prevent excessive memory use. */ if (static_cast<int>(m_DataBuffer.size()) >= GetFlushThreshold()) { Log(LogDebug, "ElasticsearchWriter") << "Data buffer overflow writing " << m_DataBuffer.size() << " data points"; Flush(); } }
void ScheduledDowntime::EvaluateApplyRuleOneInstance(const Checkable::Ptr& checkable, const String& name, const Dictionary::Ptr& locals, const ApplyRule& rule) { DebugInfo di = rule.GetDebugInfo(); Log(LogDebug, "ScheduledDowntime") << "Applying scheduled downtime '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di; ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di); builder->SetType("ScheduledDowntime"); builder->SetName(name); builder->SetScope(locals); Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); builder->AddExpression(new SetExpression(MakeIndexer("host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di)); if (service) builder->AddExpression(new SetExpression(MakeIndexer("service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di)); String zone = checkable->GetZone(); if (!zone.IsEmpty()) { builder->AddExpression(new SetExpression(MakeIndexer("zone"), OpSetLiteral, MakeLiteral(zone), di)); } builder->AddExpression(new OwnedExpression(rule.GetExpression())); ConfigItem::Ptr downtimeItem = builder->Compile(); DynamicObject::Ptr dobj = downtimeItem->Commit(); dobj->OnConfigLoaded(); }
void PluginCheckTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, const Value& commandLine, const ProcessResult& pr) { Checkable::DecreasePendingChecks(); if (pr.ExitStatus > 3) { Process::Arguments parguments = Process::PrepareCommand(commandLine); Log(LogWarning, "PluginCheckTask") << "Check command for object '" << checkable->GetName() << "' (PID: " << pr.PID << ", arguments: " << Process::PrettyPrintArguments(parguments) << ") terminated with exit code " << pr.ExitStatus << ", output: " << pr.Output; } String output = pr.Output.Trim(); std::pair<String, String> co = PluginUtility::ParseCheckOutput(output); cr->SetCommand(commandLine); cr->SetOutput(co.first); cr->SetPerformanceData(PluginUtility::SplitPerfdata(co.second)); cr->SetState(PluginUtility::ExitStatusToState(pr.ExitStatus)); cr->SetExitStatus(pr.ExitStatus); cr->SetExecutionStart(pr.ExecutionStart); cr->SetExecutionEnd(pr.ExecutionEnd); checkable->ProcessCheckResult(cr); }
void Downtime::Start(bool runtimeCreated) { ObjectImpl<Downtime>::Start(runtimeCreated); { boost::mutex::scoped_lock lock(l_DowntimeMutex); SetLegacyId(l_NextDowntimeID); l_LegacyDowntimesCache[l_NextDowntimeID] = GetName(); l_NextDowntimeID++; } Checkable::Ptr checkable = GetCheckable(); checkable->RegisterDowntime(this); if (runtimeCreated) OnDowntimeAdded(this); /* if this object is already in a NOT-OK state trigger * this downtime now *after* it has been added (important * for DB IDO, etc.) */ if (checkable->GetStateRaw() != ServiceOK) { Log(LogNotice, "Downtime") << "Checkable '" << checkable->GetName() << "' already in a NOT-OK state." << " Triggering downtime now."; TriggerDowntime(); } }
void GelfWriter::NotificationToUserHandler(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const User::Ptr& user, NotificationType notification_type, CheckResult::Ptr const& cr, const String& author, const String& comment_text, const String& command_name) { CONTEXT("GELF Processing notification to all users '" + checkable->GetName() + "'"); Log(LogDebug, "GelfWriter") << "GELF Processing notification for '" << checkable->GetName() << "'"; Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); String notification_type_str = Notification::NotificationTypeToString(notification_type); String author_comment = ""; if (notification_type == NotificationCustom || notification_type == NotificationAcknowledgement) { author_comment = author + ";" + comment_text; } String output; if (cr) output = CompatUtility::GetCheckResultOutput(cr); Dictionary::Ptr fields = new Dictionary(); if (service) { fields->Set("_type", "SERVICE NOTIFICATION"); fields->Set("_service", service->GetShortName()); fields->Set("short_message", output); } else { fields->Set("_type", "HOST NOTIFICATION"); fields->Set("short_message", "(" + (host->IsReachable() ? Host::StateToString(host->GetState()) : String("UNREACHABLE")) + ")"); } fields->Set("_state", service ? Service::StateToString(service->GetState()) : Host::StateToString(host->GetState())); fields->Set("_hostname", host->GetName()); fields->Set("_command", command_name); fields->Set("_notification_type", notification_type_str); fields->Set("_comment", author_comment); SendLogMessage(ComposeGelfMessage(fields, GetSource())); }
void LogstashWriter::NotificationToUserHandler(const Notification::Ptr& notification, const Checkable::Ptr& checkable, const User::Ptr& user, NotificationType notification_type, CheckResult::Ptr const& cr, const String& author, const String& comment_text, const String& command_name) { CONTEXT("Logstash Processing notification to all users '" + checkable->GetName() + "'"); Log(LogDebug, "LogstashWriter") << "Processing notification for '" << checkable->GetName() << "'"; Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); String notification_type_str = Notification::NotificationTypeToString(notification_type); String author_comment = ""; if (notification_type == NotificationCustom || notification_type == NotificationAcknowledgement) { author_comment = author + ";" + comment_text; } double ts = Utility::GetTime(); Dictionary::Ptr fields = new Dictionary(); if (service) { fields->Set("type", "SERVICE NOTIFICATION"); fields->Set("service_name", service->GetShortName()); } else { fields->Set("type", "HOST NOTIFICATION"); } if (cr) { fields->Set("plugin_output", cr->GetOutput()); ts = cr->GetExecutionEnd(); } fields->Set("state", service ? Service::StateToString(service->GetState()) : Host::StateToString(host->GetState())); fields->Set("host_name", host->GetName()); fields->Set("command", command_name); fields->Set("notification_type", notification_type_str); fields->Set("comment", author_comment); SendLogMessage(ComposeLogstashMessage(fields, GetSource(), ts)); }
void CheckerComponent::ExecuteCheckHelper(const Checkable::Ptr& checkable) { try { checkable->ExecuteCheck(); } catch (const std::exception& ex) { CheckResult::Ptr cr = new CheckResult(); cr->SetState(ServiceUnknown); String output = "Exception occurred while checking '" + checkable->GetName() + "': " + DiagnosticInformation(ex); cr->SetOutput(output); double now = Utility::GetTime(); cr->SetScheduleStart(now); cr->SetScheduleEnd(now); cr->SetExecutionStart(now); cr->SetExecutionEnd(now); checkable->ProcessCheckResult(cr); Log(LogCritical, "checker", output); } Checkable::DecreasePendingChecks(); { boost::mutex::scoped_lock lock(m_Mutex); /* remove the object from the list of pending objects; if it's not in the * list this was a manual (i.e. forced) check and we must not re-add the * object to the list because it's already there. */ auto it = m_PendingCheckables.find(checkable); if (it != m_PendingCheckables.end()) { m_PendingCheckables.erase(it); if (checkable->IsActive()) m_IdleCheckables.insert(GetCheckableScheduleInfo(checkable)); m_CV.notify_all(); } } Log(LogDebug, "CheckerComponent") << "Check finished for object '" << checkable->GetName() << "'"; }
Value ClusterEvents::SendNotificationsAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params) { Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint(); if (!endpoint) { Log(LogNotice, "ClusterEvents") << "Discarding 'send notification' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed)."; return Empty; } Host::Ptr host = Host::GetByName(params->Get("host")); if (!host) return Empty; Checkable::Ptr checkable; if (params->Contains("service")) checkable = host->GetServiceByShortName(params->Get("service")); else checkable = host; if (!checkable) return Empty; if (origin->FromZone && origin->FromZone != Zone::GetLocalZone()) { Log(LogNotice, "ClusterEvents") << "Discarding 'send custom notification' message for checkable '" << checkable->GetName() << "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access."; return Empty; } CheckResult::Ptr cr; Array::Ptr vperf; if (params->Contains("cr")) { cr = new CheckResult(); Dictionary::Ptr vcr = params->Get("cr"); if (vcr && vcr->Contains("performance_data")) { vperf = vcr->Get("performance_data"); if (vperf) vcr->Remove("performance_data"); Deserialize(cr, vcr, true); } } NotificationType type = static_cast<NotificationType>(static_cast<int>(params->Get("type"))); String author = params->Get("author"); String text = params->Get("text"); Checkable::OnNotificationsRequested(checkable, type, cr, author, text, origin); return Empty; }
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); }
void PluginNotificationTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, const Value& commandLine, const ProcessResult& pr) { if (pr.ExitStatus != 0) { Process::Arguments parguments = Process::PrepareCommand(commandLine); Log(LogWarning, "PluginNotificationTask", "Notification command for object '" + checkable->GetName() + "' (PID: " + Convert::ToString(pr.PID) + ", arguments: " + Process::PrettyPrintArguments(parguments) + ") terminated with exit code " + Convert::ToString(pr.ExitStatus) + ", output: " + pr.Output); } }
void PluginEventTask::ProcessFinishedHandler(const Checkable::Ptr& checkable, const Value& commandLine, const ProcessResult& pr) { if (pr.ExitStatus != 0) { Process::Arguments parguments = Process::PrepareCommand(commandLine); Log(LogNotice, "PluginEventTask") << "Event command for object '" << checkable->GetName() << "' (PID: " << pr.PID << ", arguments: " << Process::PrettyPrintArguments(parguments) << ") terminated with exit code " << pr.ExitStatus << ", output: " << pr.Output; } }
Dictionary::Ptr ApiActions::AcknowledgeProblem(const ConfigObject::Ptr& object, const Dictionary::Ptr& params) { Checkable::Ptr checkable = static_pointer_cast<Checkable>(object); if (!checkable) return ApiActions::CreateResult(404, "Cannot acknowledge problem for non-existent object."); if (!params->Contains("author") || !params->Contains("comment")) return ApiActions::CreateResult(403, "Acknowledgements require author and comment."); AcknowledgementType sticky = AcknowledgementNormal; bool notify = false; double timestamp = 0.0; if (params->Contains("sticky")) sticky = AcknowledgementSticky; if (params->Contains("notify")) notify = true; if (params->Contains("expiry")) timestamp = HttpUtility::GetLastParameter(params, "expiry"); else timestamp = 0; Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); if (!service) { if (host->GetState() == HostUp) return ApiActions::CreateResult(409, "Host " + checkable->GetName() + " is UP."); } else { if (service->GetState() == ServiceOK) return ApiActions::CreateResult(409, "Service " + checkable->GetName() + " is OK."); } Comment::AddComment(checkable, CommentAcknowledgement, HttpUtility::GetLastParameter(params, "author"), HttpUtility::GetLastParameter(params, "comment"), timestamp); checkable->AcknowledgeProblem(HttpUtility::GetLastParameter(params, "author"), HttpUtility::GetLastParameter(params, "comment"), sticky, notify, timestamp); return ApiActions::CreateResult(200, "Successfully acknowledged problem for object '" + checkable->GetName() + "'."); }
void ServiceDbObject::OnConfigUpdate(void) { Service::Ptr service = static_pointer_cast<Service>(GetObject()); /* service dependencies */ Log(LogDebug, "db_ido", "service dependencies for '" + service->GetName() + "'"); BOOST_FOREACH(const Dependency::Ptr& dep, service->GetDependencies()) { Checkable::Ptr parent = dep->GetParent(); if (!parent) continue; Log(LogDebug, "db_ido", "service parents: " + parent->GetName()); int state_filter = dep->GetStateFilter(); /* service dependencies */ Dictionary::Ptr fields1 = make_shared<Dictionary>(); fields1->Set("service_object_id", parent); fields1->Set("dependent_service_object_id", service); fields1->Set("inherits_parent", 1); fields1->Set("timeperiod_object_id", dep->GetPeriod()); fields1->Set("fail_on_ok", (state_filter & StateFilterOK) ? 1 : 0); fields1->Set("fail_on_warning", (state_filter & StateFilterWarning) ? 1 : 0); fields1->Set("fail_on_critical", (state_filter & StateFilterCritical) ? 1 : 0); fields1->Set("fail_on_unknown", (state_filter & StateFilterUnknown) ? 1 : 0); fields1->Set("instance_id", 0); /* DbConnection class fills in real ID */ DbQuery query1; query1.Table = GetType()->GetTable() + "dependencies"; query1.Type = DbQueryInsert; query1.Category = DbCatConfig; query1.Fields = fields1; OnQuery(query1); } /* service contacts, contactgroups */ Log(LogDebug, "db_ido", "service contacts: " + service->GetName()); BOOST_FOREACH(const User::Ptr& user, CompatUtility::GetCheckableNotificationUsers(service)) { Log(LogDebug, "db_ido", "service contacts: " + user->GetName()); Dictionary::Ptr fields_contact = make_shared<Dictionary>(); fields_contact->Set("service_id", DbValue::FromObjectInsertID(service)); fields_contact->Set("contact_object_id", user); fields_contact->Set("instance_id", 0); /* DbConnection class fills in real ID */ DbQuery query_contact; query_contact.Table = GetType()->GetTable() + "_contacts"; query_contact.Type = DbQueryInsert; query_contact.Category = DbCatConfig; query_contact.Fields = fields_contact; OnQuery(query_contact); }
String Comment::AddComment(const Checkable::Ptr& checkable, CommentType entryType, const String& author, const String& text, double expireTime, const String& id, const MessageOrigin::Ptr& origin) { String fullName; if (id.IsEmpty()) fullName = checkable->GetName() + "!" + Utility::NewUniqueID(); else fullName = id; Dictionary::Ptr attrs = new Dictionary(); attrs->Set("author", author); attrs->Set("text", text); attrs->Set("expire_time", expireTime); attrs->Set("entry_type", entryType); attrs->Set("entry_time", Utility::GetTime()); Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); attrs->Set("host_name", host->GetName()); if (service) attrs->Set("service_name", service->GetShortName()); String zone = checkable->GetZoneName(); if (!zone.IsEmpty()) attrs->Set("zone", zone); String config = ConfigObjectUtility::CreateObjectConfig(Comment::TypeInstance, fullName, true, Array::Ptr(), attrs); Array::Ptr errors = new Array(); if (!ConfigObjectUtility::CreateObject(Comment::TypeInstance, fullName, config, errors)) { ObjectLock olock(errors); for (const String& error : errors) { Log(LogCritical, "Comment", error); } BOOST_THROW_EXCEPTION(std::runtime_error("Could not create comment.")); } Comment::Ptr comment = Comment::GetByName(fullName); if (!comment) BOOST_THROW_EXCEPTION(std::runtime_error("Could not create comment.")); Log(LogNotice, "Comment") << "Added comment '" << comment->GetName() << "'."; return fullName; }
String ServiceDbObject::CalculateConfigHash(const Dictionary::Ptr& configFields) const { String hashData = DbObject::CalculateConfigHash(configFields); Service::Ptr service = static_pointer_cast<Service>(GetObject()); Array::Ptr groups = service->GetGroups(); if (groups) hashData += DbObject::HashValue(groups); Array::Ptr dependencies = new Array(); /* dependencies */ for (const Dependency::Ptr& dep : service->GetDependencies()) { Checkable::Ptr parent = dep->GetParent(); if (!parent) continue; Array::Ptr depInfo = new Array(); depInfo->Add(parent->GetName()); depInfo->Add(dep->GetStateFilter()); depInfo->Add(dep->GetPeriodRaw()); dependencies->Add(depInfo); } dependencies->Sort(); hashData += DbObject::HashValue(dependencies); Array::Ptr users = new Array(); for (const User::Ptr& user : CompatUtility::GetCheckableNotificationUsers(service)) { users->Add(user->GetName()); } users->Sort(); hashData += DbObject::HashValue(users); Array::Ptr userGroups = new Array(); for (const UserGroup::Ptr& usergroup : CompatUtility::GetCheckableNotificationUserGroups(service)) { userGroups->Add(usergroup->GetName()); } userGroups->Sort(); hashData += DbObject::HashValue(userGroups); return SHA256(hashData); }
Dictionary::Ptr ApiActions::RemoveAllComments(const ConfigObject::Ptr& object, const Dictionary::Ptr& params) { Checkable::Ptr checkable = static_pointer_cast<Checkable>(object); if (!checkable) return ApiActions::CreateResult(404, "Cannot remove comment form non-existent object."); checkable->RemoveAllComments(); return ApiActions::CreateResult(200, "Successfully removed comments for object '" + checkable->GetName() + "'."); }
void LogstashWriter::StateChangeHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, StateType type) { CONTEXT("Logstash Processing state change '" + checkable->GetName() + "'"); Log(LogDebug, "LogstashWriter") << "Processing state change for '" << checkable->GetName() << "'"; Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); Dictionary::Ptr fields = new Dictionary(); fields->Set("state", service ? Service::StateToString(service->GetState()) : Host::StateToString(host->GetState())); fields->Set("type", "StateChange"); fields->Set("current_check_attempt", checkable->GetCheckAttempt()); fields->Set("max_check_attempts", checkable->GetMaxCheckAttempts()); fields->Set("hostname", host->GetName()); if (service) { fields->Set("service_name", service->GetShortName()); fields->Set("service_state", Service::StateToString(service->GetState())); fields->Set("last_state", service->GetLastState()); fields->Set("last_hard_state", service->GetLastHardState()); } else { fields->Set("last_state", host->GetLastState()); fields->Set("last_hard_state", host->GetLastHardState()); } double ts = Utility::GetTime(); if (cr) { fields->Set("plugin_output", cr->GetOutput()); fields->Set("check_source", cr->GetCheckSource()); ts = cr->GetExecutionEnd(); } SendLogMessage(ComposeLogstashMessage(fields, GetSource(), ts)); }
void GelfWriter::CheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr) { CONTEXT("GELF Processing check result for '" + checkable->GetName() + "'"); Log(LogDebug, "GelfWriter") << "GELF Processing check result for '" << checkable->GetName() << "'"; Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); Dictionary::Ptr fields = new Dictionary(); if (service) { fields->Set("_service_name", service->GetShortName()); fields->Set("_service_state", Service::StateToString(service->GetState())); fields->Set("_last_state", service->GetLastState()); fields->Set("_last_hard_state", service->GetLastHardState()); } else { fields->Set("_last_state", host->GetLastState()); fields->Set("_last_hard_state", host->GetLastHardState()); } fields->Set("_hostname", host->GetName()); fields->Set("_type", "CHECK RESULT"); fields->Set("_state", service ? Service::StateToString(service->GetState()) : Host::StateToString(host->GetState())); fields->Set("_current_check_attempt", checkable->GetCheckAttempt()); fields->Set("_max_check_attempts", checkable->GetMaxCheckAttempts()); if (cr) { fields->Set("short_message", CompatUtility::GetCheckResultOutput(cr)); fields->Set("full_message", CompatUtility::GetCheckResultLongOutput(cr)); fields->Set("_check_source", cr->GetCheckSource()); } SendLogMessage(ComposeGelfMessage(fields, GetSource())); }
bool Notification::EvaluateApplyRule(const Checkable::Ptr& checkable, const ApplyRule& rule) { DebugInfo di = rule.GetDebugInfo(); std::ostringstream msgbuf; msgbuf << "Evaluating 'apply' rule (" << di << ")"; CONTEXT(msgbuf.str()); Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); Dictionary::Ptr locals = make_shared<Dictionary>(); locals->Set("host", host); if (service) locals->Set("service", service); if (!rule.EvaluateFilter(locals)) return false; std::ostringstream msgbuf2; msgbuf2 << "Applying notification '" << rule.GetName() << "' to object '" << checkable->GetName() << "' for rule " << di; Log(LogDebug, "icinga", msgbuf2.str()); ConfigItemBuilder::Ptr builder = make_shared<ConfigItemBuilder>(di); builder->SetType("Notification"); builder->SetName(rule.GetName()); builder->SetScope(rule.GetScope()); builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, make_shared<AExpression>(&AExpression::OpLiteral, "host_name", di), make_shared<AExpression>(&AExpression::OpLiteral, host->GetName(), di), di)); if (service) { builder->AddExpression(make_shared<AExpression>(&AExpression::OpSet, make_shared<AExpression>(&AExpression::OpLiteral, "service_name", di), make_shared<AExpression>(&AExpression::OpLiteral, service->GetShortName(), di), di)); } builder->AddExpression(rule.GetExpression()); ConfigItem::Ptr notificationItem = builder->Compile(); notificationItem->Register(); DynamicObject::Ptr dobj = notificationItem->Commit(); dobj->OnConfigLoaded(); return true; }
void ElasticsearchWriter::InternalCheckResultHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr) { AssertOnWorkQueue(); CONTEXT("Elasticwriter processing check result for '" + checkable->GetName() + "'"); if (!IcingaApplication::GetInstance()->GetEnablePerfdata() || !checkable->GetEnablePerfdata()) return; Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); Dictionary::Ptr fields = new Dictionary(); if (service) { fields->Set("service", service->GetShortName()); fields->Set("state", service->GetState()); fields->Set("last_state", service->GetLastState()); fields->Set("last_hard_state", service->GetLastHardState()); } else { fields->Set("state", host->GetState()); fields->Set("last_state", host->GetLastState()); fields->Set("last_hard_state", host->GetLastHardState()); } fields->Set("host", host->GetName()); fields->Set("state_type", checkable->GetStateType()); fields->Set("current_check_attempt", checkable->GetCheckAttempt()); fields->Set("max_check_attempts", checkable->GetMaxCheckAttempts()); fields->Set("reachable", checkable->IsReachable()); CheckCommand::Ptr commandObj = checkable->GetCheckCommand(); if (commandObj) fields->Set("check_command", commandObj->GetName()); double ts = Utility::GetTime(); if (cr) { AddCheckResult(fields, checkable, cr); ts = cr->GetExecutionEnd(); } Enqueue(checkable, "checkresult", fields, ts); }
String Downtime::AddDowntime(const Checkable::Ptr& checkable, const String& author, const String& comment, double startTime, double endTime, bool fixed, const String& triggeredBy, double duration, const String& scheduledDowntime, const String& scheduledBy, const String& id, const MessageOrigin::Ptr& origin) { String fullName; if (id.IsEmpty()) fullName = checkable->GetName() + "!" + Utility::NewUniqueID(); else fullName = id; Dictionary::Ptr attrs = new Dictionary(); attrs->Set("author", author); attrs->Set("comment", comment); attrs->Set("start_time", startTime); attrs->Set("end_time", endTime); attrs->Set("fixed", fixed); attrs->Set("duration", duration); attrs->Set("triggered_by", triggeredBy); attrs->Set("scheduled_by", scheduledBy); attrs->Set("config_owner", scheduledDowntime); Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); attrs->Set("host_name", host->GetName()); if (service) attrs->Set("service_name", service->GetShortName()); String zone = checkable->GetZoneName(); if (!zone.IsEmpty()) attrs->Set("zone", zone); String config = ConfigObjectUtility::CreateObjectConfig(Downtime::TypeInstance, fullName, true, Array::Ptr(), attrs); Array::Ptr errors = new Array(); if (!ConfigObjectUtility::CreateObject(Downtime::TypeInstance, fullName, config, errors)) { ObjectLock olock(errors); BOOST_FOREACH(const String& error, errors) { Log(LogCritical, "Downtime", error); }
void DbEvents::ReachabilityChangedHandler(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, std::set<Checkable::Ptr> children) { int is_reachable = 0; if (cr->GetState() == ServiceOK) is_reachable = 1; Log(LogDebug, "DbEvents") << "Updating reachability for checkable '" << checkable->GetName() << "': " << (is_reachable ? "" : "not" ) << " reachable for " << children.size() << " children."; BOOST_FOREACH(const Checkable::Ptr& child, children) { Log(LogDebug, "DbEvents") << "Updating reachability for checkable '" << child->GetName() << "': " << (is_reachable ? "" : "not" ) << " reachable."; Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(child); DbQuery query1; if (service) query1.Table = "servicestatus"; else query1.Table = "hoststatus"; query1.Type = DbQueryUpdate; query1.Category = DbCatState; query1.StatusUpdate = true; query1.Object = DbObject::GetOrCreateByObject(child); Dictionary::Ptr fields1 = new Dictionary(); fields1->Set("is_reachable", is_reachable); query1.Fields = fields1; query1.WhereCriteria = new Dictionary(); if (service) query1.WhereCriteria->Set("service_object_id", service); else query1.WhereCriteria->Set("host_object_id", host); query1.WhereCriteria->Set("instance_id", 0); /* DbConnection class fills in real ID */ DbObject::OnQuery(query1); }
bool Dependency::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, ScriptFrame& frame, const ApplyRule& rule) { if (!rule.EvaluateFilter(frame)) return false; DebugInfo di = rule.GetDebugInfo(); #ifdef _DEBUG Log(LogDebug, "Dependency") << "Applying dependency '" << name << "' to object '" << checkable->GetName() << "' for rule " << di; #endif /* _DEBUG */ ConfigItemBuilder builder{di}; builder.SetType(Dependency::TypeInstance); builder.SetName(name); builder.SetScope(frame.Locals->ShallowClone()); builder.SetIgnoreOnError(rule.GetIgnoreOnError()); Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); builder.AddExpression(new SetExpression(MakeIndexer(ScopeThis, "parent_host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di)); builder.AddExpression(new SetExpression(MakeIndexer(ScopeThis, "child_host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di)); if (service) builder.AddExpression(new SetExpression(MakeIndexer(ScopeThis, "child_service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di)); String zone = checkable->GetZoneName(); if (!zone.IsEmpty()) builder.AddExpression(new SetExpression(MakeIndexer(ScopeThis, "zone"), OpSetLiteral, MakeLiteral(zone), di)); builder.AddExpression(new SetExpression(MakeIndexer(ScopeThis, "package"), OpSetLiteral, MakeLiteral(rule.GetPackage()), di)); builder.AddExpression(new ImportDefaultTemplatesExpression()); builder.AddExpression(new OwnedExpression(rule.GetExpression())); ConfigItem::Ptr dependencyItem = builder.Compile(); dependencyItem->Register(); return true; }
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 ElasticsearchWriter::StateChangeHandlerInternal(const Checkable::Ptr& checkable, const CheckResult::Ptr& cr, StateType type) { AssertOnWorkQueue(); CONTEXT("Elasticwriter processing state change '" + checkable->GetName() + "'"); Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); Dictionary::Ptr fields = new Dictionary(); fields->Set("current_check_attempt", checkable->GetCheckAttempt()); fields->Set("max_check_attempts", checkable->GetMaxCheckAttempts()); fields->Set("host", host->GetName()); if (service) { fields->Set("service", service->GetShortName()); fields->Set("state", service->GetState()); fields->Set("last_state", service->GetLastState()); fields->Set("last_hard_state", service->GetLastHardState()); } else { fields->Set("state", host->GetState()); fields->Set("last_state", host->GetLastState()); fields->Set("last_hard_state", host->GetLastHardState()); } CheckCommand::Ptr commandObj = checkable->GetCheckCommand(); if (commandObj) fields->Set("check_command", commandObj->GetName()); double ts = Utility::GetTime(); if (cr) { AddCheckResult(fields, checkable, cr); ts = cr->GetExecutionEnd(); } Enqueue(checkable, "statechange", fields, ts); }
Value ClusterEvents::NextCheckChangedAPIHandler(const MessageOrigin::Ptr& origin, const Dictionary::Ptr& params) { Endpoint::Ptr endpoint = origin->FromClient->GetEndpoint(); if (!endpoint) { Log(LogNotice, "ClusterEvents") << "Discarding 'next check changed' message from '" << origin->FromClient->GetIdentity() << "': Invalid endpoint origin (client not allowed)."; return Empty; } Host::Ptr host = Host::GetByName(params->Get("host")); if (!host) return Empty; Checkable::Ptr checkable; if (params->Contains("service")) checkable = host->GetServiceByShortName(params->Get("service")); else checkable = host; if (!checkable) return Empty; if (origin->FromZone && !origin->FromZone->CanAccessObject(checkable)) { Log(LogNotice, "ClusterEvents") << "Discarding 'next check changed' message for checkable '" << checkable->GetName() << "' from '" << origin->FromClient->GetIdentity() << "': Unauthorized access."; return Empty; } double nextCheck = params->Get("next_check"); if (nextCheck < Application::GetStartTime() + 60) return Empty; checkable->SetNextCheck(params->Get("next_check"), false, origin); return Empty; }
bool Dependency::EvaluateApplyRuleInstance(const Checkable::Ptr& checkable, const String& name, ScriptFrame& frame, const ApplyRule& rule) { if (!rule.EvaluateFilter(frame)) return false; DebugInfo di = rule.GetDebugInfo(); Log(LogDebug, "Dependency") << "Applying dependency '" << name << "' to object '" << checkable->GetName() << "' for rule " << di; ConfigItemBuilder::Ptr builder = new ConfigItemBuilder(di); builder->SetType("Dependency"); builder->SetName(name); builder->SetScope(frame.Locals->ShallowClone()); Host::Ptr host; Service::Ptr service; tie(host, service) = GetHostService(checkable); builder->AddExpression(new SetExpression(MakeIndexer(ScopeThis, "parent_host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di)); builder->AddExpression(new SetExpression(MakeIndexer(ScopeThis, "child_host_name"), OpSetLiteral, MakeLiteral(host->GetName()), di)); if (service) builder->AddExpression(new SetExpression(MakeIndexer(ScopeThis, "child_service_name"), OpSetLiteral, MakeLiteral(service->GetShortName()), di)); String zone = checkable->GetZoneName(); if (!zone.IsEmpty()) builder->AddExpression(new SetExpression(MakeIndexer(ScopeThis, "zone"), OpSetLiteral, MakeLiteral(zone), di)); builder->AddExpression(new SetExpression(MakeIndexer(ScopeThis, "module"), OpSetLiteral, MakeLiteral(rule.GetModule()), di)); builder->AddExpression(new OwnedExpression(rule.GetExpression())); ConfigItem::Ptr dependencyItem = builder->Compile(); dependencyItem->Register(); return true; }