]> granicus.if.org Git - icinga2/blob - lib/icinga/host.cpp
Implement support for hosts in the agent component.
[icinga2] / lib / icinga / host.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2014 Icinga Development Team (http://www.icinga.org)    *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "icinga/host.h"
21 #include "icinga/service.h"
22 #include "icinga/hostgroup.h"
23 #include "icinga/icingaapplication.h"
24 #include "icinga/pluginutility.h"
25 #include "base/dynamictype.h"
26 #include "base/objectlock.h"
27 #include "base/logger_fwd.h"
28 #include "base/timer.h"
29 #include "base/convert.h"
30 #include "base/utility.h"
31 #include "base/scriptfunction.h"
32 #include "base/debug.h"
33 #include "base/serializer.h"
34 #include "config/configitembuilder.h"
35 #include "config/configcompilercontext.h"
36 #include <boost/foreach.hpp>
37
38 using namespace icinga;
39
40 REGISTER_TYPE(Host);
41
42 void Host::OnConfigLoaded(void)
43 {
44         Checkable::OnConfigLoaded();
45
46         ASSERT(!OwnsLock());
47
48         Array::Ptr groups = GetGroups();
49
50         if (groups) {
51                 ObjectLock olock(groups);
52
53                 BOOST_FOREACH(const String& name, groups) {
54                         HostGroup::Ptr hg = HostGroup::GetByName(name);
55
56                         if (hg)
57                                 hg->ResolveGroupMembership(GetSelf(), true);
58                 }
59         }
60 }
61
62 void Host::Stop(void)
63 {
64         Checkable::Stop();
65
66         Array::Ptr groups = GetGroups();
67
68         if (groups) {
69                 ObjectLock olock(groups);
70
71                 BOOST_FOREACH(const String& name, groups) {
72                         HostGroup::Ptr hg = HostGroup::GetByName(name);
73
74                         if (hg)
75                                 hg->ResolveGroupMembership(GetSelf(), false);
76                 }
77         }
78
79         // TODO: unregister slave services/notifications?
80 }
81
82 std::set<Service::Ptr> Host::GetServices(void) const
83 {
84         boost::mutex::scoped_lock lock(m_ServicesMutex);
85
86         std::set<Service::Ptr> services;
87         typedef std::pair<String, Service::Ptr> ServicePair;
88         BOOST_FOREACH(const ServicePair& kv, m_Services) {
89                 services.insert(kv.second);
90         }
91
92         return services;
93 }
94
95 void Host::AddService(const Service::Ptr& service)
96 {
97         boost::mutex::scoped_lock lock(m_ServicesMutex);
98
99         m_Services[service->GetShortName()] = service;
100 }
101
102 void Host::RemoveService(const Service::Ptr& service)
103 {
104         boost::mutex::scoped_lock lock(m_ServicesMutex);
105
106         m_Services.erase(service->GetShortName());
107 }
108
109 int Host::GetTotalServices(void) const
110 {
111         return GetServices().size();
112 }
113
114 Service::Ptr Host::GetServiceByShortName(const Value& name)
115 {
116         if (name.IsScalar()) {
117                 {
118                         boost::mutex::scoped_lock lock(m_ServicesMutex);
119
120                         std::map<String, Service::Ptr>::const_iterator it = m_Services.find(name);
121
122                         if (it != m_Services.end())
123                                 return it->second;
124                 }
125
126                 return Service::Ptr();
127         } else if (name.IsObjectType<Dictionary>()) {
128                 Dictionary::Ptr dict = name;
129                 String short_name;
130
131                 return Service::GetByNamePair(dict->Get("host"), dict->Get("service"));
132         } else {
133                 BOOST_THROW_EXCEPTION(std::invalid_argument("Host/Service name pair is invalid: " + JsonSerialize(name)));
134         }
135 }
136
137 HostState Host::CalculateState(ServiceState state)
138 {
139         switch (state) {
140                 case ServiceOK:
141                 case ServiceWarning:
142                         return HostUp;
143                 default:
144                         return HostDown;
145         }
146 }
147
148 HostState Host::GetState(void) const
149 {
150         return CalculateState(GetStateRaw());
151 }
152
153 HostState Host::GetLastState(void) const
154 {
155         return CalculateState(GetLastStateRaw());
156 }
157
158 HostState Host::GetLastHardState(void) const
159 {
160         return CalculateState(GetLastHardStateRaw());
161 }
162
163 double Host::GetLastStateUp(void) const
164 {
165         if (GetLastStateOK() > GetLastStateWarning())
166                 return GetLastStateOK();
167         else
168                 return GetLastStateWarning();
169 }
170
171 double Host::GetLastStateDown(void) const
172 {
173         return GetLastStateCritical();
174 }
175
176 HostState Host::StateFromString(const String& state)
177 {
178         if (state == "UP")
179                 return HostUp;
180         else
181                 return HostDown;
182 }
183
184 String Host::StateToString(HostState state)
185 {
186         switch (state) {
187                 case HostUp:
188                         return "UP";
189                 case HostDown:
190                         return "DOWN";
191                 default:
192                         return "INVALID";
193         }
194 }
195
196 StateType Host::StateTypeFromString(const String& type)
197 {
198         if (type == "SOFT")
199                 return StateTypeSoft;
200         else
201                 return StateTypeHard;
202 }
203
204 String Host::StateTypeToString(StateType type)
205 {
206         if (type == StateTypeSoft)
207                 return "SOFT";
208         else
209                 return "HARD";
210 }
211
212 bool Host::ResolveMacro(const String& macro, const CheckResult::Ptr&, String *result) const
213 {
214         if (macro == "state") {
215                 *result = StateToString(GetState());
216                 return true;
217         } else if (macro == "state_id") {
218                 *result = Convert::ToString(GetState());
219                 return true;
220         } else if (macro == "state_type") {
221                 *result = StateTypeToString(GetStateType());
222                 return true;
223         } else if (macro == "last_state") {
224                 *result = StateToString(GetLastState());
225                 return true;
226         } else if (macro == "last_state_id") {
227                 *result = Convert::ToString(GetLastState());
228                 return true;
229         } else if (macro == "last_state_type") {
230                 *result = StateTypeToString(GetLastStateType());
231                 return true;
232         } else if (macro == "last_state_change") {
233                 *result = Convert::ToString((long)GetLastStateChange());
234                 return true;
235         } else if (macro == "duration_sec") {
236                 *result = Convert::ToString((long)(Utility::GetTime() - GetLastStateChange()));
237                 return true;
238         } else if (macro == "total_services" || macro == "total_services_ok" || macro == "total_services_warning"
239                     || macro == "total_services_unknown" || macro == "total_services_critical") {
240                         int filter = -1;
241                         int count = 0;
242
243                         if (macro == "total_services_ok")
244                                 filter = ServiceOK;
245                         else if (macro == "total_services_warning")
246                                 filter = ServiceWarning;
247                         else if (macro == "total_services_unknown")
248                                 filter = ServiceUnknown;
249                         else if (macro == "total_services_critical")
250                                 filter = ServiceCritical;
251
252                         BOOST_FOREACH(const Service::Ptr& service, GetServices()) {
253                                 if (filter != -1 && service->GetState() != filter)
254                                         continue;
255
256                                 count++;
257                         }
258
259                         *result = Convert::ToString(count);
260                         return true;
261         }
262
263         CheckResult::Ptr cr = GetLastCheckResult();
264
265         if (cr) {
266                 if (macro == "latency") {
267                         *result = Convert::ToString(Service::CalculateLatency(cr));
268                         return true;
269                 } else if (macro == "execution_time") {
270                         *result = Convert::ToString(Service::CalculateExecutionTime(cr));
271                         return true;
272                 } else if (macro == "output") {
273                         *result = cr->GetOutput();
274                         return true;
275                 } else if (macro == "perfdata") {
276                         *result = PluginUtility::FormatPerfdata(cr->GetPerformanceData());
277                         return true;
278                 } else if (macro == "last_check") {
279                         *result = Convert::ToString((long)cr->GetScheduleStart());
280                         return true;
281                 }
282         }
283
284         return false;
285 }