[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/se3master/usr/share/se3/scripts-alertes/ -> check_smartmon (source)

   1  #!/usr/local/bin/python
   2  
   3  # -*- coding: iso8859-1 -*-
   4  #
   5  # $Id: version.py 133 2006-03-24 10:30:20Z fuller $
   6  #
   7  # check_smartmon
   8  # Copyright (C) 2006  daemogorgon.net
   9  #
  10  #   This program is free software; you can redistribute it and/or modify
  11  #   it under the terms of the GNU General Public License as published by
  12  #   the Free Software Foundation; either version 2 of the License, or
  13  #   (at your option) any later version.
  14  #
  15  #   This program is distributed in the hope that it will be useful,
  16  #   but WITHOUT ANY WARRANTY; without even the implied warranty of
  17  #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18  #   GNU General Public License for more details.
  19  #
  20  #   You should have received a copy of the GNU General Public License along
  21  #   with this program; if not, write to the Free Software Foundation, Inc.,
  22  #   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  23  
  24  
  25  """Package versioning
  26  """
  27  
  28  
  29  import os.path
  30  import sys
  31  
  32  from optparse import OptionParser
  33  
  34  
  35  __author__ = "fuller <fuller@daemogorgon.net>"
  36  __version__ = "$Revision$"
  37  
  38  
  39  # path to smartctl
  40  _smartctlPath = "/usr/local/sbin/smartctl"
  41  
  42  # application wide verbosity (can be adjusted with -v [0-3])
  43  _verbosity = 0
  44  
  45  
  46  def parseCmdLine(args):
  47          """Commandline parsing."""
  48  
  49          usage = "usage: %prog [options] device"
  50          version = "%%prog %s" % (__version__)
  51  
  52          parser = OptionParser(usage=usage, version=version)
  53      parser.add_option("-d", "--device", action="store", dest="device", default="", metavar="DEVICE",
  54              help="device to check")
  55          parser.add_option("-v", "--verbosity", action="store",
  56                          dest="verbosity", type="int", default=0,
  57                          metavar="LEVEL", help="set verbosity level to LEVEL; defaults to 0 (quiet), \
  58                                          possible values go up to 3")
  59          parser.add_option("-w", "--warning-threshold", metavar="TEMP", action="store",
  60                          type="int", dest="warningThreshold", default=55,
  61                          help="set temperature warning threshold to given temperature (defaults to 55)")
  62          parser.add_option("-c", "--critical-threshold", metavar="TEMP", action="store",
  63                          type="int", dest="criticalThreshold", default="60",
  64                          help="set temperature critical threshold to given temperature (defaults to 60)")
  65  
  66          return parser.parse_args(args)
  67  # end
  68  
  69  
  70  def checkDevice(path):
  71          """Check if device exists and permissions are ok.
  72          
  73          Returns:
  74                  - 0 ok
  75                  - 1 no such device
  76                  - 2 no read permission given
  77          """
  78  
  79          vprint(3, "Check if %s does exist and can be read" % path)
  80          if not os.access(path, os.F_OK):
  81                  return (1, "UNKNOWN: no such device found")
  82          elif not os.access(path, os.R_OK):
  83                  return (2, "UNKNOWN: no read permission given")
  84          else:
  85                  return (0, "")
  86          # fi
  87  # end
  88  
  89  
  90  def checkSmartMonTools(path):
  91          """Check if smartctl is available and can be executed.
  92  
  93          Returns:
  94                  - 0 ok
  95                  - 1 no such file
  96                  - 2 cannot execute file
  97          """
  98  
  99          vprint(3, "Check if %s does exist and can be read" % path)
 100          if not os.access(path, os.F_OK):
 101                  return (1, "UNKNOWN: cannot find %s" % path)
 102          elif not os.access(path, os.X_OK):
 103                  return (2, "UNKNOWN: cannot execute %s" % path)
 104          else:
 105                  return (0, "")
 106          # fi
 107  # end
 108  
 109  
 110  def callSmartMonTools(path, device):
 111          # get health status
 112          cmd = "%s -H %s" % (path, device)
 113          vprint(3, "Get device health status: %s" % cmd)
 114          (child_stdin, child_stdout, child_stderr) = os.popen3(cmd)
 115          line = child_stderr.readline()
 116          if len(line):
 117                  return (3, "UNKNOWN: call exits unexpectedly (%s)" % line, "",
 118                                  "")
 119          healthStatusOutput = ""
 120          for line in child_stdout:
 121                  healthStatusOutput = healthStatusOutput + line
 122          # done
 123  
 124          # get temperature
 125          cmd = "%s -A %s" % (path, device)
 126          vprint(3, "Get device temperature: %s" % cmd)
 127          (child_stdin, child_stdout, child_stderr) = os.popen3(cmd)
 128          line = child_stderr.readline()
 129          if len(line):
 130                  return (3, "UNKNOWN: call exits unexpectedly (%s)" % line, "",
 131                                  "")
 132  
 133          temperatureOutput = ""
 134          for line in child_stdout:
 135                  temperatureOutput = temperatureOutput + line
 136          # done
 137  
 138          return (0 ,"", healthStatusOutput, temperatureOutput)
 139  # end
 140  
 141  
 142  def parseOutput(healthMessage, temperatureMessage):
 143          """Parse smartctl output
 144  
 145          Returns (health status, temperature).
 146          """
 147  
 148          # parse health status
 149          #
 150          # look for line '=== START OF READ SMART DATA SECTION ==='
 151          statusLine = ""
 152          lines = healthMessage.split("\n")
 153          getNext = 0
 154          for line in lines:
 155                  if getNext:
 156                          statusLine = line
 157                          break
 158                  elif line == "=== START OF READ SMART DATA SECTION ===":
 159                          getNext = 1
 160                  # fi
 161          # done
 162          parts = statusLine.split()
 163          healthStatus = parts[-1]
 164          vprint(3, "Health status: %s" % healthStatus)
 165  
 166  
 167          # parse temperature attribute line
 168          temperature = 0
 169          lines = temperatureMessage.split("\n")
 170          for line in lines:
 171                  parts = line.split()
 172                  if len(parts):
 173                          # 194 is the temperature value id
 174                          if parts[0] == "194":
 175                                  temperature = int(parts[9])
 176                                  break
 177                          # fi
 178                  # fi
 179          # done
 180          vprint(3, "Temperature: %d" %temperature)
 181  
 182          return (healthStatus, temperature)
 183  # end
 184  
 185  
 186  def createReturnInfo(healthStatus, temperature, warningThreshold,
 187                  criticalThreshold):
 188          """Create return information according to given thresholds."""
 189  
 190          # this is absolutely critical!
 191          if healthStatus != "PASSED":
 192                  return (2, "CRITICAL: device does not pass health status")
 193          # fi
 194  
 195          if temperature > criticalThreshold:
 196                  return (2, "CRITICAL: device temperature (%d) exceeds critical temperature threshold (%s)" % (temperature, criticalThreshold))
 197          elif temperature > warningThreshold:
 198                  return (1, "WARNING: device temperature (%d) exceeds warning temperature threshold (%s)" % (temperature, warningThreshold))
 199          else:
 200                  return (0, "OK: device is functional and stable (temperature: %d)" % temperature)
 201          # fi
 202  # end
 203  
 204  
 205  def exitWithMessage(value, message):
 206          """Exit with given value and status message."""
 207  
 208          print message
 209          sys.exit(value)
 210  # end
 211  
 212  
 213  def vprint(level, message):
 214          """Verbosity print.
 215  
 216          Decide according to the given verbosity level if the message will be
 217          printed to stdout.
 218          """
 219  
 220          if level <= verbosity:
 221                  print message
 222          # fi
 223  # end
 224  
 225  
 226  if __name__ == "__main__":
 227          (options, args) = parseCmdLine(sys.argv)
 228          verbosity = options.verbosity
 229  
 230          vprint(2, "Get device name")
 231          device = options.device
 232          vprint(1, "Device: %s" % device)
 233  
 234          # check if we can access 'path'
 235          vprint(2, "Check device")
 236          (value, message) = checkDevice(device)
 237          if value != 0:
 238                  exitWithMessage(3, message)
 239          # fi
 240  
 241          # check if we have smartctl available
 242          (value, message) = checkSmartMonTools(_smartctlPath)
 243          if value != 0:
 244                  exitWithMessage(3, message)
 245          # fi
 246          vprint(1, "Path to smartctl: %s" % _smartctlPath)
 247  
 248          # call smartctl and parse output
 249          vprint(2, "Call smartctl")
 250          (value, message, healthStatusOutput, temperatureOutput) = callSmartMonTools(_smartctlPath, device)
 251          if value != 0:
 252                  exitWithMessage(value, message)
 253          vprint(2, "Parse smartctl output")
 254          (healthStatus, temperature) = parseOutput(healthStatusOutput, temperatureOutput)
 255          vprint(2, "Generate return information")
 256          (value, message) = createReturnInfo(healthStatus, temperature,
 257                          options.warningThreshold, options.criticalThreshold)
 258  
 259          # exit program
 260          exitWithMessage(value, message)
 261  
 262  # fi


Generated: Tue Mar 17 22:47:18 2015 Cross-referenced by PHPXref 0.7.1