Refactoring: Changed all check parameters starting with an 'o' to the new rulespec...
[check_mk.git] / checks / mtr
blobf44499fde75aa064d7842211e698d73988e08609
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 # Example for output from agent
28 # ---------------------------------------------------------
29 #<<<mtr>>>
30 #www.google.com|1451237587|8|80.69.76.120|0.0%|10|39.2|7.0|0.3|39.2|14.2|80.249.209.100|0.0%|10|1.2|1.2|1.0|1.4|0.0|209.85.240.61|0.0%|10|1.4|1.6|1.2|2.4|0.0|209.85.248.247|0.0%|10|1.6|1.7|1.5|2.1|0.0|216.239.51.17|0.0%|10|4.8|5.0|4.7|5.3|0.0|216.239.49.36|0.0%|10|6.1|5.5|4.7|8.8|1.1|???|100.0|10|0.0|0.0|0.0|0.0|0.0|74.125.136.105|0.0%|10|4.7|5.0|4.7|5.4|0.0
31 # ---------------------------------------------------------
33 factory_settings["mtr_default_levels"] = {
34 "pl": (10, 25), # warn/crit for loss percentage
35 "rta": (150, 250), # warn/crit for average roundtrip time
36 "rtstddev": (150, 250), # warn/crit for standard deviation
40 def parse_mtr(info):
41 hosts = {}
42 for line in info:
43 if line[0].startswith("**ERROR**"):
44 continue
46 ret = {'hops': {}}
47 if not len(line) > 0:
48 return ret
49 hostname = line[0]
50 ret['hostname'] = hostname
51 ret['last_check'] = line[1]
52 ret['hopcount'] = int(float(line[2]))
53 rest = line[3:]
55 if ret['hopcount'] > 0:
56 for hopnum in range(0, ret['hopcount']):
57 ret['hops'][hopnum + 1] = {
58 'hopname': rest[0 + 8 * hopnum],
59 'pl': rest[1 + 8 * hopnum].replace("%", "").rstrip(),
60 'snt': rest[2 + 8 * hopnum],
61 'response_time': rest[3 + 8 * hopnum],
62 'rta': rest[4 + 8 * hopnum],
63 'rtmin': rest[5 + 8 * hopnum],
64 'rtmax': rest[6 + 8 * hopnum],
65 'rtstddev': rest[7 + 8 * hopnum],
67 hosts[hostname] = ret
68 return hosts
71 def inventory_mtr(parsed):
72 for host in parsed.keys():
73 yield host, {}
76 def check_mtr(item, params, parsed):
77 hostinfo = parsed.get(item)
78 if not hostinfo:
79 return
81 if hostinfo["hopcount"] == 0:
82 yield 3, "Insufficient data: No hop information available"
83 return
85 hopnames = []
86 perfdata = []
87 hops = hostinfo['hops']
89 def get_hop_info(hops, idx, apply_levels=False):
90 if apply_levels:
91 pl_warn, pl_crit = params["pl"]
92 rta_warn, rta_crit = params["rta"]
93 rtstddev_warn, rtstddev_crit = params["rtstddev"]
94 else:
95 pl_warn, pl_crit = None, None
96 rta_warn, rta_crit = None, None
97 rtstddev_warn, rtstddev_crit = None, None
99 hop = hops[idx]
100 hopnames.append(hop["hopname"])
101 rta = float(hop['rta'])
102 rtmin = float(hop['rtmin'])
103 rtmax = float(hop['rtmax'])
104 rtstddev = float(hop['rtstddev'])
105 response_time = float(hop['response_time'])
106 pl = float(hop['pl'])
107 # snt = float(hop['snt'])
108 # perfdata.append( ( 'hop_%d_snt' % idx, snt, "", "", "", "" ) ) # packets sent
109 perfdata.append( ('hop_%d_rta' % idx, rta / 1000 , rta_warn and rta_warn / 1000,\
110 rta_crit and rta_crit / 1000) )
111 perfdata.append(('hop_%d_rtmin' % idx, rtmin / 1000))
112 perfdata.append(('hop_%d_rtmax' % idx, rtmax / 1000))
113 perfdata.append( ('hop_%d_rtstddev' % idx, rtstddev / 1000, rtstddev_warn and rtstddev_warn / 1000,\
114 rtstddev_crit and rtstddev_crit / 1000) )
115 perfdata.append(('hop_%d_response_time' % idx, response_time / 1000))
116 perfdata.append(('hop_%d_pl' % idx, pl, pl_warn, pl_crit))
118 if apply_levels: # the params only apply to the last host
119 hop_text_entries = []
120 for what, unit, value, warn, crit in [
121 ("Packet loss", "%", pl, pl_warn, pl_crit),
122 ("Round trip average", "ms", rta, rta_warn, rta_crit),
123 ("Standard deviation", "ms", rtstddev, rtstddev_warn, rtstddev_crit),
125 what_state = 0
126 hop_text = ""
127 if value >= crit:
128 what_state = 2
129 elif value >= warn:
130 what_state = 1
131 hop_text = "%s %s%s%s" % (what, value, unit,
132 what_state and state_markers[what_state] or "")
133 if what_state:
134 hop_text += " (Levels at %d%s/%d%s)" % (warn, unit, crit, unit)
135 hop_text_entries.append(hop_text)
137 return what_state, ", ".join(hop_text_entries), perfdata
138 return None, None, perfdata
140 hc = int(hostinfo['hopcount'])
141 hop_perfdata = [('hops', hc)]
143 def format_hopnames(hopnames):
144 result = "Hops in last check:\n"
145 for idx, name in enumerate(hopnames):
146 result += "Hop %d: %s\n" % (idx + 1, name)
147 return result
149 for idx in range(0, hc):
150 state, text, perfdata = get_hop_info(hops, idx + 1, apply_levels=(idx + 1 == hc))
151 if state is None:
152 # This is perfdata from a hop, we do not yield it yet (looks ugly..)
153 hop_perfdata.extend(perfdata)
154 else:
155 # Last hop with state, text and perfdata. Yield everything we have
156 yield 0, "Number of Hops: %d" % hc, hop_perfdata
157 yield state, text + "\r\n%s" % format_hopnames(hopnames), perfdata
160 check_info['mtr'] = {
161 "parse_function": parse_mtr,
162 "check_function": check_mtr,
163 "inventory_function": inventory_mtr,
164 "service_description": "Mtr to %s",
165 "has_perfdata": True,
166 "group": "mtr",
167 "default_levels_variable": "mtr_default_levels",