#!/usr/bin/python # +------------------------------------------------------------------+ # | ____ _ _ __ __ _ __ | # | / ___| |__ ___ ___| | __ | \/ | |/ / | # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / | # | | |___| | | | __/ (__| < | | | | . \ | # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ | # | | # | Copyright Mathias Kettner 2018 mk@mathias-kettner.de | # +------------------------------------------------------------------+ # # This file is part of Check_MK. # The official homepage is at http://mathias-kettner.de/check_mk. # # check_mk is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation in version 2. check_mk is distributed # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with- # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. See the GNU General Public License for more de- # tails. You should have received a copy of the GNU General Public # License along with GNU Make; see the file COPYING. If not, write # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, # Boston, MA 02110-1301 USA. # example output # #y.y.y.y:/mount/name mounted on /var/log/da: # # op/s rpc bklog #2579.20 0.00 #read: ops/s kB/s kB/op retrans avg RTT (ms) avg exe (ms) # 0.000 0.000 0.000 0 (0.0%) 0.000 0.000 #write: ops/s kB/s kB/op retrans avg RTT (ms) avg exe (ms) # 2578.200 165768.087 64.296 0 (0.0%) 21.394 13980.817 # #x.x.x.x:/mount/name mounted on /data: # ... factory_settings["nfsiostat_default_levels"] = { "op_s" : (2500000.00, 2600000.00), "rpc_backlog" : (2500000.00, 2600000.00), "read_ops" : (2500000.00, 2600000.00), "read_b_s" : (2500000.00, 2600000.00), "read_b_op" : (2500000.00, 2600000.00), "read_retrans" : (2500000.0, 2600000.0), "read_avg_rtt_ms" : (2500000.00, 2600000.00), "read_avg_exe_ms" : (2500000.00, 2600000.00), "write_ops_s" : (2500000.00, 2600000.00), "write_b_s" : (2500000.00, 2600000.00), "write_b_op" : (2500000.00, 2600000.00), "write_retrans" : (2500000.0, 2600000.0), "write_avg_rtt_ms" : (2500000.00, 2600000.00), "write_avg_exe_ms" : (2500000.00, 2600000.0), } # we can convert once it is clear what the format/standards are # count, (item (name), title, factor, fmt,) param_name = { "0" : ("op_s","Operations", 1, "%.2f/s"), "1" : ("rpc_backlog", "RPC Backlog", 1, "%.2f"), "2" : ("read_ops", "Read operations", 1, "%.3f/s"), "3" : ("read_b_s", "Reads per second", 1000, "%.3fB/s"), "4" : ("read_b_op", "Read bytes", 1000, "%.3fB/op"), "5" : ("read_retrans", "Read Retransmission", 1, "%.1f%%"), "6" : ("read_retrans", "Read Retransmission", 1, "%.1f%%"), "7" : ("read_avg_rtt_ms", "Read average RTT", 1000, "%.3f/s",), "8" : ("read_avg_exe_ms", "Read average EXE", 1000, "%.3f/s",), "9" : ("write_ops_s", "Write operations", 1, "%.3f/s"), "10" : ("write_b_s", "Writes per second", 1000, "%.3fkB/s"), "11" : ("write_b_op", "Write bytes", 1000, "%.3fB/op"), "12" : ("write_retrans", "Write Retransmission", 1, "%.1f%%"), "13" : ("write_retrans", "Write Retransmission", 1, "%.3f%%"), "14" : ("write_avg_rtt_ms", "Write Average RTT", 1, "%.3f/ms"), "15" : ("write_avg_exe_ms", "Write Average EXE", 1, "%.3f/ms"), } def parse_nfsiostat(info): #removes double list [new_info] = info import re # provides a dictionary with mountpoint as key and a list of 16 metrics # in exact order parsed = {m[0]: m[1:] for m in re.findall(r'(\S+:/\S+)%s' % \ (r'.*?([\d.]+)' * 16), str(new_info).strip('[]'), flags=re.DOTALL)} return parsed def inventory_nfsiostat(parsed): inventory = [] for mountname in parsed.keys(): yield mountname, "nfsiostat_default_levels" def check_nfsiostat(item, params, parsed): # check the value we recieved against our map of values # assign appropriate type to value def check_nfsiostat_params(count, value): item = param_name[str(count)][0] title = param_name[str(count)][1] factor = param_name[str(count)][2] fmt = param_name[str(count)][3] value = float(value) crit = float(params[item][1]) warn = float(params[item][0]) # convert value = factor * value # match on item or fmt if item == "read_ops": # if fmt == "%.3f/s": value = value / factor if value >= crit: perfdata = [ (item, value, warn, crit ) ] return(2, "%s: %s" % (title, fmt % value), perfdata) elif value >= warn: perfdata = [ (item, value, warn, crit ) ] return(1, "%s: %s" % (title, fmt % value), perfdata) else: perfdata = [ (item, value, warn, crit ) ] return(0, "%s: %s" % (title, fmt % value), perfdata) for mountpoint, values in parsed.items(): # We have duplicate items at index 5 and 12. We exclude the dupes here if mountpoint == item: count = 0 for value in values: if count != 5 and count != 12: yield(check_nfsiostat_params(count, value)) count = count + 1 check_info['nfsiostat'] = { 'parse_function' : parse_nfsiostat, 'inventory_function' : inventory_nfsiostat, 'check_function' : check_nfsiostat, 'service_description' : 'NFS IO stats %s', 'group' : 'nfsiostats', 'default_levels_variable': 'nfsiostat_default_levels', 'has_perfdata' : True, #'includes' : ['size_trend.include', 'df.include'] }