[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 17 22:47:18 2015 | Cross-referenced by PHPXref 0.7.1 |