#!/usr/bin/env python #Copyright (c) 2014, Logilab, All rights reserved. #This library is free software; you can redistribute it and/or #modify it under the terms of the GNU Lesser General Public #License as published by the Free Software Foundation; either #version 3.0 of the License, or (at your option) any later version. #This library is distributed in the hope that it will be useful, #but WITHOUT ANY WARRANTY; without even the implied warranty of #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #Lesser General Public License for more details. # #You should have received a copy of the GNU Lesser General Public #License along with this library. import cPickle from optparse import OptionParser import os.path as osp import subprocess as sp import time __version__ = "0.0.1" #in degrees/min WARN_THRESHOLD = 2.0 CRIT_THRESHOLD = 3.0 # in minutes MAX_DELAY = 20 MIN_DELAY = 4 FILENAME = '/tmp/dell_temperatures.pickle' STATUS = { 0: 'OK', 1: 'WARNING', 2: 'CRITICAL', 3: 'UNKNOWN' } class Statistics(object): def __init__(self, command, warn, crit, filename): self.command = command.split() self.data = sp.Popen(self.command, stdout=sp.PIPE).stdout.readlines() self.ordered_data = {} self.warn = warn self.crit = crit self.filename = filename # Make sure omreport returns at least one sensor block. self.extract_data() if osp.isfile(self.filename): with open(self.filename) as od_file: self.load_data(od_file) self.clean_data() with open(self.filename, 'w') as od_file: self.dump_data(od_file) self.get_difference() def extract_data(self): """ run the program and""" index = -1 date = int(time.time()) for item in self.data: if item.startswith("Index"): index = int(item.split(':')[-1]) elif item.startswith("Probe Name"): name = item.split(':')[-1].strip() elif item.startswith("Reading"): value = float(item.split(':')[-1].rstrip(' C\n').strip()) if date not in self.ordered_data: self.ordered_data[date] = {} self.ordered_data[date][index] = { 'name' : name, 'value' : value } if index < 0: raise ValueError("No output from omreport. Is OMSA running?") def load_data(self, filedesc): try: self.ordered_data.update(cPickle.load(filedesc)) except EOFError: pass #wrongly formatted file, can happen def dump_data(self, filedesc): cPickle.dump(self.ordered_data, filedesc) def print_omreport_results(self): """Prints names and values for each sensor.""" print self.ordered_data def clean_data(self): """Remove old data from records""" for date in self.ordered_data.keys(): if MAX_DELAY > 0 and time.time() - date > MAX_DELAY * 60: del self.ordered_data[date] def get_difference(self): """ check the temperature difference beetwen previous records and current records for all available probes """ comparee = 0 dates = sorted(self.ordered_data.keys(), reverse=True) while dates[0] - dates[comparee] < MIN_DELAY * 60: comparee += 1 if len(dates) <= comparee: raise IndexError('Not enough values in data') new_data = self.ordered_data[dates[0]] old_data = self.ordered_data[dates[comparee]] assert len(old_data) == len(new_data) ret_code = 0 output = [] for key in new_data: total_delta = 60. * (new_data[key]['value'] - old_data[key]['value']) total_delta /= dates[0] - dates[comparee] rplcts = (new_data[key]['name'], total_delta) output.append("Temperature varition for %s is %f C/min" % rplcts) if ret_code < 2 and total_delta > self.crit: ret_code = 2 if ret_code < 1 and total_delta > self.warn: ret_code = 1 print "%s: %s" % (STATUS[ret_code], '|'.join(output)) exit(ret_code) if __name__ == '__main__': omreport = '/opt/dell/srvadmin/bin/omreport chassis temps' parser = OptionParser() parser.add_option("-w", "--warn", dest="warn", default=WARN_THRESHOLD, type=float, help="warning threshold (default %i)" % WARN_THRESHOLD) parser.add_option("-c", "--crit", dest="crit", default=CRIT_THRESHOLD, type=float, help="critical threshold (default %i)" % CRIT_THRESHOLD) parser.add_option("-f", "--filename", dest="filename", default=FILENAME, type=str, help="output and input filename (default %s)" % FILENAME) (options, args) = parser.parse_args() try: Statistics(omreport, warn=options.warn, crit=options.crit, filename=options.filename) except IndexError as e: print "%s: %s" % (STATUS[1], str(e)) exit(1) except ValueError as e: print "%s: %s" % (STATUS[2], str(e)) exit(2) except Exception as e: print "%s: %s" % (STATUS[3], str(e)) exit(3)