#!/usr/bin/env python from optparse import OptionParser, Option, IndentedHelpFormatter import socket import sys import os import time import re from cStringIO import StringIO ## CONSTANTS VERSION='0.2' STATUS = { '0':'API_COMMAND_OK_STATUS', '1':'API_INVALID_COMMAND_TYPE', '2':'API_INVALID_COMMAND', '3':'API_INVALID_PARAMETER_COUNT', '4':'API_INVALID_PARAMETER_NAME', '5':'API_INVALID_PARAMETER_VALUE', '6':'API_INSUFFICIENT_MEMORY', '7':'API_SECURITY_VIOLATION', '8':'API_COMMAND_ERROR_STATUS', '9':'API_COMMAND_NOT_YET_SUPPORTED', '10':'API_OUTPUT_LIMIT_REACHED' } ## VARIABLES platform = '' ### # Argument parser ### # Adding required arguments to option parser, wish I could use argparse # but have to be compat with Py 2.3.4 class PosOptionParser(OptionParser): def format_help(self, formatter=None): class Positional(object): def __init__(self, args): self.option_groups = [] self.option_list = args positional = Positional(self.positional) formatter = IndentedHelpFormatter() formatter.store_option_strings(positional) output = ['\n', formatter.format_heading("Required Arguments")] formatter.indent() pos_help = [formatter.format_option(opt) for opt in self.positional] pos_help = [line.replace('--','') for line in pos_help] output += pos_help return OptionParser.format_help(self, formatter) + ''.join(output) def add_positional_argument(self, option): try: args = self.positional except AttributeError: args = [] args.append(option) self.positional = args def set_out(self, out): self.out = out usage = "%prog [options] host test" desc = """This program communicates with DataDirect Networks storage hardware using the documented API to report to Xymon metrics.""" parser = PosOptionParser(usage=usage, version='%prog ' + VERSION, description=desc) parser.add_option('-d', '--debug', action='store_const', dest='debug', const=True, default=False, help='Debug takes input string from stdin and does not send update to Xymon') parser.add_option('-f', '--from', action='store', dest='from_host', help='Hostname to report to Xymon that is sending the status') parser.add_option('--port', default=8008, type='int', help='Port to connect to API, defaults to 8008') parser.add_option('-u', '--username', default='user', help='User to connect as, defaults to "user"') parser.add_option('-p', '--password', default='password', help='Password to connect as, defaults to "password"') parser.add_option('-s', '--xymonserver', default='xymon', help='Xymon server to connect to, defaults to "xymon"') parser.add_option('--xymonport', default='1984', type='int', help='Port of the Xymon server to connect to, defaults to 1984') parser.add_option('--notest', default='', help='Comma separated list of tests that should not be reported to Xymon') parser.add_option('--skipports', default='', help='Comma separated list of SFP ports that should not be reported to Xymon') parser.add_positional_argument(Option('--host', action='store_true', help='Host to connect to DDN API')) parser.add_positional_argument(Option('--test', action='store_true', help='One of (version, data, faults)')) (options, args) = parser.parse_args() if len(args) != 2: parser.error('Incorrect number of arguments') host = args[0] test = args[1] ### # Argument parser ### ### # Private methods ### """ This sends status messages to Xymon. The lifetime parameter, if specified, is reported in minutes unless you add h, d, w to the end of the integer value. The host parameter is taken from global variables at top of code. """ def xymon_message(test, color, message, lifetime = None): if options.from_host == None: from_host = host.replace('.',',') else: from_host = options.from_host.replace('.',',') if lifetime == None: #payload = 'status {1}.{2} {3} {4}'.format(XYMONFROMHOST, test, color, message) #payload = 'status '+from_host+'.'+test+' '+color+' '+message payload = 'status %s.%s %s %s\nTest originating from %s\n\n%s' % (from_host, test, color, time.strftime("%a %b %d %H:%M:%S %Y"), socket.gethostname(), message) else: #payload = 'status+{0} {1}.{2} {3} {4}'.format(lifetime, XYMONFROMHOST, test, color, message) #payload = 'status+'+lifetime+' '+from_host+'.'+test+' '+color+' '+message payload = 'status+%s %s.%s %s %s\nTest originating from %s\n\n%s' % (lifetime, from_host, test, color, time.strftime("%a %b %d %H:%M:%S %Y"), socket.gethostname(), message) if options.debug: print "Not sending to Xymon\nFrom host:%s\nXymon server:%s\nXymon port:%s\nPayload:\n%s" % \ (from_host, options.xymonserver, options.xymonport, repr(payload)) else: try: s = socket.socket() s.settimeout(5) s.connect((options.xymonserver,int(options.xymonport))) s.send(payload) except socket.timeout: print 'Socket timeout error' sys.exit(1) except socket.error, (value,message): if s: s.close() print "Could not open socket to Xymon: " + message sys.exit(1) s.close """ This function is to send the error messsage to Xymon mainly to be used in catching exceptions """ def xymon_error(message): xymon_message('ddnfaults-basic','red', '%s - red - Check unable to complete!\nTest originating from %s\n%s' % \ (time.asctime(time.localtime(time.time())), socket.gethostname(), message)) def get_data(code, params = '0@'): try: s = socket.socket() s.settimeout(5) s.connect((host, options.port)) s.send('%s@%s@%s@0@%s$' % (str(code), options.username, options.password, params)) data_parts=[] while True: data_part = s.recv(2048) if not data_part: break data_parts.append(data_part) data=''.join(data_parts) except socket.timeout: print 'Socket timeout error' xymon_error('Socket timeout error') sys.exit(1) except socket.error, (value,message): if s: s.close() print 'Could not open socket to DDN API: %s' % message xymon_error('Could not open socket to DDN API: %s' % message) sys.exit(1) s.close() return data def process_data(code, params = None, debug=None): if debug == None: if params == None: data_string = get_data(code) else: data_string = get_data(code, params) else: data_string = debug #SANITY: get status first and make sure it is 0 rStatus = re.search(r'^([0-9]{1,4})@', data_string) status = rStatus.group(1) if status != '0': print '!! API %s returned non-zero status: %s (%s). This is a fatal error. :(' % (str(code), STATUS[status], status) return None # get status, count, and data off data string regex = re.search(r'^([0-9]{1,4})@([0-9]{1,4})@(.*)@\$', data_string) gStatus = regex.group(1) gCount = int(regex.group(2)) gData = regex.group(3).split('@') dData = [] for i in range(0,len(gData),2): dData.append((gData[i],gData[i+1])) data = {'status': gStatus, 'count': gCount, 'response': dData} if options.debug: print 'code: %s' % code print repr(data) return dData, gStatus, gCount # get list position of starting point # BUG: Assumes that it WILL find item.. def get_list_pos(data, item): i = 0 for k,v in data: if k == item: break i = i+1 return i """ Given a key, loop through data structure and find value Arugments: data : List of items(tuples) key : String to search for Returns value of key or None """ def dget_value(data, key): for k,v in data: if k == key: return v return None """ Group consecutive items by set number, i.e. 4 groups of 3 items each with an item being a key, value pair of data from the API Arguments: data : List of items(tuples) start_after : What item to start AFTER num_in_group : Number of items in a single group num_groups : Number of groups, if not specified defaults to the value of the start_after key Returns a two dimensional array of [group] by [item in group] """ def dgroup_sets(data, start_after, num_in_group, num_groups = None): if num_groups == None: num_groups = dget_value(data,start_after) if start_after == None: start_i = -1 else: start_i = get_list_pos(data, start_after) groups = [] # start at the next item # stop at start(ofset) + (number of groups * number of items in a group) # step is number of items in a group for group_start in range(start_i+1,start_i+1+(int(num_groups)*int(num_in_group)),num_in_group): group = [] for gitem in range(group_start,group_start+num_in_group): group.append(data[gitem]) groups.append(group) return groups """ Group by key. Good when dealing with a variable number of items in a group, i.e. group all device_category items for a single device together. Arguments: data : List of items(tuples) key : String to group by Returns a two dimensional array of [group] by [item in group] """ def dgroup_by_key(data, key): groups = [] group = [] flag = False for k,v in data: if k == key: if flag == False: flag = True else: groups.append(group) group = [] if flag == True: group.append((k,v)) if group != []: groups.append(group) return groups """ Here we are manipulating the message struct that holds variables for what to send to Xymon in a message. Print into the message string the key, value item pair and set the color variable for the message Arguments: data : List of items(tuples) message_struct : dict holding message and color information for xymon message start_item : key of item to report num_to_print : number of items to consecutively print, defaults to 1 color : color to change to, defaults to red """ def mprint_items(data, message_struct, start_item, num_to_print = 1, color = 'red', extra = ''): if start_item not in options.notest.split(','): start_i = get_list_pos(data, start_item) for i in range(start_i,start_i+num_to_print): print >>message_struct['message'], '%s%s = %s' % (extra, data[i][0], data[i][1]) message_struct['color'] = color return None def mprint_raw(message_struct, text): print >>message_struct['message'], text return None ### # Private methods ### ### # Main ### if options.debug: print "Debugging!" #for line in sys.stdin: #data = process_data(0000, debug=line) #xymon_message('ddn-version',COLOR,time.asctime(time.localtime(time.time()))+' - '+COLOR+' - '+message.getvalue(),'12h') #print dget_value(data,'disk_failures_count') #print dgroup_sets(data['response'],'disk_failures_count',1) #print dgroup_sets(data['response'],'num_temp_sensors',2) #print dgroup_by_key(data['response'], 'device_category') if test == 'faults': ##1600 #basic_data, basic_status, basic_count = process_data(1600, debug='0@11@hstd1_online_failure@TRUE@hstd1_online_status@Failed@hstd2_online_failure@FALSE@system_platform@S2A 9900@ping_fault@FALSE@avr_temp_C_failures_count@0@avr_temp_W_failures_count@0@avr_pwr_sup_failures_count@0@avr_fan_ctrl_failures_count@0@system_fully_booted@TRUE@disk_failures_count@1@failed_disk_item@Disk 11S Failed.@$') basic_data, basic_status, basic_count = process_data(1600) basic_message = {'message': StringIO(), 'color': 'green'} platform = dget_value(basic_data, 'system_platform') if dget_value(basic_data, 'hstd1_online_failure') == 'TRUE': mprint_items(basic_data, basic_message, 'hstd1_online_status') if dget_value(basic_data, 'hstd2_online_failure') == 'TRUE': mprint_items(basic_data, basic_message, 'hstd2_online_status') if dget_value(basic_data, 'ping_fault') == 'TRUE': mprint_items(basic_data, basic_message, 'ping_fault_tag') else: if dget_value(basic_data, 'avr_temp_C_failures_count') != '0': mprint_items(basic_data, basic_message, 'failed_avr_temp_C_item') if dget_value(basic_data, 'avr_temp_W_failures_count') != '0': mprint_items(basic_data, basic_message, 'failed_avr_temp_W_item') if dget_value(basic_data, 'avr_pwr_sup_failures_count') != '0': mprint_items(basic_data, basic_message, 'failed_avr_pwr_sup_item') if dget_value(basic_data, 'avr_fan_ctrl_failures_count') != '0': mprint_items(basic_data, basic_message, 'failed_avr_fan_ctrl_item') if dget_value(basic_data, 'system_fully_booted') == 'TRUE': if dget_value(basic_data, 'disk_failures_count') != '0': mprint_items(basic_data, basic_message, 'failed_disk_item', num_to_print=int(dget_value(basic_data, 'disk_failures_count'))) #disk_data, disk_status, disk_count = process_data(1609, debug='0@9@disk_issue_count@1@disk@11S@health@Failed@activity@Normal@action_disk@N/A@percent@N/A@paused@NO@queued@NO@status@Failed.@$') #disk_issues = dgroup_sets(disk_data, 'disk_issue_count', 8) #for issue in disk_issues: # item_list = [] # for item in issue: # item_list.append(': %s = %s :'% (item[0], item[1])) # mprint_raw(basic_message, ''.join(item_list)) #print repr(basic_message['message'].getvalue()), basic_message['color'] xymon_message('ddnfaults-basic', basic_message['color'], basic_message['message'].getvalue()) ##1602 #ses_data, ses_status, ses_count = process_data(1602,'1@list_control@RESTART@', debug='0@71@have_faults_to_report@TRUE@MAX_SES_DEVICE_TYPES@31@total_faults@1@total_faults_this_message@1@device_category@UNSPECIFIED@fault_count@0@device_category@DEVICE@fault_count@1@status_level@CRITICAL@device_name@EncID:50001FF126110000: Device 52 (Drive 11S) : @device_ID@52@AL_PA@0@device_category@POWER_SUPPLY@fault_count@0@device_category@COOLING_ELEMENT@fault_count@0@device_category@TEMPERATURE_SENSOR@fault_count@0@device_category@DOOR_LOCK@fault_count@0@device_category@AUDIBLE_ALARM@fault_count@0@device_category@ENCLOSURE_SERVICES_ELECTRONICS@fault_count@0@device_category@SCC_ENCLOSURE_ELECTRONICS@fault_count@0@device_category@NONVOLATILE_CACHE@fault_count@0@device_category@UNINTERRUPTIBLE_POWER_SUPPLY@fault_count@0@device_category@DISPLAY@fault_count@0@device_category@KEY_PAD_ENTRY_DEVICE@fault_count@0@device_category@SCSI_PORT_TRANCEIVER@fault_count@0@device_category@LANGUAGE@fault_count@0@device_category@COMMUNICATIONS_PORT@fault_count@0@device_category@VOLTAGE_SENSOR@fault_count@0@device_category@CURRENT_SENSOR@fault_count@0@device_category@SCSI_TARGET_PORT@fault_count@0@device_category@SCSI_INITIATOR_PORT@fault_count@0@device_category@SIMPLE_SUB_ENCLOSURE@fault_count@0@device_category@SES_ENHANCED_SWITCHED_HUB@fault_count@0@device_category@SES_TARGET_SES_DEVICE@fault_count@0@device_category@SES_ATA_CONTROLLER@fault_count@0@device_category@SES_LED_CLUSTER_NEWISYS@fault_count@0@device_category@UNSPECIFIED@fault_count@0@device_category@UNSPECIFIED@fault_count@0@device_category@UNSPECIFIED@fault_count@0@device_category@UNSPECIFIED@fault_count@0@device_category@UNSPECIFIED@fault_count@0@device_category@UNSPECIFIED@fault_count@0@total_remaining_faults@0@$') ses_data, ses_status, ses_count = process_data(1602,'1@list_control@RESTART@') ses_message = {'message': StringIO(), 'color': 'green'} if dget_value(ses_data, 'have_faults_to_report') == 'TRUE': ses_devices = dgroup_by_key(ses_data, 'device_category') for device_category in ses_devices: if dget_value(device_category, 'fault_count') != '0': faults = dgroup_by_key(device_category, 'status_level') for fault in faults: mprint_items(fault, ses_message, 'status_level', num_to_print=len(fault)) else: if type(re.match(r'.*(No faults were detected).*', dget_value(ses_data, 'explanation'))) != 'NoneType': mprint_items(ses_data, ses_message, 'explanation', color='green') else: mprint_items(ses_data, ses_message, 'explanation', color='clear') #print repr(ses_message['message'].getvalue()), ses_message['color'] xymon_message('ddnfaults-ses', ses_message['color'], ses_message['message'].getvalue()) ##1603 #busparity_data, busparity_status, busparity_count = process_data(1603, '1@cmd_version@1@', debug='0@72@internal_host_err@0@uncorrected_host_ecc@0@host_hard@0@host_soft@0@disk_hard@0@disk_soft@0@control_bus@0@ecc_recovered@0@ecc_unrecovered@0@host_hard@0@host_soft@0@disk_hard@0@disk_soft@0@control_bus@0@ecc_recovered@0@ecc_unrecovered@0@host_hard@0@host_soft@0@disk_hard@0@disk_soft@0@control_bus@0@ecc_recovered@2@ecc_unrecovered@1@host_hard@0@host_soft@0@disk_hard@0@disk_soft@0@control_bus@0@ecc_recovered@0@ecc_unrecovered@0@host_hard@0@host_soft@0@disk_hard@1@disk_soft@0@control_bus@0@ecc_recovered@0@ecc_unrecovered@0@host_hard@0@host_soft@0@disk_hard@0@disk_soft@0@control_bus@0@ecc_recovered@0@ecc_unrecovered@0@host_hard@0@host_soft@0@disk_hard@0@disk_soft@0@control_bus@0@ecc_recovered@0@ecc_unrecovered@0@host_hard@0@host_soft@0@disk_hard@0@disk_soft@0@control_bus@0@ecc_recovered@0@ecc_unrecovered@0@host_hard@0@host_soft@0@disk_hard@0@disk_soft@0@control_bus@0@ecc_recovered@0@ecc_unrecovered@0@host_hard@0@host_soft@0@disk_hard@0@disk_soft@0@control_bus@0@ecc_recovered@0@ecc_unrecovered@0@$') busparity_data, busparity_status, busparity_count = process_data(1603, '1@cmd_version@1@') busparity_message = {'message': StringIO(), 'color': 'green'} disk_channels = dgroup_by_key(busparity_data, 'host_hard') channels = ['A','B','C','D','E','F','G','H','P','S'] for channel,values in zip(channels,disk_channels): for data_point in values: if data_point[1] != '0': mprint_items(values, busparity_message, data_point[0], extra = 'Channel %s: ' % channel) #print repr(busparity_message['message'].getvalue()), busparity_message['color'] xymon_message('ddnfaults-busparity', busparity_message['color'], busparity_message['message'].getvalue()) ##1604 if platform == 'S2A 8000' or platform == 'S2A 8500': #memory8000_data, memory8000_status, memory8000_count = process_data(1604, debug='0@14@total_correctable_ECC@1@total_correctable_ECC@0@last_ECC_err_address@0@last_ECC_err_value@0@last_ECC_err_actual@0@last_ECC_err_calc@0@out_of_range_err@0@address_parity_err@0@unknown_int@0@PCI_master_read_err@0@PCI_master_write_err@17@PCI_slave_read_err@0@PCI_slave_write_err@0@PCI_slave_write_err@0@$') memory8000_data, memory8000_status, memory8000_count = process_data(1604) memory8000_message = {'message': StringIO(), 'color': 'green'} for err_value in memory8000_data: if err_value[1] != '0': mprint_items(memory8000_data, memory8000_message, err_value[0]) #print repr(memory8000_message['message'].getvalue()), memory8000_message['color'] xymon_message('ddnfaults-memory8000', memory8000_message['color'], memory8000_message['message'].getvalue()) ##1605 if platform != 'S2A 3000' and platform != 'S2A 6200' and platform != 'S2A 8000' and platform != 'S2A 8500': #memory9900_data, memory9900_status, memory9900_count = process_data(1605, debug='0@73@num_processors@8@processor_name@Main Processor @single_bit_ECC_err@0@single_bit_ECC_read_err@0@single_bit_ECC_write_err@0@multi_bit_ECC_err@0@multi_bit_ECC_read_err@0@multi_bit_ECC_write_err@0@N_bit_ECC_err@0@num_scrubbed_locations@0@processor_name@Host Processor 12@single_bit_ECC_err@0@single_bit_ECC_read_err@0@single_bit_ECC_write_err@0@multi_bit_ECC_err@0@multi_bit_ECC_read_err@0@multi_bit_ECC_write_err@0@N_bit_ECC_err@0@num_scrubbed_locations@0@processor_name@Host Processor 34@single_bit_ECC_err@0@single_bit_ECC_read_err@1@single_bit_ECC_write_err@0@multi_bit_ECC_err@0@multi_bit_ECC_read_err@0@multi_bit_ECC_write_err@0@N_bit_ECC_err@0@num_scrubbed_locations@0@processor_name@Disk Processor AB@single_bit_ECC_err@0@single_bit_ECC_read_err@0@single_bit_ECC_write_err@0@multi_bit_ECC_err@0@multi_bit_ECC_read_err@0@multi_bit_ECC_write_err@0@N_bit_ECC_err@0@num_scrubbed_locations@0@processor_name@Disk Processor CD@single_bit_ECC_err@0@single_bit_ECC_read_err@0@single_bit_ECC_write_err@0@multi_bit_ECC_err@0@multi_bit_ECC_read_err@0@multi_bit_ECC_write_err@0@N_bit_ECC_err@0@num_scrubbed_locations@0@processor_name@Disk Processor EF@single_bit_ECC_err@0@single_bit_ECC_read_err@0@single_bit_ECC_write_err@0@multi_bit_ECC_err@0@multi_bit_ECC_read_err@0@multi_bit_ECC_write_err@0@N_bit_ECC_err@0@num_scrubbed_locations@0@processor_name@Disk Processor GH@single_bit_ECC_err@0@single_bit_ECC_read_err@0@single_bit_ECC_write_err@0@multi_bit_ECC_err@0@multi_bit_ECC_read_err@0@multi_bit_ECC_write_err@0@N_bit_ECC_err@0@num_scrubbed_locations@0@processor_name@Disk Processor PS@single_bit_ECC_err@0@single_bit_ECC_read_err@1@single_bit_ECC_write_err@15@multi_bit_ECC_err@0@multi_bit_ECC_read_err@0@multi_bit_ECC_write_err@0@N_bit_ECC_err@0@num_scrubbed_locations@0@$') memory9900_data, memory9900_status, memory9900_count = process_data(1605) memory9900_message = {'message': StringIO(), 'color': 'green'} processors = dgroup_by_key(memory9900_data, 'processor_name') for processor in processors: for err_value in processor: if err_value[0] != 'processor_name' and err_value[1] != '0': mprint_items(processor, memory9900_message, err_value[0], extra='%s : ' %dget_value(processor, 'processor_name')) #print repr(memory9900_message['message'].getvalue()), memory9900_message['color'] xymon_message('ddnfaults-memory9900', memory9900_message['color'], memory9900_message['message'].getvalue()) ##1606 #Note: I created the debug data, may not be acurate.. based off of API docs #arrayparity_data, arrayparity_status, arrayparity_count = process_data(1606, '1@cmd_version@1@', debug='0@6@num_entries@1@lun@0@tier@1@hard_errors@0@soft_errors@0@recovered_errors@1@$') arrayparity_data, arrayparity_status, arrayparity_count = process_data(1606, '1@cmd_version@1@') arrayparity_message = {'message': StringIO(), 'color': 'green'} if dget_value(arrayparity_data, 'num_entries') != '0': entries = dgroup_by_key(arrayparity_data, 'lun') for entry in entries: mprint_items(entry, arrayparity_message, 'lun', num_to_print=len(entry)) #print repr(arrayparity_message['message'].getvalue()), arrayparity_message['color'] xymon_message('ddnfaults-arrayparity', arrayparity_message['color'], arrayparity_message['message'].getvalue()) ##1607 #sfp_data, sfp_status, sfp_count = process_data(1607, debug='0@42@disk_channel@A@disk_laser@SFP transmitter fault detected@disk_signal@SFP signal OK@disk_channel@B@disk_laser@SFP transmitter OK@disk_signal@SFP signal OK@disk_channel@C@disk_laser@SFP transmitter OK@disk_signal@SFP signal OK@disk_channel@D@disk_laser@SFP transmitter OK@disk_signal@SFP signal OK@disk_channel@E@disk_laser@SFP transmitter OK@disk_signal@SFP signal OK@disk_channel@F@disk_laser@SFP transmitter OK@disk_signal@SFP signal OK@disk_channel@G@disk_laser@SFP transmitter OK@disk_signal@SFP signal OK@disk_channel@H@disk_laser@SFP transmitter OK@disk_signal@SFP signal OK@disk_channel@P@disk_laser@SFP transmitter OK@disk_signal@SFP signal OK@disk_channel@S@disk_laser@SFP transmitter OK@disk_signal@SFP signal OK@host_port@1@host_laser@SFP transmitter OK@host_signal@SFP signal OK@host_port@2@host_laser@SFP transmitter OK@host_signal@SFP signal OK@host_port@3@host_laser@SFP transmitter OK@host_signal@SFP signal OK@host_port@4@host_laser@SFP transmitter OK@host_signal@SFP signal OK@$') sfp_data, sfp_status, sfp_count = process_data(1607) sfp_message = {'message': StringIO(), 'color': 'green'} portset = dgroup_sets(sfp_data, None, 3, sfp_count/3) for port in portset: if dget_value(port, 'host_port') in options.skipports.split(','): continue if dget_value(port, 'disk_laser') == 'SFP transmitter fault detected': mprint_items(port, sfp_message, 'disk_laser', extra='Disk channel %s : ' % dget_value(port, 'disk_channel')) if dget_value(port, 'disk_signal') == 'SFP loss of signal': mprint_items(port, sfp_message, 'disk_signal', extra='Disk channel %s : ' % dget_value(port, 'disk_channel')) if dget_value(port, 'host_laser') == 'SFP transmitter fault detected': mprint_items(port, sfp_message, 'host_laser', extra='Host port %s : ' % dget_value(port, 'host_port')) if dget_value(port, 'host_signal') == 'SFP loss of signal': mprint_items(port, sfp_message, 'host_signal', extra='Host port %s : ' % dget_value(port, 'host_port')) #print repr(sfp_message['message'].getvalue()), sfp_message['color'] xymon_message('ddnfaults-sfp', sfp_message['color'], sfp_message['message'].getvalue()) ##3402 #temp_data, temp_status, temp_count = process_data(3402, debug='0@33@num_temp_sensors@16@sensor_location@Right Rear Temperature@current_temp@45@sensor_location@Left Rear Temperature@current_temp@38@sensor_location@Fan Control Temperature@current_temp@39@sensor_location@Main CPU Temperature@current_temp@77@sensor_location@Host 12 CPU Temperature@current_temp@61@sensor_location@Host 34 CPU Temperature@current_temp@57@sensor_location@Host 12 IF Temperature@current_temp@N/A@sensor_location@Host 34 IF Temperature@current_temp@N/A@sensor_location@DP FPGA Temperature@current_temp@60@sensor_location@Host 12 Cache Temperature@current_temp@61@sensor_location@Host 34 Cache Temperature@current_temp@56@sensor_location@Disk AB CPU Temperature@current_temp@56@sensor_location@Disk CD CPU Temperature@current_temp@54@sensor_location@Disk EF CPU Temperature@current_temp@54@sensor_location@Disk GH CPU Temperature@current_temp@52@sensor_location@Disk PS CPU Temperature@current_temp@55@$') #temp_data, temp_status, temp_count = process_data(3402, debug='0@9@num_temp_sensors@4@sensor_location@Right Rear Temperature@current_temp@25@sensor_location@Left Rear Temperature@current_temp@23@sensor_location@Host Board Temperature@current_temp@27@sensor_location@Fan Control Temperature@current_temp@21@$') temp_data, temp_status, temp_count = process_data(3402) temp_message = {'message': StringIO(), 'color': 'green'} temperatures = dgroup_sets(temp_data, 'num_temp_sensors', 2) for sensor in temperatures: try: mprint_raw(temp_message, '%s : %s' % (dget_value(sensor, 'sensor_location'), int(dget_value(sensor, 'current_temp'))*1.8+32)) except ValueError: mprint_raw(temp_message, '%s : %s' % (dget_value(sensor, 'sensor_location'), dget_value(sensor, 'current_temp'))) #print repr(temp_message['message'].getvalue()), temp_message['color'] xymon_message('ddnfaults-temp', temp_message['color'], temp_message['message'].getvalue())