1 changed file
check_ram.py + | ||
Add comment 1 Plus #!/usr/bin/env python
Add comment 2 Plus #
Add comment 3 Plus # Author: Hari Sekhon
Add comment 4 Plus # Date: 2007-02-25 22:58:59 +0000 (Sun, 25 Feb 2007)
Add comment 5 Plus #
Add comment 6 Plus # http://github.com/harisekhon
Add comment 7 Plus #
Add comment 8 Plus # License: see accompanying LICENSE file
Add comment 9 Plus #
Add comment 10 Plus
Add comment 11 Plus """
Add comment 12 Plus Nagios plugin to check the amount of ram used on a Linux box. Takes in to
Add comment 13 Plus account cache and returns performance data for graphing as well.
Add comment 14 Plus """
Add comment 15 Plus
Add comment 16 Plus __author__ = "Hari Sekhon"
Add comment 17 Plus __title__ = "Nagios Plugin to check RAM used on Linux"
Add comment 18 Plus __version__ = "0.2"
Add comment 19 Plus
Add comment 20 Plus from sys import exit
Add comment 21 Plus from optparse import OptionParser
Add comment 22 Plus
Add comment 23 Plus
Add comment 24 Plus # Standard Exit Codes for Nagios
Add comment 25 Plus OK = 0
Add comment 26 Plus WARNING = 1
Add comment 27 Plus CRITICAL = 2
Add comment 28 Plus UNKNOWN = 3
Add comment 29 Plus
Add comment 30 Plus
Add comment 31 Plus def check_ram(warning_threshold, critical_threshold, percent, verbosity, \
Add comment 32 Plus nocache):
Add comment 33 Plus """Takes warning and critical thresholds in KB or percentage if third
Add comment 34 Plus argument is true, and returns a result depending on whether the amount free
Add comment 35 Plus ram is less than the thresholds"""
Add comment 36 Plus
Add comment 37 Plus if verbosity >= 3:
Add comment 38 Plus print "Opening /proc/meminfo"
Add comment 39 Plus try:
Add comment 40 Plus f = open('/proc/meminfo')
Add comment 41 Plus except IOError, e:
Add comment 42 Plus print "RAM CRITICAL: Error opening /proc/meminfo - %s" % str(e)
Add comment 43 Plus return CRITICAL
Add comment 44 Plus
Add comment 45 Plus output = f.readlines()
Add comment 46 Plus
Add comment 47 Plus for x in range(len(output)):
Add comment 48 Plus y = output[x].split()
Add comment 49 Plus if y [0] == "MemTotal:":
Add comment 50 Plus memtotal = int(y[1])
Add comment 51 Plus elif y[0] == "MemFree:":
Add comment 52 Plus memfree = int(y[1])
Add comment 53 Plus elif y[0] == "Cached:":
Add comment 54 Plus memcached = int(y[1])
Add comment 55 Plus
Add comment 56 Plus for x in memtotal, memfree, memcached:
Add comment 57 Plus if x == None:
Add comment 58 Plus print "UNKNOWN: failed to get mem stats"
Add comment 59 Plus return UNKNOWN
Add comment 60 Plus
Add comment 61 Plus if nocache == True:
Add comment 62 Plus total_free = memfree
Add comment 63 Plus else:
Add comment 64 Plus total_free = memfree + memcached
Add comment 65 Plus
Add comment 66 Plus total_used_megs = ( memtotal - total_free ) / 1024.0
Add comment 67 Plus #total_free_megs = total_free / 1024.0
Add comment 68 Plus memtotal_megs = memtotal / 1024.0
Add comment 69 Plus
Add comment 70 Plus if percent == True:
Add comment 71 Plus warning_threshold_megs = \
Add comment 72 Plus memtotal_megs * (100 - warning_threshold) / 100.0
Add comment 73 Plus critical_threshold_megs = \
Add comment 74 Plus memtotal_megs * (100 - critical_threshold) / 100.0
Add comment 75 Plus else:
Add comment 76 Plus warning_threshold_megs = memtotal_megs - warning_threshold
Add comment 77 Plus critical_threshold_megs = memtotal_megs - critical_threshold
Add comment 78 Plus
Add comment 79 Plus percentage_free = int( float(total_free) / float(memtotal) * 100 )
Add comment 80 Plus stats = "%d%% ram free (%d/%d MB used)" \
Add comment 81 Plus % (percentage_free, total_used_megs, memtotal_megs) \
Add comment 82 Plus + "|'RAM Used'=%.2fMB;%.2f;%.2f;0;%.2f" % \
Add comment 83 Plus (total_used_megs, warning_threshold_megs, critical_threshold_megs, \
Add comment 84 Plus memtotal_megs)
Add comment 85 Plus
Add comment 86 Plus if percent == True:
Add comment 87 Plus if percentage_free < critical_threshold:
Add comment 88 Plus print "RAM CRITICAL:",
Add comment 89 Plus print "%s" % stats
Add comment 90 Plus return CRITICAL
Add comment 91 Plus elif percentage_free < warning_threshold:
Add comment 92 Plus print "RAM WARNING:",
Add comment 93 Plus print "%s" % stats
Add comment 94 Plus return WARNING
Add comment 95 Plus else:
Add comment 96 Plus print "RAM OK:",
Add comment 97 Plus print "%s" % stats
Add comment 98 Plus return OK
Add comment 99 Plus else:
Add comment 100 Plus if total_free < critical_threshold:
Add comment 101 Plus print "RAM CRITICAL:",
Add comment 102 Plus print "%s" % stats
Add comment 103 Plus return CRITICAL
Add comment 104 Plus if total_free < warning_threshold:
Add comment 105 Plus print "RAM WARNING:",
Add comment 106 Plus print "%s" % stats
Add comment 107 Plus return WARNING
Add comment 108 Plus else:
Add comment 109 Plus print "RAM OK:",
Add comment 110 Plus print "%s" % stats
Add comment 111 Plus return OK
Add comment 112 Plus
Add comment 113 Plus
Add comment 114 Plus def main():
Add comment 115 Plus """main func, parse args, do sanity checks and call check_ram func"""
Add comment 116 Plus
Add comment 117 Plus parser = OptionParser()
Add comment 118 Plus
Add comment 119 Plus parser.add_option("-n", "--no-include-cache",
Add comment 120 Plus action="store_true", dest="nocache",
Add comment 121 Plus help="Do not include cache as free ram. Linux tends to "
Add comment 122 Plus + "gobble up free ram as disk cache, but this is freely"
Add comment 123 Plus + " reusable so this plugin counts it as free space by "
Add comment 124 Plus + "default since this is nearly always what you want. "
Add comment 125 Plus + "This switch disables this behaviour so you use only "
Add comment 126 Plus + "the pure free ram. Not advised.")
Add comment 127 Plus parser.add_option("-c", "--critical", dest="critical_threshold",
Add comment 128 Plus help="Critical threshold. Returns a critical status if "
Add comment 129 Plus + "the amount of free ram is less than this number. "
Add comment 130 Plus + "Specify KB, MB or GB after to specify units of "
Add comment 131 Plus + "KiloBytes, MegaBytes or GigaBytes respectively or % "
Add comment 132 Plus + "afterwards to indicate"
Add comment 133 Plus + "a percentage. KiloBytes is used if not specified")
Add comment 134 Plus parser.add_option("-v", "--verbose", action="count", dest="verbosity",
Add comment 135 Plus help="Verbose mode. Good for testing plugin. By default"
Add comment 136 Plus + " only one result line is printed as per Nagios "
Add comment 137 Plus + "standards. Use multiple times for increasing "
Add comment 138 Plus + "verbosity (3 times = debug)")
Add comment 139 Plus parser.add_option("-w", "--warning", dest="warning_threshold",
Add comment 140 Plus help="warning threshold. Returns a warning status if "
Add comment 141 Plus + "the amount of free ram "
Add comment 142 Plus + "is less than this number. Specify KB, MB or GB after"
Add comment 143 Plus + "to specify units of "
Add comment 144 Plus + "KiloBytes, MegaBytes or GigaBytes respectively or % "
Add comment 145 Plus + "afterwards to indicate a percentage. KiloBytes is "
Add comment 146 Plus + "used if not specified")
Add comment 147 Plus
Add comment 148 Plus options, args = parser.parse_args()
Add comment 149 Plus
Add comment 150 Plus # This script doesn't take any args, only options so we print
Add comment 151 Plus # usage and exit if any are found
Add comment 152 Plus if args:
Add comment 153 Plus parser.print_help()
Add comment 154 Plus return UNKNOWN
Add comment 155 Plus
Add comment 156 Plus nocache = False
Add comment 157 Plus
Add comment 158 Plus warning_threshold = options.warning_threshold
Add comment 159 Plus critical_threshold = options.critical_threshold
Add comment 160 Plus nocache = options.nocache
Add comment 161 Plus verbosity = options.verbosity
Add comment 162 Plus
Add comment 163 Plus #==========================================================================#
Add comment 164 Plus # Sanity Checks #
Add comment 165 Plus # This is TOO big really but it allows for #
Add comment 166 Plus # nice flexibility on the command line #
Add comment 167 Plus #==========================================================================#
Add comment 168 Plus if warning_threshold == None:
Add comment 169 Plus print "UNKNOWN: you did not specify a warning threshold\n"
Add comment 170 Plus parser.print_help()
Add comment 171 Plus return UNKNOWN
Add comment 172 Plus elif critical_threshold == None:
Add comment 173 Plus print "UNKNOWN: you did not specify a critical threshold\n"
Add comment 174 Plus parser.print_help()
Add comment 175 Plus return UNKNOWN
Add comment 176 Plus else:
Add comment 177 Plus warning_threshold = str( warning_threshold )
Add comment 178 Plus critical_threshold = str( critical_threshold )
Add comment 179 Plus
Add comment 180 Plus megs = [ "MB", "Mb", "mb", "mB" , "M", "m" ]
Add comment 181 Plus gigs = [ "GB", "Gb", "gb", "gB" , "G", "g" ]
Add comment 182 Plus
Add comment 183 Plus warning_percent = False
Add comment 184 Plus critical_percent = False
Add comment 185 Plus
Add comment 186 Plus def get_threshold(threshold):
Add comment 187 Plus """takes one arg and returns the float threshold value"""
Add comment 188 Plus
Add comment 189 Plus try:
Add comment 190 Plus threshold = float(threshold)
Add comment 191 Plus except ValueError:
Add comment 192 Plus print "UNKNOWN: invalid threshold given"
Add comment 193 Plus exit(UNKNOWN)
Add comment 194 Plus
Add comment 195 Plus return threshold
Add comment 196 Plus
Add comment 197 Plus # Find out if the supplied argument is a percent or a size
Add comment 198 Plus # and get it's value
Add comment 199 Plus if warning_threshold[-1] == "%":
Add comment 200 Plus warning_threshold = get_threshold(warning_threshold[:-1])
Add comment 201 Plus warning_percent = True
Add comment 202 Plus elif warning_threshold[-2:] in megs:
Add comment 203 Plus warning_threshold = get_threshold(warning_threshold[:-2]) * 1024
Add comment 204 Plus elif warning_threshold[-1] in megs:
Add comment 205 Plus warning_threshold = get_threshold(warning_threshold[:-1]) * 1024
Add comment 206 Plus elif warning_threshold[-2:] in gigs:
Add comment 207 Plus warning_threshold = get_threshold(warning_threshold[:-2]) * 1024 * 1024
Add comment 208 Plus elif warning_threshold[-1] in gigs:
Add comment 209 Plus warning_threshold = get_threshold(warning_threshold[:-1]) * 1024 * 1024
Add comment 210 Plus else:
Add comment 211 Plus warning_threshold = get_threshold(warning_threshold)
Add comment 212 Plus
Add comment 213 Plus if critical_threshold[-1] == "%":
Add comment 214 Plus critical_threshold = get_threshold(critical_threshold[:-1])
Add comment 215 Plus critical_percent = True
Add comment 216 Plus elif critical_threshold[-2:] in megs:
Add comment 217 Plus critical_threshold = get_threshold(critical_threshold[:-2]) * 1024
Add comment 218 Plus elif critical_threshold[-1] in megs:
Add comment 219 Plus critical_threshold = get_threshold(critical_threshold[:-1]) * 1024
Add comment 220 Plus elif critical_threshold[-2:] in gigs:
Add comment 221 Plus critical_threshold = get_threshold(critical_threshold[:-2]) * 1024 * \
Add comment 222 Plus 1024
Add comment 223 Plus elif critical_threshold[-1] in gigs:
Add comment 224 Plus critical_threshold = get_threshold(critical_threshold[:-1]) * 1024 * \
Add comment 225 Plus 1024
Add comment 226 Plus else:
Add comment 227 Plus critical_threshold = get_threshold(critical_threshold)
Add comment 228 Plus
Add comment 229 Plus # Make sure that we use either percentages or units but not both as this
Add comment 230 Plus # makes the code more ugly and complex
Add comment 231 Plus if warning_percent == True and critical_percent == True:
Add comment 232 Plus percent_true = True
Add comment 233 Plus elif warning_percent == False and critical_percent == False:
Add comment 234 Plus percent_true = False
Add comment 235 Plus else:
Add comment 236 Plus print "UNKNOWN: please make thresholds either units or percentages, \
Add comment 237 Plus not one of each"
Add comment 238 Plus return UNKNOWN
Add comment 239 Plus
Add comment 240 Plus # This assumes that the percentage units are numeric, which they must be to
Add comment 241 Plus # have gotten through the get_threhold func above
Add comment 242 Plus if warning_percent == True:
Add comment 243 Plus if (warning_threshold < 0) or (warning_threshold > 100):
Add comment 244 Plus print "warning percentage must be between 0 and 100"
Add comment 245 Plus exit(WARNING)
Add comment 246 Plus if critical_percent == True:
Add comment 247 Plus if (critical_threshold < 0) or (critical_threshold > 100):
Add comment 248 Plus print "critical percentage must be between 0 and 100"
Add comment 249 Plus exit(CRITICAL)
Add comment 250 Plus
Add comment 251 Plus if warning_threshold <= critical_threshold:
Add comment 252 Plus print "UNKNOWN: Critical threshold must be less than Warning threshold"
Add comment 253 Plus return UNKNOWN
Add comment 254 Plus
Add comment 255 Plus # End of Sanity Checks
Add comment 256 Plus
Add comment 257 Plus result = check_ram(warning_threshold, critical_threshold, percent_true, \
Add comment 258 Plus verbosity, nocache)
Add comment 259 Plus
Add comment 260 Plus return result
Add comment 261 Plus
Add comment 262 Plus if __name__ == "__main__":
Add comment 263 Plus exit_code = main()
Add comment 264 Plus exit(exit_code)
Add comment 265 Plus