/usr/share/check_mk/checks/df.include is in check-mk-server 1.1.12-1ubuntu1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | #!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# | ____ _ _ __ __ _ __ |
# | / ___| |__ ___ ___| | __ | \/ | |/ / |
# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
# | | |___| | | | __/ (__| < | | | | . \ |
# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
# | |
# | Copyright Mathias Kettner 2010 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-
# ails. 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.
# Common include file for all filesystem checks (df, df_netapp, hr_fs, ...)
# Settings for filesystem checks (df, df_vms, df_netapp and maybe others)
filesystem_levels = [] # obsolete. Just here to check config and warn if changed
filesystem_default_levels = {} # can also be dropped some day in future
# Filesystems to ignore (shouldn't be sent by agent anyway)
inventory_df_exclude_fs = [ 'nfs', 'smbfs', 'cifs', 'iso9660' ]
inventory_df_exclude_mountpoints = [ '/dev' ]
# Alternative syntax for parameters:
# { "levels" : (80, 90), # levels in percent
# "magic" : 0.5, # magic factor
# "magic_normsize" : 20, # normsize in GB
# "levels_low" : (50, 60), # magic never lowers levels below this (percent)
# "trend_range" : 24, # hours
# "trend_mb" : (10, 20), # MB of change during trend_range
# "trend_perc" : (1, 2), # Percent change during trend_range
# "trend_timeleft" : (72, 48) # run time left in hours until full
# }
factory_settings["filesystem_default_levels"] = {
"levels" : (80, 90), # warn/crit in percent
"magic_normsize" : 20, # Standard size if 20 GB
"levels_low" : (50, 60), # Never move warn level below 50% due to magic factor
"trend_range" : 24,
"trend_perfdata" : True, # do send performance data for trends
}
# Users might have set filesystem_default_levels to old format like (80, 90)
# needed by df, df_netapp and vms_df and maybe others in future:
# compute warning and critical levels. Takes into account the size of
# the filesystem and the magic number. Since the size is only known at
# check time this function's result cannot be precompiled.
# Note: this function is in our days only needed in order to support
# old style params a'la (80, 90). As soon as we drop support for that
# (can happen any decade now), we can get rid of this function.
def get_filesystem_levels(host, mountpoint, size_gb, params):
# Start with factory settings
levels = factory_settings["filesystem_default_levels"].copy()
# convert default levels to dictionary. This is in order support
# old style levels like (80, 90)
if type(filesystem_default_levels) == dict:
levels.update(filesystem_default_levels)
else:
levels = factory_settings["filesystem_default_levels"].copy()
levels["levels"] = filesystem_default_levels[:2]
if len(filesystem_default_levels) == 2:
levels["magic"] = None
else:
levels["magic"] = filesystem_default_levels[2]
# If params is a dictionary, make that override the default values
if type(params) == dict:
levels.update(params)
else: # simple format - explicitely override levels and magic
levels["levels"] = params[:2]
if len(params) >= 3:
levels["magic"] = params[2]
warn, crit = levels["levels"]
# If the magic factor is used, take disk size and magic factor
# into account in order to move levels
magic = levels.get("magic")
if magic:
normsize = levels["magic_normsize"]
hgb_size = size_gb / float(normsize)
felt_size = hgb_size ** magic
scale = felt_size / hgb_size
warn_scaled = 100 - (( 100 - warn ) * scale)
crit_scaled = 100 - (( 100 - crit ) * scale)
# Make sure, levels do never get too low due to magic factor
lowest_warning_level, lowest_critical_level = levels["levels_low"]
if warn_scaled < lowest_warning_level:
warn_scaled = lowest_warning_level
if crit_scaled < lowest_critical_level:
crit_scaled = lowest_critical_level
else:
warn_scaled = warn
crit_scaled = crit
size_mb = size_gb * 1024
warn_mb = int(size_mb * warn_scaled / 100)
crit_mb = int(size_mb * crit_scaled / 100)
levels["levels_mb"] = (warn_mb, crit_mb)
levels["levels_text"] = "(levels at %.1f/%.1f%%)" % (warn_scaled, crit_scaled)
return levels
def df_check_filesystem(hostname, mountpoint, size_mb, avail_mb, params):
if size_mb == 0:
return (1, "WARN - size of filesystem is 0 MB")
used_mb = size_mb - avail_mb
used_perc = 100.0 * (float(used_mb) / size_mb)
size_gb = size_mb / 1024.0
# Get warning and critical levels already with 'magic factor' applied
levels = get_filesystem_levels(g_hostname, mountpoint, size_gb, params)
warn_mb, crit_mb = levels["levels_mb"]
# Take into account magic scaling factor (third optional argument
# in check params). A factor of 1.0 changes nothing. Factor should
# be > 0 and <= 1. A smaller factor raises levels for big file systems
# bigger than 100 GB and lowers it for file systems smaller than 100 GB.
# Please run df_magic_factor.py to understand how it works.
perfdata = [(mountpoint, str(used_mb) + 'MB', warn_mb, crit_mb, 0, size_mb)]
infotext = "%.1f%% used (%.2f of %.1f GB), %s" % \
(used_perc, used_mb / 1024.0, size_gb, levels["levels_text"])
# Trends. The trends are computed in two steps. In the first step we
# compute the delta to the last check, using a normal check_mk counter.
# In the second step we compute an average over that counter and can
# make a long-time prediction. If we have that values we can optionally
# apply levels.
# Trend parameters:
# "trend_range" : 24, # hours
# "trend_mb" : (10, 20), # MB of change during trend_range
# "trend_perc" : (1, 2), # Percent change during trend_range
# "trend_timeleft" : (72, 48) # run time left in hours until full
status = 0
problems = []
MB = 1024 * 1024.0
if levels.get("trend_range"):
try:
range = levels["trend_range"] # in hours
range_sec = range * 3600.0
this_time = time.time()
# first compute current rate in MB/s by computing delta since last check
timedif, rate = get_counter("df.%s.delta" % mountpoint, this_time, used_mb, True)
if levels.get("trend_perfdata"):
perfdata.append(("growth", rate * range_sec))
# average trend, initialize with zero, rate_avg is in MB/s
timedif, rate_avg = get_average("df.%s.trend" % mountpoint,
this_time, rate, range_sec / 60.0, True)
# rate_avg is growth in MB/s, trend is in MB per trend range hours
trend = rate_avg * range_sec
sign = trend > 0 and "+" or ""
infotext += ", trend: %s%s / %g hours" % \
(sign, get_bytes_human_readable(trend * MB), range)
# levels for performance data
warn_perf, crit_perf = None, None
# apply levels for absolute growth in MB / interval
trend_mb = levels.get("trend_mb")
if trend_mb:
wa, cr = trend_mb
warn_perf, crit_perf = wa, cr
if trend >= wa:
problems.append("growing too fast (levels at %s/%s per %.1fh)!" %
( get_bytes_human_readable(wa * MB), get_bytes_human_readable(cr * MB), range))
status = max(1, status)
if trend >= cr:
status = 2
problems[-1] += "!"
else:
wa, cr = None, None
# apply levels for growth relative to filesystem size
trend_perc = levels.get("trend_perc")
if trend_perc:
wa_perc, cr_perc = trend_perc
wa = wa_perc / 100.0 * size_mb
cr = cr_perc / 100.0 * size_mb
if warn_perf != None:
warn_perf = min(warn_perf, wa)
crit_perf = min(crit_perf, cr)
else:
warn_perf, crit_perf = wa, cr
if trend >= wa:
problems.append("growing too fast (levels at %.3f%%/%.3f%% per %.1fh)!" %
( wa_perc, cr_perc, range))
status = max(1, status)
if trend >= cr:
status = 2
problems[-1] += "!"
if levels.get("trend_perfdata"):
perfdata.append(("trend", trend, warn_perf, crit_perf, 0, size_mb / range))
# compute time until filesystem is full (only for positive trend, of course)
if trend > 0:
space_left = size_mb - used_mb
hours_left = space_left / trend * range
timeleft = levels.get("trend_timeleft")
if timeleft:
wa, cr = timeleft
if hours_left <= cr:
status = 2
problems.append("only %.1fh until disk full!!" % hours_left)
elif hours_left <= wa:
status = max(status, 1)
problems.append("only %.1fh until disk full!" % hours_left)
elif hours_left <= wa * 2:
problems.append("time left: %.1fh" % hours_left)
except MKCounterWrapped:
# need more data for computing a trend
# In this case erase all perfdata to prevent an rrd file which has no space
# for the trend information
perfdata = []
if used_mb >= crit_mb:
status = 2
elif used_mb >= warn_mb:
status = max(1, status)
if len(problems) > 0:
infotext += " - " + ", ".join(problems)
return (status, nagios_state_names[status] + " - " + infotext, perfdata)
|