Module: check_mk
Branch: master
Commit: 4ceb309e259023ad5c329a032354162b27c40e72
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=4ceb309e259023…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Thu Mar 17 09:48:02 2011 +0100
diskstat: rewritten check: now show different devices
---
ChangeLog | 1 +
checkman/diskstat | 2 +-
checks/diskstat | 99 +++++++++++++++++++++++-----------
pnp-templates/check_mk-diskstat.php | 48 ++++++++++++++---
web/plugins/perfometer/check_mk.py | 13 +++++
web/plugins/views/perfometer.py | 28 ++++++++++
6 files changed, 151 insertions(+), 40 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d6de430..a368655 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -34,6 +34,7 @@
with index 1
* df: split PNP graphs for growth/trend into two graphs
* omd_status: new check for checking status of OMD sites
+ * diskstat: rewritten check: now show different devices, r+w in one check
1.1.10:
diff --git a/checkman/diskstat b/checkman/diskstat
index 098bbb9..9ef5a5b 100644
--- a/checkman/diskstat
+++ b/checkman/diskstat
@@ -1,4 +1,4 @@
-title: Measure Disk IO
+title: Monitor disk throughput on Linux
agents: linux
author: Mathias Kettner <mk(a)mathias-kettner.de>
license: GPL
diff --git a/checks/diskstat b/checks/diskstat
index 8819cd2..e4bff2b 100644
--- a/checks/diskstat
+++ b/checks/diskstat
@@ -24,46 +24,81 @@
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA.
+# <<<diskstat>>>
+# 1300264105
+# 8 0 sda 691860 951191 13559915 491748 234686 197346 3359512 94944 0 56844
586312
+# 8 32 sdb 791860 91191 23589915 491748 234686 197346 3359512 94944 0 56844
586312
-def inventory_diskstat(checkname, info):
- if len(info) > 1: # first line is timestamp
- return [('read', "", "None"),
- ('write', "", "None")]
-
-# Fields in /proc/diskstat
-# At the beginning: major minor devicename
-#
-# Field 1 -- # of reads issued
-# Field 2 -- # of reads merged, field 6 -- # of writes merged
-# Field 3 -- # of sectors read
-# Field 4 -- # of milliseconds spent reading
-# Field 5 -- # of writes completed
-# Field 7 -- # of sectors written
-# Field 8 -- # of milliseconds spent writing
-# Field 9 -- # of I/Os currently in progress
-# Field 10 -- # of milliseconds spent doing I/Os
-# Field 11 -- weighted # of milliseconds spent doing I/Os
+# Fields in /proc/diskstats
+# Index 0 -- major number
+# Index 1 -- minor number
+# Index 2 -- device name
+# Index 3 -- # of reads issued
+# Index 4 -- # of reads merged, field 6 -- # of writes merged
+# Index 5 -- # of sectors read (a 512 Byte)
+# Index 6 -- # of milliseconds spent reading
+# Index 7 -- # of writes completed
+# Index 8 -- # of sectors written (a 512 Byte)
+# Index 9 -- # of milliseconds spent writing
+# Index 10 -- # of I/Os currently in progress
+# Index 11 -- # of milliseconds spent doing I/Os
+# Index 12 -- weighted # of milliseconds spent doing I/Os
#
# -> Field 1 has index 3
+diskstat_default_levels = {
+# "read" : (10, 20), # MB/sec
+# "write" : (20, 40), # MB/sec
+# "average" : 15, # min
+}
-# major minor device ...
-def check_diskstat(item, params, info):
- # sum up over all devices
- if item == 'read':
- index = 5 # sectors read
- elif item == 'write':
- index = 9 # sectors written
- else:
- return (3, "UNKNOWN - invalid item %s" % (item,))
+def inventory_diskstat(checkname, info):
+ inventory = []
+ for line in info[1:]:
+ inventory.append( (line[2], "diskstat_default_levels" ) )
+ return inventory
+def check_diskstat(item, params, info):
+ average_range = params.get("average")
this_time = int(info[0][0])
- this_val = sum([int(x[index]) for x in info[1:]])
+ for line in info[1:]:
+ if line[2] == item:
+ perfdata = []
+ infos = []
+ status = 0
+ for what, ctr in [ ("read", line[5]), ("write", line[8])
]:
+ countername = "diskstat.%s.%s" % (item, what)
+
+ # compute IO rate in bytes/sec
+ timedif, sectors_per_sec = get_counter(countername, this_time, int(ctr))
+ bytes_per_sec = sectors_per_sec * 512
+ infos.append("%s/sec %s" %
(get_bytes_human_readable(bytes_per_sec), what))
+ perfdata.append( (what, bytes_per_sec) )
+
+ # compute average of the rate over ___ minutes
+ if average_range != None:
+ timedif, avg = get_average(countername + ".avg", this_time,
bytes_per_sec, average_range * 60)
+ perfdata.append( (what + ".avg", avg) )
+ bytes_per_sec = avg
+
+ # check levels
+ levels = params.get(what)
+ if levels != None:
+ mb_per_sec = bytes_per_sec / 1048576
+ warn, crit = levels
+ if mb_per_sec >= crit:
+ status = 2
+ infos[-1] += "!!"
+ elif mb_per_sec >= warn:
+ status = max(status, 1)
+ infos[-1] += "!"
+
+ if average_range != None:
+ perfdata = [ perfdata[0], perfdata[2], perfdata[1], perfdata[3] ]
- timedif, per_sec = get_counter("diskstat." + item, this_time, this_val)
- mb_per_s = per_sec / 2048.0 # Diskstat output is in sectors a 512 Byte
- perfdata = [ (item, "%dc" % this_val ) ]
- return (0, "OK - %.1fMB/s (in last %d secs)" % (mb_per_s, timedif),
perfdata)
+ return (status, nagios_state_names[status] + " - " + ",
".join(infos) , perfdata)
+
+ return (3, "UNKNOWN - device missing")
check_info['diskstat'] = (check_diskstat, "Disk IO %s", 1,
inventory_diskstat)
diff --git a/pnp-templates/check_mk-diskstat.php b/pnp-templates/check_mk-diskstat.php
index 195c0e4..48b006d 100644
--- a/pnp-templates/check_mk-diskstat.php
+++ b/pnp-templates/check_mk-diskstat.php
@@ -23,12 +23,46 @@
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA.
-$opt[1] = "--vertical-label 'Througput (MByte/s)' -l0 -u 1 --title
\"Disk throughput $hostname / $servicedesc\" ";
+$parts = explode("_", $servicedesc);
+$disk = $parts[2];
-$def[1] = "DEF:kb=$RRDFILE[1]:$DS[1]:AVERAGE " ;
-$def[1] .= "CDEF:mb=kb,1024,/ " ;
-$def[1] .= "AREA:mb#40c080 " ;
-$def[1] .= "GPRINT:mb:LAST:\"%6.1lf MByte/s last\" " ;
-$def[1] .= "GPRINT:mb:AVERAGE:\"%6.1lf MByte/s avg\" " ;
-$def[1] .= "GPRINT:mb:MAX:\"%6.1lf MByte/s max\\n\" ";
+$opt[1] = "--vertical-label 'Throughput (MB/s)' -X0 --title \"Disk
throughput $hostname / $disk\" ";
+
+$def[1] =
+ "HRULE:0#a0a0a0 ".
+# read
+ "DEF:read=$RRDFILE[1]:$DS[1]:MAX ".
+ "CDEF:read_mb=read,1048576,/ ".
+ "AREA:read_mb#40c080:\"Read \" ".
+ "GPRINT:read_mb:LAST:\"%6.1lf MByte/s last\" ".
+ "GPRINT:read_mb:AVERAGE:\"%6.1lf MByte/s avg\" ".
+ "GPRINT:read_mb:MAX:\"%6.1lf MByte/s max\\n\" ";
+
+# read average
+if (isset($DS[3])) {
+ $def[1] .=
+ "DEF:read_avg=$RRDFILE[3]:$DS[3]:MAX ".
+ "CDEF:read_avg_mb=read_avg,1048576,/ ".
+ "LINE:read_avg_mb#202020 ";
+}
+
+# write
+$def[1] .=
+ "DEF:write=$RRDFILE[2]:$DS[2]:MAX ".
+ "CDEF:write_mb=write,1048576,/ ".
+ "CDEF:write_mb_neg=write_mb,-1,* ".
+ "AREA:write_mb_neg#4080c0:Write ".
+ "GPRINT:write_mb:LAST:\"%6.1lf MByte/s last\" ".
+ "GPRINT:write_mb:AVERAGE:\"%6.1lf MByte/s avg\" ".
+ "GPRINT:write_mb:MAX:\"%6.1lf MByte/s max\\n\" ".
+ "";
+
+# write average
+if (isset($DS[3])) {
+ $def[1] .=
+ "DEF:write_avg=$RRDFILE[4]:$DS[4]:MAX ".
+ "CDEF:write_avg_mb=write_avg,1048576,/ ".
+ "CDEF:write_avg_mb_neg=write_avg_mb,-1,* ".
+ "LINE:write_avg_mb_neg#202020 ";
+}
?>
diff --git a/web/plugins/perfometer/check_mk.py b/web/plugins/perfometer/check_mk.py
index f7be5aa..8aaa712 100644
--- a/web/plugins/perfometer/check_mk.py
+++ b/web/plugins/perfometer/check_mk.py
@@ -271,3 +271,16 @@ def perfometer_check_mk_uptime(row, check_command, perf_data):
perfometers["check_mk-uptime"] = perfometer_check_mk_uptime
perfometers["check_mk-snmp_uptime"] = perfometer_check_mk_uptime
+
+def perfometer_check_mk_diskstat(row, check_command, perf_data):
+ read_bytes = float(perf_data[0][1])
+ write_bytes = float(perf_data[1][1])
+
+ text = "%-.2fM/s %-.2fM/s" % \
+ (read_bytes / (1024*1024.0), write_bytes / (1024*1024.0))
+
+ return text, perfometer_logarithmic_dual(
+ read_bytes, "#60e0a0", write_bytes, "#60a0e0", 5000000,
10)
+
+perfometers["check_mk-diskstat"] = perfometer_check_mk_diskstat
+
diff --git a/web/plugins/views/perfometer.py b/web/plugins/views/perfometer.py
index afd7b84..2fdac40 100644
--- a/web/plugins/views/perfometer.py
+++ b/web/plugins/views/perfometer.py
@@ -61,6 +61,34 @@ def perfometer_logarithmic(value, half_value, base, color):
"</tr></table>"
+# Dual logarithmic Perf-O-Meter
+def perfometer_logarithmic_dual(value_left, color_left, value_right, color_right,
half_value, base):
+ result = '<table><tr>'
+ for where, value, color in [
+ ("left", value_left, color_left),
+ ("right", value_right, color_right) ]:
+ value = float(value)
+ if value == 0.0:
+ pos = 0
+ else:
+ half_value = float(half_value)
+ h = math.log(half_value, base) # value to be displayed at 50%
+ pos = 25 + 10.0 * (math.log(value, base) - h)
+ if pos < 1:
+ pos = 1
+ if pos > 49:
+ pos = 49
+
+ if where == "right":
+ result += perfometer_td(pos, color) + \
+ perfometer_td(50 - pos, "white")
+ else:
+ result += perfometer_td(50 - pos, "white") + \
+ perfometer_td(pos, color)
+
+ return result + '</tr></table>'
+
+
perfometer_plugins_dir = defaults.web_dir + "/plugins/perfometer"
for fn in os.listdir(perfometer_plugins_dir):
if fn.endswith(".py"):