Module: check_mk
Branch: master
Commit: 98968cdbbde6ba8f3a4cdc3f5373e47f844ab0b7
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=98968cdbbde6ba…
Author: Simon Betz <si(a)mathias-kettner.de>
Date: Mon Dec 19 08:05:34 2016 +0100
4170 local: local check is now clusteraware. Best or worst state in cluster mode can be
configured
Change-Id: Iea613ba04877ed54fab98f4846c1015b5bf51142
---
.werks/4170 | 11 +++
ChangeLog | 1 +
checks/local | 138 +++++++++++++++++++++++------------
web/plugins/wato/check_parameters.py | 20 +++++
4 files changed, 125 insertions(+), 45 deletions(-)
diff --git a/.werks/4170 b/.werks/4170
new file mode 100644
index 0000000..1f0eb6d
--- /dev/null
+++ b/.werks/4170
@@ -0,0 +1,11 @@
+Title: local: local check is now clusteraware. Best or worst state in cluster mode can be
configured
+Level: 1
+Component: checks
+Compatible: compat
+Version: 1.4.0i4
+Date: 1482131073
+Class: feature
+
+Now your're able to determine the state of local checks on clusters via {{Settings
for local checks}}
+in {{Host & Service parameters}}. Within these settings you can choose between best
or worst state.
+Default setting is worst state.
diff --git a/ChangeLog b/ChangeLog
index 598017a..eb242a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -40,6 +40,7 @@
* 4098 ups_cps_battery, ups_cps_battery.temp, ups_cps_inphase, ups_cps_outphase:
Several checks to monitor CPS UPS devices
* 4118 check_bi_aggr: changed check and WATO rule to support Kerberos auth...
* 4104 veeam_tapejobs: New check to monitor Veeam tape jobs
+ * 4170 local: local check is now clusteraware. Best or worst state in cluster mode
can be configured
* 3987 FIX: Check_MK Agent Access: Windows agent reported incorrect only from value
* 3952 FIX: diskstat: fixed bug if multipath devices having an alias...
* 3939 FIX: f5_bigip_conns: readded performance data and graphs...
diff --git a/checks/local b/checks/local
index db71272..a73f548 100644
--- a/checks/local
+++ b/checks/local
@@ -99,61 +99,109 @@ def inventory_local(info):
inventory = []
# Lines with P do not need to supply a text
for line in info:
- if len(line) >= 4 or len(line) == 3 and line[0] == 'P':
- inventory.append( (line[1], None) )
+ nodename = line[0]
+ stripped_line = line[1:]
+ if len(stripped_line) >= 4 or len(stripped_line) == 3 and stripped_line[0] ==
'P':
+ inventory.append( (stripped_line[1], None) )
else:
- raise MKGeneralException("Invalid line in agent section
<<<local>>>: %s" % " ".join(line))
+ raise MKGeneralException("Invalid line in agent section
<<<local>>>: %s" % " ".join(stripped_line))
return inventory
+# Some helper functions
+def _parse_local_line(line):
+ if not (len(line) >= 4 or (len(line) == 3 and line[0] == 'P')):
+ return 3, "Incomplete line in local check output: %s" % "
".join(line), []
+
+ statechar = line[0]
+ perftxt = line[2]
+
+ # convert eventually escaped newinfo_line chars to real newinfo_lines
+ # (will be converted back later individually for the different cores)
+ output = " ".join(line[3:]).replace("\\n", "\n")
+
+ perfdata = []
+ if perftxt != "-":
+ for entry in perftxt.split('|'):
+ try:
+ varname, valuetxt = entry.split('=')
+ values = valuetxt.split(';')
+ perfdata.append( tuple([varname] + values) )
+
+ except ValueError:
+ return 3, "Invalid performance data %s in local check output
%s" % \
+ (perftxt, " ".join(line)), []
+
+ if statechar == 'P':
+ state, texts = local_compute_state(perfdata)
+ if output:
+ texts = [output] + texts
+ output = ", ".join(texts)
+
+ else:
+ try:
+ state = int(statechar)
+ except:
+ return 3, "Invalid state %s in local check output %s: must be P, 0, 1, 2
or 3" % \
+ (statechar, " ".join(line)), []
+
+ if state not in range(0, 4):
+ output += ", local check has sent invalid state %d" % state
+ state = 3
+
+ return state, output, perfdata
+
+
+def _calculate_local_best_state(collected_stats):
+ states = []
+ infotexts = []
+ perfdatas = []
+ for nodename, attrs in collected_stats.items():
+ for itemname, (state, output, perfdata) in attrs.items():
+ if nodename is not None:
+ output = "On node %s: %s" % (nodename, output)
+ states.append(state)
+ infotexts.append(output)
+ perfdatas += perfdata
+ return min(states), ", ".join(infotexts), perfdatas
+
+
+def _calculate_local_worst_state(collected_stats):
+ for nodename, attrs in collected_stats.items():
+ for itemname, (state, output, perfdata) in attrs.items():
+ if nodename is not None:
+ output = "On node %s: %s" % (nodename, output)
+ yield state, output, perfdata
+
+
def check_local(item, params, info):
+ collected_stats = {}
for line in info:
+ nodename = line[0]
+ stripped_line = line[1:]
# Ignore invalid lines, tolerate bugs in local checks
# of unexperienced users
- if len(line) >= 2 and line[1] == item:
- if not (len(line) >= 4 or (len(line) == 3 and line[0] == 'P')):
- return 3, "Incomplete line in local check output: %s" % "
".join(line)
-
- statechar = line[0]
- perftxt = line[2]
-
- output = " ".join(line[3:])
- # convert eventually escaped newline chars to real newlines
- # (will be converted back later individually for the different cores)
- output = output.replace("\\n", "\n")
-
- perfdata = []
- if perftxt != "-":
- # new: allow multiple perfdata by using | as separator
- for entry in perftxt.split('|'):
- try:
- varname, valuetxt = entry.split('=')
- values = valuetxt.split(';')
- perfdata.append(tuple( [varname] + values ))
- except ValueError:
- return 3, "Invalid performance data %s in local check output
%s" % \
- (perftxt, " ".join(line))
- if statechar == 'P':
- state, texts = local_compute_state(perfdata)
- if output:
- texts = [output] + texts
- output = ", ".join(texts)
- else:
- try:
- state = int(statechar)
- except:
- return 3, "Invalid state %s in local check output %s: must be P,
0, 1, 2 or 3" % \
- (statechar, " ".join(line))
+ if len(stripped_line) >= 2 and stripped_line[1] == item:
+ collected_stats.setdefault(nodename, {})
+ collected_stats[nodename].setdefault(item, _parse_local_line(stripped_line))
+
+ if collected_stats == {}:
+ yield 3, "No data found in agent output"
+ return
- if state not in range(0, 4):
- output += ", local check has sent invalid state %d" %
state
- state = 3
- return (state, output, perfdata)
+ if params is not None and params.get("outcome_on_cluster",
"worst") == "best":
+ yield _calculate_local_best_state(collected_stats)
+ return
+ else:
+ for res in _calculate_local_worst_state(collected_stats):
+ yield res
check_info["local"] = {
- 'inventory_function' : inventory_local,
- 'check_function' : check_local,
- 'service_description' : '%s',
- 'has_perfdata' : True,
+ 'check_function' : check_local,
+ 'inventory_function' : inventory_local,
+ 'service_description' : '%s',
+ 'has_perfdata' : True,
+ 'node_info' : True,
+ 'group' : 'local',
}
diff --git a/web/plugins/wato/check_parameters.py b/web/plugins/wato/check_parameters.py
index 6cb567c..92a622e 100644
--- a/web/plugins/wato/check_parameters.py
+++ b/web/plugins/wato/check_parameters.py
@@ -1423,6 +1423,26 @@ register_rule(group + '/' + subgroup_applications,
)
+register_check_parameters(
+ subgroup_applications,
+ "local",
+ _("Settings for local checks"),
+ Dictionary(
+ elements = [
+ ("outcome_on_cluster", DropdownChoice(choices = [
+ ("worst", _("Worst state")),
+ ("best", _("Best state")),
+ ],
+ title = _("Clusters: Prefered check result of local checks"),
+ help = _("If you're running local checks on clusters via clustered
services rule "
+ "you can influence the check result with this rule. You can
choose between "
+ "best or worst state. Default setting is worst state."),
+ default_value = "worst"))
+ ]
+ ),
+ TextAscii(title = _("Name of local item")),
+ "dict"
+)
register_check_parameters(