Refactoring: Moved check parameters from unsorted.py to dedicated modules (CMK-1393)
[check_mk.git] / checks / docsis_channels_upstream
blob6d4aac1a566c68990afb09ce05de524a8699e4b9
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 # Old comments:
28 # Strange: Channel IDs seem to be not unique. But the second
29 # usage has '0' in the docsIfUpChannelFrequency...
31 # Info might look different: on the one hand the channel id is the connector
32 # on the other hand the OID. In some cases the channel id is not unique:
34 # [[[u'4', u'3', u'38000000']], [[u'3', u'541092', u'36', u'6', u'498']], []]
36 # [[[u'1337', u'1', u'20000000'],
37 # [u'1338', u'2', u'32000000'],
38 # [u'1339', u'3', u'38000000'],
39 # [u'1361', u'1', u'0'],
40 # [u'1362', u'2', u'0'],
41 # [u'1363', u'3', u'0'],
42 # [u'1364', u'4', u'0']],
43 # [[u'1337', u'2262114535', u'322661943', u'406110', u'293'],
44 # [u'1338', u'2567058620', u'5306417', u'78105', u'328'],
45 # [u'1339', u'4222307191', u'4132447', u'19600', u'339'],
46 # [u'1361', u'0', u'0', u'0', u'0'],
47 # [u'1362', u'0', u'0', u'0', u'0'],
48 # [u'1363', u'0', u'0', u'0', u'0'],
49 # [u'1364', u'0', u'0', u'0', u'0']],
50 # [[u'1337', u'9', u'9', u'9', u'5'],
51 # [u'1338', u'10', u'10', u'10', u'61'],
52 # [u'1339', u'10', u'10', u'10', u'4'],
53 # [u'1361', u'0', u'0', u'0', u'0'],
54 # [u'1362', u'0', u'0', u'0', u'0'],
55 # [u'1363', u'0', u'0', u'0', u'0'],
56 # [u'1364', u'0', u'0', u'0', u'0']]]
58 # [[[u'4', u'3', u'32400000'],
59 # [u'80', u'1', u'25200000'],
60 # [u'81', u'2', u'27600000'],
61 # [u'82', u'4', u'38800000']],
62 # [[u'3', u'104052489', u'22364', u'23308', u'389']],
63 # []]
65 factory_settings["docsis_channels_upstream_default_levels"] = {
66 "signal_noise": (10.0, 5.0), # dB
67 "corrected": (5.0, 8.0), # Percent
68 "uncorrectable": (1.0, 2.0), # Percent
72 def parse_docsis_channels_upstream(info):
73 freq_info = info[0]
74 freq_info_dict = dict([(x[0], x[1:]) for x in freq_info])
75 sig_info_dict = dict([(x[0], x[1:]) for x in info[1]])
76 cm_info_dict = dict([(x[0], x[1:]) for x in info[2]])
78 parsed = {}
79 for endoid, (cid, freq_str) in freq_info_dict.items():
80 unique_name = cid if len(freq_info) == len({x[1] for x in freq_info
81 }) else ('%s.%s' % (endoid, cid))
83 data = []
84 if endoid in sig_info_dict:
85 data = sig_info_dict[endoid] + cm_info_dict.get(endoid, [])
86 elif cid in sig_info_dict:
87 data = sig_info_dict[cid] + cm_info_dict.get(cid, [])
89 if data:
90 parsed[unique_name] = [float(freq_str)] + data
92 return parsed
95 def inventory_docsis_channels_upstream(parsed):
96 for unique_name, entry in parsed.items():
97 if entry[0] != '0' and entry[4] != '0':
98 yield unique_name, {}
101 def check_docsis_channels_upstream(item, params, parsed):
102 if item in parsed:
103 entry = parsed[item]
104 mhz, unerroreds, correcteds, uncorrectables, signal_noise = entry[:5]
106 # Signal Noise
107 noise_db = float(signal_noise) / 10
108 infotext = "Signal/Noise ratio: %.2f dB" % noise_db
109 warn, crit = params['signal_noise']
111 state = 0
112 if noise_db < crit:
113 state = 2
114 elif noise_db < warn:
115 state = 1
117 if state:
118 infotext += " (warn/crit below %.1f/%.1f dB)" % (warn, crit)
120 yield state, infotext, [('signal_noise', noise_db, warn, crit)]
122 fields = [("frequency", float(mhz) / 1000000, "Frequency", "%.2f", " MHz")]
123 if len(entry) >= 6:
124 total, active, registered, avg_util = entry[5:9]
125 fields += [("total", int(total), "Modems total", "%d", ""),
126 ("active", int(active), "Active", "%d", ""),
127 ("registered", int(registered), "Registered", "%d", ""),
128 ("util", int(avg_util), "Aaverage utilization", "%d", "%")]
130 for varname, value, title, form, unit in fields:
131 yield 0, title + ": " + (form + "%s") % (value, unit), [(varname, value)]
133 # Handle codewords. These are counters.
134 now = time.time()
135 rates = {}
136 total_rate = 0.0
137 for what, counter in [(
138 "unerrored",
139 int(unerroreds),
140 ), (
141 "corrected",
142 int(correcteds),
143 ), ("uncorrectable", int(uncorrectables))]:
144 rate = get_rate("docsis_channels_upstream.%s.%s" % (item, what), now, counter)
145 rates[what] = rate
146 total_rate += rate
148 if total_rate:
149 for what, title in [(
150 "corrected",
151 "corrected errors",
152 ), (
153 "uncorrectable",
154 "uncorrectable errors",
156 ratio = rates[what] / total_rate
157 perc = 100.0 * ratio
158 warn, crit = params[what]
159 infotext = "%s %s" % (get_percent_human_readable(perc), title)
161 if perc >= crit:
162 state = 2
163 elif perc >= crit:
164 state = 1
166 if state:
167 infotext += " (warn/crit at %.1f/%.1f%%)" % (warn, crit)
169 yield state, infotext, [("codewords_" + what, ratio, warn / 100.0, crit / 100.0)]
172 check_info["docsis_channels_upstream"] = {
173 "parse_function": parse_docsis_channels_upstream,
174 "inventory_function": inventory_docsis_channels_upstream,
175 "check_function": check_docsis_channels_upstream,
176 "service_description": "Upstream Channel %s",
177 "has_perfdata": True,
178 "snmp_scan_function": docsis_scan_function,
179 "snmp_info": [
181 ".1.3.6.1.2.1.10.127.1.1.2.1",
183 OID_END,
184 "1", # DOCS-IF-MIB::docsIfUpChannelId
185 "2", # DOCS-IF-MIB::docsIfUpChannelFrequency
188 ".1.3.6.1.2.1.10.127.1.1.4.1",
190 OID_END,
191 "2", # DOCS-IF-MIB::docsIfSigQUnerroreds:
192 # "Codewords received on this channel without error.
193 # This includes all codewords, whether or not they
194 # were part of frames destined for this device."
195 "3", # DOCS-IF-MIB::docsIfSigQCorrecteds:
196 # "Codewords received on this channel with correctable
197 # errors. This includes all codewords, whether or not
198 # they were part of frames destined for this device."
199 "4", # DOCS-IF-MIB::docsIfSigQUncorrectables:
200 # "Codewords received on this channel with uncorrectable
201 # errors. This includes all codewords, whether or not
202 # they were part of frames destined for this device."
203 "5", # DOCS-IF-MIB::docsIfSigQSignalNoise
206 ".1.3.6.1.4.1.9.9.116.1.4.1.1",
208 OID_END,
209 "3", # CISCO-DOCS-EXT-MIB::cdxIfUpChannelCmTotal
210 "4", # CISCO-DOCS-EXT-MIB::cdxIfUpChannelCmActive
211 "5", # CISCO-DOCS-EXT-MIB::cdxIfUpChannelCmRegistered
212 "7", # CISCO-DOCS-EXT-MIB::cdxIfUpChannelAvgUtil
215 "default_levels_variable": "docsis_channels_upstream_default_levels",
216 "group": "docsis_channels_upstream",
217 "includes": ["docsis.include"],