%PDF- %PDF-
Direktori : /lib64/nagios/plugins/nccustom/ |
Current File : //lib64/nagios/plugins/nccustom/check_smartctl.py |
#!/usr/libexec/platform-python ################################ # Check SMART for drives # # (from cached datafile) # # Created by Bogdan Kukharskiy # # Namecheap # ################################ # This script checks SMART for drives based on cache data gathered with # 'nc-zabbix-check-smart' by Alex Rabchenyuk # or 'nc-smart-data-exporter' by Vladimir Kuprikov # # Returns the nagios native status codes: # 0 = OK # 1 = WARNING # 2 = CRITICAL # 3 = UNKNOWN # # Also provides Nagios PerfData for every checked parameter import os import re import sys import time import json import argparse from os import access, R_OK from os.path import isfile from datetime import datetime if __name__ == "__main__": # parsing arguments parser = argparse.ArgumentParser() parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Extra output") parser.add_argument("-f", "--cachefile", default="", type=str, help="Path to file with cached SMART data") parser.add_argument("-t", "--tmpfilepath", default="/tmp/smartctl/", type=str, help="tmp file path, default: /tmp/smartctl/") parser.add_argument("-c", "--configfile", type=str, default="", help="Config file, full path and name (by default, check_smartctl.conf in script dir)") args = parser.parse_args() # determining config file full path if args.configfile == "": configFileName = os.path.join(os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]))), 'check_smartctl.conf') else: configFileName = args.configfile if not (isfile(configFileName) and access(configFileName, R_OK)): print("Config file doesn't exist or isn't readable: " + configFileName) exit(3) try: if os.path.getsize(configFileName) > 0: configData = json.loads(open(configFileName).read()) if args.verbose: print("Config file contents:") print(json.dumps(configData, indent=4, sort_keys=True)) else: print("Config file is empty") exit(3) except OSError as e: print("Config file does not exist or not accessible: %s" % e) exit(3) except ValueError as e: print("Config file has invalid JSON format: %s" % e) exit(3) cacheFileName = "" if args.cachefile == "": for filename in os.listdir(args.tmpfilepath): if filename.startswith("smart"): cacheFileName = (os.path.join(args.tmpfilepath, filename)) break # we take first file which starts from 'smart', weird but should be ok else: continue else: cacheFileName = args.cachefile if args.verbose: print("Cache file name = " + cacheFileName) if not (isfile(cacheFileName) and access(cacheFileName, R_OK)): print("Cache file doesn't exist or isn't readable: " + cacheFileName) exit(3) try: if args.verbose: print("Information about cache file:") print(" *Created Time : {0}".format( str(datetime.fromtimestamp(os.path.getctime(cacheFileName)).strftime('%Y-%m-%d %H:%M:%S')))) print(" *Modified Time : {0}".format( str(datetime.fromtimestamp(os.path.getmtime(cacheFileName)).strftime('%Y-%m-%d %H:%M:%S')))) print(" *Access Time : {0}".format( str(datetime.fromtimestamp(os.path.getatime(cacheFileName)).strftime('%Y-%m-%d %H:%M:%S')))) print(" *Size : {0}".format(os.path.getsize(cacheFileName))) if os.path.getmtime(cacheFileName) < (time.time() - 7200): print("Cache file is too old") exit(3) if os.path.getsize(cacheFileName) > 0: cacheData = json.loads(open(cacheFileName).read()) else: print("Cache file is empty") exit(3) except OSError as e: print("Cache file does not exist or not accessible: %s" % e) exit(3) except ValueError as e: print("Cache file has invalid JSON format: %s" % e) exit(3) # now will iterate through all drive types flagDriveTypeOnServerFound = False warningArray = [] criticalArray = [] perfDataArray = [] perfData = "" for driveTypeOnServerKey, driveSerialNumberKey in cacheData.items(): for driveTypeInConfigKey, driveTypeInConfigValue in configData.items(): if driveTypeOnServerKey == driveTypeInConfigKey: flagDriveTypeOnServerFound = True # we have found server drive type in config for driveSerialKey, driveSmartParamKey in driveSerialNumberKey.items(): if args.verbose: print("------------") print("Drive serial = {0}".format(driveSerialKey)) for configParamNameKey, configParamNameValue in driveTypeInConfigValue.items(): for driveSmartParamNameKey, driveSmartParamNameValue in driveSmartParamKey.items(): if re.search(configParamNameKey, driveSmartParamNameKey): perfData = "" try: driveSmartParamNameValue=str(driveSmartParamNameValue) # fix for new nc-zabbix-kvmnodes-smart which stores values as ints instead of strings if args.verbose: print(" Parameter name: {0}".format(configParamNameKey)) print(" Critical value = {0}".format(configParamNameValue['Critical'])) print(" Warning value = {0}".format(configParamNameValue['Warning'])) print(" Cached value from SMART = {0}".format(driveSmartParamNameValue)) if len(str(configParamNameValue['Critical'])) < 1 or len(str(configParamNameValue['Warning'])) < 1 or len(driveSmartParamNameValue) < 1: print("Empty value of key for parameter {0} (in config file or in cache file)".format(configParamNameKey)) exit(3) if driveSmartParamNameValue != "-" and int(driveSmartParamNameValue) > configParamNameValue['Critical']: criticalArray.append(driveSerialKey + ":" + driveSmartParamNameKey + "=" + driveSmartParamNameValue + ">" + str(configParamNameValue['Critical'])) elif driveSmartParamNameValue != "-" and int(driveSmartParamNameValue) > configParamNameValue['Warning']: warningArray.append(driveSerialKey + ":" + driveSmartParamNameKey + "=" + driveSmartParamNameValue + ">" + str(configParamNameValue['Warning'])) perfData = driveSerialKey + "_" + driveSmartParamNameKey + "=" + driveSmartParamNameValue + ";" + str(configParamNameValue['Warning']) + ";" + str(configParamNameValue['Critical']) perfDataArray.append(perfData) except KeyError as k: print("{0} key was not found for parameter '{1}' in config file".format(k, configParamNameKey)) exit(3) except (TypeError, ValueError) as u: print("Numbers in cache JSON file are in invalid format: %s" % u) exit(3) break if flagDriveTypeOnServerFound is False: print("Server drive type was not found in config file") exit(3) if len(criticalArray) > 0: print("CRITICAL! " + '; '.join(criticalArray) + " | " + ' '.join(perfDataArray)) exit(2) elif len(warningArray) > 0: print("WARNING! " + '; '.join(warningArray) + " | " + ' '.join(perfDataArray)) exit(1) else: print("SMART parameters for all drives are OK" + " | " + ' '.join(perfDataArray)) exit(0)