Cleanup config.nodes_of
[check_mk.git] / checks / services
blob69438045ac474eb2878a021c90950d24ca8c7063
1 #!/usr/bin/python
2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
9 # | |
10 # | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
27 # Output of old agent (< 1.1.10i2):
28 # AeLookupSvc running Application Experience Lookup Service
29 # Alerter stopped Alerter
30 # ALG stopped Application Layer Gateway Service
31 # AppMgmt stopped Application Management
32 # appmgr running Remote Server Manager
34 # Output of new agent (>= 1.1.10i2):
35 # Alerter stopped/disabled Warndienst
36 # ALG running/demand Gatewaydienst auf Anwendungsebene
37 # Apple_Mobile_Device running/auto Apple Mobile Device
38 # AppMgmt stopped/demand Anwendungsverwaltung
39 # AudioSrv running/auto Windows Audio
40 # BITS running/demand Intelligenter Hintergrund<FC>bertragungsdienst
41 # Bonjour_Service running/auto Dienst "Bonjour"
43 # Deprecated option since 1.6. cmk_base creates a config warning when finding rules
44 # for this ruleset. Can be dropped with 1.7.
45 inventory_services = []
47 # Implemented in 1.2.1i2:
48 # New rule-style (WATO compatible) notation:
49 # [({'start_mode': 'demand', 'service': ['Netman']}, [], ['@all'], {'docu_url': ''})]
51 # <services> is list of regexes matching the service name
52 # <state> is the expected state to inventorize services of (running, stopped, ...)
53 # <start_mode> is the expected state to inventorize services of (auto, manual, ...)
55 # All above attributes can be set to None or not set to disable this filter option for the entry.
56 inventory_services_rules = []
59 def inventory_windows_services(info):
60 # Handle single entries (type str)
61 def add_matching_services(name, description, state, start_type, entry):
62 if isinstance(entry, tuple):
63 # New wato rule handling
64 svc = entry[0]
65 statespec = entry[1:]
67 elif ' ' in entry and len(entry.split()) == 2:
68 svc, statespec = entry.split()
70 else:
71 svc = entry
72 statespec = "running"
74 # First match name or description (optional since rule based config option available)
75 if svc:
76 if svc.startswith("~"):
77 r = regex(svc[1:])
78 if not r.match(name) and not r.match(description):
79 return []
80 elif svc != name and svc != description:
81 return []
83 if isinstance(statespec, tuple):
84 # New wato rule handling (always given as tuple of two)
85 if (statespec[0] and statespec[0] != state) \
86 or (statespec[1] and statespec[1] != start_type):
87 return []
89 else:
90 for n in statespec.split("/"):
91 if n not in [state, start_type]:
92 return []
94 return [(name, {})]
96 # Extract the WATO compatible rules for the current host
97 rules = []
98 for value in host_extra_conf(host_name(), inventory_services_rules):
99 # Now extract the list of service regexes
100 svcs = value.get('services', [])
101 state = value.get('state', None)
102 start_mode = value.get('start_mode', None)
103 if svcs:
104 for svc in svcs:
105 rules.append(('~' + svc, state, start_mode))
106 else:
107 rules.append((None, state, start_mode))
109 inventory = []
110 for line in info:
111 name = line[1]
112 description = " ".join(line[3:])
113 if '/' in line[2]:
114 state, start_type = line[2].split('/')
115 else:
116 state = line[2]
117 start_type = "unknown"
119 for rule in rules:
120 inventory += add_matching_services(name, description, state, start_type, rule)
122 return inventory
125 # Format of parameters
127 # "states" : [ ( "running", "demand", 1 ),
128 # ( "stopped", None, 2 ) ],
129 # "else" : 2,
133 def check_windows_services(item, params, info):
134 # Hack for old manually defined checks:
135 if params is None:
136 params = factory_settings["services_default_levels"]
138 # A service may appear more than once (due to clusters).
139 # First make a list of all matching entries with their
140 # states
141 found = []
142 for line in info:
143 # allow to match agains the internal name or agains the display name
144 # of the service
145 display_name = " ".join(line[3:])
146 if item == line[1] or item == display_name \
147 or line[1] in params['additional_servicenames'] \
148 or display_name in params['additional_servicenames']:
149 # newer agents also send start type as part of state,
150 # e.g. running/auto
151 if '/' in line[2]:
152 state, start_type = line[2].split('/')
153 else:
154 state = line[2]
155 start_type = "unknown"
156 found.append((line[0], state, start_type, " ".join(line[3:])))
158 if not found:
159 return params["else"], "service not found"
161 # We take the best found state (neccessary for clusters)
162 best_desc, best_state, best_info, best_running_on = None, None, None, None
163 for running_on, state, start_type, desc in found:
164 for t_state, t_start_type, mon_state in params["states"]:
165 if (t_state is None or t_state == state) \
166 and (t_start_type is None or t_start_type == start_type):
167 this_state = mon_state
168 break
169 else:
170 this_state = params["else"]
172 if best_state is None or this_state < best_state:
173 best_state = this_state
174 best_info = state, start_type
175 best_running_on = running_on
176 best_desc = desc
178 infotext = best_desc + ": %s (start type is %s)" % best_info
179 if best_running_on and best_state != 2: #if best state ist critical, there should no message "running on"
180 infotext += " (running on: %s)" % best_running_on
182 return (best_state, infotext)
185 factory_settings["services_default_levels"] = {
186 "states": [("running", None, 0)],
187 "else": 2,
188 "additional_servicenames": [],
191 check_info['services'] = {
192 "check_function": check_windows_services,
193 "inventory_function": inventory_windows_services,
194 "service_description": "Service %s",
195 "node_info": True,
196 "group": "services",
197 "default_levels_variable": "services_default_levels",
200 factory_settings["services_summary_default_levels"] = {"ignored": [], "state_if_stopped": 0}
203 def inventory_services_summary(info):
204 if info[0]:
205 return [(None, "services_summary_default_levels")]
208 def check_services_summary(item, params, info):
209 blacklist = params.get("ignored", ())
210 stoplist = []
211 num_blacklist = 0
212 num_auto = 0
213 for line in info:
214 # newer agents also send start type as part of state,
215 # e.g. running/auto
216 if '/' in line[2]:
217 startstop, auto = line[2].split('/')
218 else:
219 startstop = line[2]
220 auto = "unknown"
221 srv_name = line[1]
222 if auto == "auto":
223 num_auto += 1
224 if startstop == "stopped":
225 match = False
226 for srv in blacklist:
227 if re.match(srv, srv_name):
228 match = True
229 if match is False:
230 stoplist.append(srv_name)
231 else:
232 num_blacklist += 1
234 num_stoplist = len(stoplist)
235 num_srv = len(info)
237 if len(stoplist) > 0:
238 stopped_srvs = " (" + ", ".join(stoplist) + ")"
239 state = params.get("state_if_stopped")
240 if state == 1:
241 sym = "(!)"
242 elif state == 2:
243 sym = "(!!)"
244 else:
245 sym = ""
246 else:
247 stopped_srvs = ""
248 state = 0
249 sym = ""
252 infotext = "%d services, %d services in autostart - of which %d services are stopped%s%s, %d services stopped but ignored" % \
253 ( num_srv, num_auto, num_stoplist, sym, stopped_srvs, num_blacklist )
255 return state, infotext
258 check_info['services.summary'] = {
259 "check_function": check_services_summary,
260 "inventory_function": inventory_services_summary,
261 "default_levels_variable": "services_summary_default_levels",
262 "service_description": "Services Summary",
263 "node_info": True,
264 "group": "services_summary",