if (tasks > 0) {
stringstream msgbuf;
msgbuf << "CheckTimerHandler: created " << tasks << " task(s)";
- Logger::Write(LogInformation, "checker", msgbuf.str());
+ Logger::Write(LogDebug, "checker", msgbuf.str());
}
RescheduleCheckTimer();
fp << "hostcomment {" << "\n";
else
fp << "servicecomment {" << "\n"
- << "\t" << "service_description=" << service->GetAlias() << "\n";
+ << "\t" << "service_description=" << service->GetShortName() << "\n";
fp << "\t" << "host_name=" << host->GetName() << "\n"
<< "\t" << "comment_id=" << static_cast<String>(comment->Get("legacy_id")) << "\n"
fp << "hostdowntime {" << "\n";
else
fp << "servicedowntime {" << "\n"
- << "\t" << "service_description=" << service->GetAlias() << "\n";
+ << "\t" << "service_description=" << service->GetShortName() << "\n";
Dictionary::Ptr triggeredByObj = DowntimeProcessor::GetDowntimeByID(downtime->Get("triggered_by"));
int triggeredByLegacy = 0;
{
fp << "servicestatus {" << "\n"
<< "\t" << "host_name=" << service->GetHost()->GetName() << "\n"
- << "\t" << "service_description=" << service->GetName() << "\n";
+ << "\t" << "service_description=" << service->GetShortName() << "\n";
DumpServiceStatusAttrs(fp, service, CompatStateService);
{
fp << "define service {" << "\n"
<< "\t" << "host_name" << "\t" << service->GetHost()->GetName() << "\n"
- << "\t" << "service_description" << "\t" << service->GetName() << "\n"
+ << "\t" << "service_description" << "\t" << service->GetShortName() << "\n"
<< "\t" << "display_name" << "\t" << service->GetAlias() << "\n"
<< "\t" << "check_command" << "\t" << "check_i2" << "\n"
<< "\t" << "check_interval" << "\t" << service->GetCheckInterval() / 60.0 << "\n"
BOOST_FOREACH(const Service::Ptr& parent, service->GetParentServices()) {
fp << "define servicedependency {" << "\n"
<< "\t" << "dependent_host_name" << "\t" << service->GetHost()->GetName() << "\n"
- << "\t" << "dependent_service_description" << "\t" << service->GetName() << "\n"
+ << "\t" << "dependent_service_description" << "\t" << service->GetShortName() << "\n"
<< "\t" << "host_name" << "\t" << parent->GetHost()->GetName() << "\n"
- << "\t" << "service_description" << "\t" << parent->GetName() << "\n"
+ << "\t" << "service_description" << "\t" << parent->GetShortName() << "\n"
<< "\t" << "execution_failure_criteria" << "\t" << "n" << "\n"
<< "\t" << "notification_failure_criteria" << "\t" << "w,u,c" << "\n"
<< "\t" << "}" << "\n"
%require "host_name",
%attribute string "host_name",
+ %attribute string "short_name",
+
%attribute string "alias",
%attribute dictionary "macros" {
%attribute string "*"
if (arguments.size() < 4)
BOOST_THROW_EXCEPTION(invalid_argument("Expected 4 arguments."));
- if (!Service::Exists(arguments[1]))
- BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist."));
-
- Service::Ptr service = Service::GetByName(arguments[1]);
+ Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
if (!service->GetEnablePassiveChecks())
BOOST_THROW_EXCEPTION(invalid_argument("Got passive check result for service '" + arguments[1] + "' which has passive checks disabled."));
if (arguments.size() < 3)
BOOST_THROW_EXCEPTION(invalid_argument("Expected 3 arguments."));
- if (!Service::Exists(arguments[1]))
- BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist."));
-
- Service::Ptr service = Service::GetByName(arguments[1]);
+ Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
double planned_check = Convert::ToDouble(arguments[2]);
if (arguments.size() < 3)
BOOST_THROW_EXCEPTION(invalid_argument("Expected 3 arguments."));
- if (!Service::Exists(arguments[1]))
- BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist."));
-
- Service::Ptr service = Service::GetByName(arguments[1]);
+ Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
Logger::Write(LogInformation, "icinga", "Rescheduling next check for service '" + arguments[1] + "'");
service->SetForceNextCheck(true);
if (arguments.size() < 2)
BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
- if (!Service::Exists(arguments[1]))
- BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist."));
-
- Service::Ptr service = Service::GetByName(arguments[1]);
+ Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
Logger::Write(LogInformation, "icinga", "Enabling active checks for service '" + arguments[1] + "'");
service->SetEnableActiveChecks(true);
if (arguments.size() < 2)
BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
- if (!Service::Exists(arguments[1]))
- BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist."));
-
- Service::Ptr service = Service::GetByName(arguments[1]);
+ Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
Logger::Write(LogInformation, "icinga", "Disabling active checks for service '" + arguments[1] + "'");
service->SetEnableActiveChecks(false);
bool sticky = Convert::ToBool(arguments[2]);
- Service::Ptr service = Service::GetByName(arguments[1]);
+ Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
if (service->GetState() == StateOK)
BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' is OK."));
bool sticky = Convert::ToBool(arguments[2]);
double timestamp = Convert::ToDouble(arguments[5]);
- Service::Ptr service = Service::GetByName(arguments[1]);
+ Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
if (service->GetState() == StateOK)
BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' is OK."));
if (arguments.size() < 2)
BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
- if (!Service::Exists(arguments[1]))
- BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist."));
-
- Service::Ptr service = Service::GetByName(arguments[1]);
+ Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
Logger::Write(LogInformation, "icinga", "Enabling passive checks for service '" + arguments[1] + "'");
service->SetEnablePassiveChecks(true);
if (arguments.size() < 2)
BOOST_THROW_EXCEPTION(invalid_argument("Expected 2 arguments."));
- if (!Service::Exists(arguments[1]))
- BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist."));
-
- Service::Ptr service = Service::GetByName(arguments[1]);
+ Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
Logger::Write(LogInformation, "icinga", "Disabling passive checks for service '" + arguments[1] + "'");
service->SetEnablePassiveChecks(false);
if (arguments.size() < 9)
BOOST_THROW_EXCEPTION(invalid_argument("Expected 9 arguments."));
- if (!Service::Exists(arguments[1]))
- BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist."));
-
- Service::Ptr service = Service::GetByName(arguments[1]);
+ Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
String triggeredBy;
int triggeredByLegacy = Convert::ToLong(arguments[5]);
if (!Service::Exists(arguments[1]))
BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist."));
- Service::Ptr service = Service::GetByName(arguments[1]);
+ Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
Logger::Write(LogInformation, "icinga", "Creating comment for service " + service->GetName());
(void) CommentProcessor::AddComment(service, Comment_User, arguments[3], arguments[4], 0);
if (!Service::Exists(arguments[1]))
BOOST_THROW_EXCEPTION(invalid_argument("The service '" + arguments[1] + "' does not exist."));
- Service::Ptr service = Service::GetByName(arguments[1]);
+ Service::Ptr service = Service::GetByNamePair(arguments[0], arguments[1]);
Logger::Write(LogInformation, "icinga", "Removing all comments for service " + service->GetName());
CommentProcessor::RemoveAllComments(service);
}
-
using namespace icinga;
-map<String, vector<Service::WeakPtr> > Host::m_ServicesCache;
+map<String, map<String, weak_ptr<Service> > > Host::m_ServicesCache;
bool Host::m_ServicesCacheValid = true;
REGISTER_SCRIPTFUNCTION("native::ValidateServiceDictionary", &Host::ValidateServiceDictionary);
return false;
}
-bool Host::IsUp(void)
+bool Host::IsUp(void) const
{
- Dictionary::Ptr hostchecks = Get("hostchecks");
- if (hostchecks) {
- hostchecks = Service::ResolveDependencies(GetSelf(), hostchecks);
-
- Value hostcheck;
- BOOST_FOREACH(tie(tuples::ignore, hostcheck), hostchecks) {
- Service::Ptr service = Service::GetByName(hostcheck);
-
- if (service->GetState() != StateOK && service->GetState() != StateWarning) {
- return false;
- }
- }
- }
-
- return true;
+ Service::Ptr service = GetHostCheckService();
+ return (!service || service->GetState() == StateOK || service->GetState() == StateWarning);
}
template<typename TDict>
-static void CopyServiceAttributes(const Host::Ptr& host, TDict serviceDesc,
- const ConfigItemBuilder::Ptr& builder)
+static void CopyServiceAttributes(TDict serviceDesc, const ConfigItemBuilder::Ptr& builder)
{
/* TODO: we only need to copy macros if this is an inline definition,
* i.e. host->GetProperties() != service, however for now we just
builder->SetName(name);
builder->AddExpression("host_name", OperatorSet, item->GetName());
builder->AddExpression("alias", OperatorSet, svcname);
+ builder->AddExpression("short_name", OperatorSet, svcname);
- CopyServiceAttributes(host, host, builder);
+ CopyServiceAttributes(host, builder);
if (svcdesc.IsScalar()) {
builder->AddParent(svcdesc);
builder->AddParent(parent);
- CopyServiceAttributes(host, service, builder);
+ CopyServiceAttributes(service, builder);
} else {
BOOST_THROW_EXCEPTION(invalid_argument("Service description must be either a string or a dictionary."));
}
ValidateServicesCache();
- BOOST_FOREACH(const Service::WeakPtr& svc, m_ServicesCache[GetName()]) {
- Service::Ptr service = svc.lock();
+ String key;
+ Service::WeakPtr wservice;
+ BOOST_FOREACH(tie(key, wservice), m_ServicesCache[GetName()]) {
+ Service::Ptr service = wservice.lock();
if (!service)
continue;
BOOST_FOREACH(tie(tuples::ignore, object), DynamicType::GetByName("Service")->GetObjects()) {
const Service::Ptr& service = static_pointer_cast<Service>(object);
- m_ServicesCache[service->GetHost()->GetName()].push_back(service);
+ // TODO: assert for duplicate short_names
+
+ m_ServicesCache[service->GetHost()->GetName()][service->GetShortName()] = service;
}
m_ServicesCacheValid = true;
task->FinishResult(Empty);
}
-Service::Ptr Host::ResolveService(const String& name) const
+Service::Ptr Host::GetServiceByShortName(const String& name) const
{
- String combinedName = GetName() + "-" + name;
+ ValidateServicesCache();
- if (Service::Exists(combinedName))
- return Service::GetByName(combinedName);
- else
- return Service::GetByName(name);
+ map<String, weak_ptr<Service> >& services = m_ServicesCache[GetName()];
+ map<String, weak_ptr<Service> >::iterator it = services.find(name);
+
+ if (it != services.end()) {
+ Service::Ptr service = it->second.lock();
+ assert(service);
+ return service;
+ }
+
+ return Service::GetByName(name);
}
set<Host::Ptr> Host::GetParentHosts(void) const
if (hostcheck.IsEmpty())
return Service::Ptr();
- return ResolveService(hostcheck);
+ return GetServiceByShortName(hostcheck);
}
set<Service::Ptr> Host::GetParentServices(void) const
if (dependencies) {
String key;
BOOST_FOREACH(tie(key, tuples::ignore), dependencies) {
- parents.insert(ResolveService(key));
+ // TODO(#3660): look up { host = "name", service = "name" } pairs
+ parents.insert(GetServiceByShortName(key));
}
}
return parents;
}
-
bool IsReachable(void);
bool IsInDowntime(void) const;
- bool IsUp(void);
+ bool IsUp(void) const;
- shared_ptr<Service> ResolveService(const String& name) const;
+ shared_ptr<Service> GetServiceByShortName(const String& name) const;
set<shared_ptr<Service> > GetServices(void) const;
static void InvalidateServicesCache(void);
private:
static bool m_InitializerDone;
- static map<String, vector<weak_ptr<Service> > > m_ServicesCache;
+ static map<String, map<String, weak_ptr<Service> > > m_ServicesCache;
static bool m_ServicesCacheValid;
static void ObjectCommittedHandler(const ConfigItem::Ptr& item);
return dynamic_pointer_cast<Service>(configObject);
}
+Service::Ptr Service::GetByNamePair(const String& hostName, const String& serviceName)
+{
+ if (!hostName.IsEmpty()) {
+ Host::Ptr host = Host::GetByName(hostName);
+ return host->GetServiceByShortName(serviceName);
+ } else {
+ return Service::GetByName(serviceName);
+ }
+}
+
Host::Ptr Service::GetHost(void) const
{
String hostname = Get("host_name");
return Get("checkers");
}
+String Service::GetShortName(void) const
+{
+ Value value = Get("short_name");
+
+ if (value.IsEmpty())
+ return GetName();
+
+ return value;
+}
+
bool Service::IsReachable(void) const
{
BOOST_FOREACH(const Service::Ptr& service, GetParentServices()) {
/* reschedule host dependencies */
BOOST_FOREACH(const Host::Ptr& parent, GetParentHosts()) {
- String hostcheck = parent->GetHostCheck();
- if (!hostcheck.IsEmpty()) {
- Service::Ptr service = parent->ResolveService(hostcheck);
+ Service::Ptr service = parent->GetHostCheckService();
+
+ if (service)
service->SetNextCheck(Utility::GetTime());
- }
}
// TODO: notify our child services/hosts that our state has changed
return false;
}
-Dictionary::Ptr Service::ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies)
-{
- Dictionary::Ptr services = host->Get("services");
-
- Dictionary::Ptr result = boost::make_shared<Dictionary>();
-
- Value dependency;
- BOOST_FOREACH(tie(tuples::ignore, dependency), dependencies) {
- String name;
-
- if (services && services->Contains(dependency))
- name = host->GetName() + "-" + static_cast<String>(dependency);
- else
- name = static_cast<String>(dependency);
-
- result->Set(name, name);
- }
-
- return result;
-}
-
void Service::OnAttributeChanged(const String& name, const Value& oldValue)
{
if (name == "checker")
OnNextCheckChanged(GetSelf(), oldValue);
else if (name == "servicegroups")
ServiceGroup::InvalidateMembersCache();
- else if (name == "host_name")
+ else if (name == "host_name" || name == "short_name")
Host::InvalidateServicesCache();
else if (name == "downtimes")
DowntimeProcessor::InvalidateDowntimeCache();
if (dependencies) {
String key;
BOOST_FOREACH(tie(key, tuples::ignore), dependencies) {
- Service::Ptr service = GetHost()->ResolveService(key);
+ // TODO(#3660): look up { host = "name", service = "name" } pairs
+ Service::Ptr service = GetHost()->GetServiceByShortName(key);
if (service->GetName() == GetName())
continue;
static bool Exists(const String& name);
static Service::Ptr GetByName(const String& name);
+ static Service::Ptr GetByNamePair(const String& hostName, const String& serviceName);
+
static const int DefaultMaxCheckAttempts;
static const int DefaultCheckInterval;
static const int CheckIntervalDivisor;
Dictionary::Ptr GetServiceDependencies(void) const;
Dictionary::Ptr GetGroups(void) const;
Dictionary::Ptr GetCheckers(void) const;
+ String GetShortName(void) const;
set<Host::Ptr> GetParentHosts(void) const;
set<Service::Ptr> GetParentServices(void) const;
static ServiceStateType StateTypeFromString(const String& state);
static String StateTypeToString(ServiceStateType state);
- static Dictionary::Ptr ResolveDependencies(const Host::Ptr& host, const Dictionary::Ptr& dependencies);
-
static boost::signal<void (const Service::Ptr& service, const CheckResultMessage&)> OnCheckResultReceived;
static boost::signal<void (const Service::Ptr&, const String&)> OnCheckerChanged;
static boost::signal<void (const Service::Ptr&, const Value&)> OnNextCheckChanged;