imported check_ram.py
58497178
Hari Sekhon
committed
1 changed file
check_ram.py
/check_ram.py+265
/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