#!/usr/bin/python # Bright would not allow us to add additional metrics to existing pdu entities (as you could with regular servers) so we create new standalone entities that we add via cmsh # the /etc/hosts has the ip of pdu001 (we could use the device ip), our entity is ipower-pdu01, the targets dict provides the mapping so easysnmp knows what to target # # cmsh commands to add this monitoring script # # # Add standalone targets # monitoring standalone # add ipower-pdu1 # set type ipower-pdu # commit # exit # add ipower-pdu2 # set type ipower-pdu # commit # exit # add ipower-pdu3 # set type ipower-pdu # commit # exit # add ipower-pdu4 # set type ipower-pdu # commit # exit # # # Create the collection, assign the monitoring script # monitoring setup # add collection ipower-pdu # set script /cm/local/apps/cmd/scripts/powerscripts/ipower-pdu.py # set format JSON # set interval 1m # commit # # # Create an execution filter to run the collection only on the active head node # nodeexecutionfilters # active # commit # exit # # # Check monitoring is being collected # monitoring standalone # list # # Name (key) Type # ------------------------ ------------------------ # ipower-pdu1 ipower-pdu # ipower-pdu2 ipower-pdu # ipower-pdu3 ipower-pdu # ipower-pdu4 ipower-pdu # # use ipower-pdu1 # latestmetricdata # # Measurable Parameter Type Value Age State Info # ------------ ------------ ------------ ---------- ---------- ---------- ---------- # IPK ipower-pdu 25.65 A 7.86s filtered # IRMS ipower-pdu 17.05 A 7.86s filtered # KW ipower-pdu 3.794 KW 7.86s filtered # VPK ipower-pdu 648.4 V 7.86s filtered # VRMS ipower-pdu 901 V 7.86s filtered import os import sys import json from easysnmp import Session def initialize(entity, meter_values): metric = [] for i in meter_values: metric_name = i unit = meter_values[i]['unit'] metric_class = meter_values[i]['class'] entry = {"metric": metric_name, "entity": entity, "unit": unit, "class": metric_class} dict_copy = entry.copy() metric.append(dict_copy) return metric def sample(entity, hostname, meter_values): # this only returns values which are set, snmpwalk will return zero values or no values at all (if powerbanks or phases arent in use the data is discarded and not returned it seems) # to force return of empty fields you may need to use get instead of get_bulk # get_bulk is like snmpwalk, get is equivalent to snmpget # # the endwith filter allows us to itterate over similarly named fields and aggregate them, for example you get multiple current readings for multiple phases that we want to aggregate for the pdu # however this also happens for voltage so you may get 230vX3 if all phases are in use session = Session(hostname=hostname, community='public', version=2, remote_port=161) system_items = session.get_bulk('PDUSNMP::pdu-Meters') for i in system_items: for j in meter_values: if i.oid.endswith(j): #print (i.oid + "." + i.oid_index + " = " + i.snmp_type + ": " + i.value) divide_value = int(meter_values[j]['divide']) meter_values[j]['value'] = float(meter_values[j]['value']) + (float(i.value) / divide_value) metric = [] for i in meter_values: metric_name = i value = meter_values[i]['value'] entry = {"metric": metric_name, "entity": entity, "value": value} dict_copy = entry.copy() metric.append(dict_copy) return metric def main(): # template for metric ititialization, also used for metric collection meter_values = {'VRMS': {'unit': 'V', 'class': "ipower-pdu", 'value': 0, 'divide': 10}, 'IRMS': {'unit': 'A', 'class': "ipower-pdu", 'value': 0, 'divide': 100}, 'KW': {'unit': 'KW', 'class': "ipower-pdu", 'value': 0, 'divide': 1000}, 'IPK': {'unit': 'A', 'class': "ipower-pdu", 'value': 0, 'divide': 100}, 'VPK': {'unit': 'V', 'class': "ipower-pdu", 'value': 0, 'divide': 10}} #targets = {'ocf-pdu1': '192.168.10.161'} # format = 'bright entity' : 'target address/hostname' targets = {'ipower-pdu1': 'pdu001', 'ipower-pdu2': 'pdu002', 'ipower-pdu3': 'pdu003', 'ipower-pdu4': 'pdu004'} data = [] if len(sys.argv) > 1 and sys.argv[1] == "--initialize": for i in targets: entity = i entry = initialize(entity, meter_values) for j in entry: data.append(j) else: for i in targets: entity = i hostname = targets[i] entry = sample(entity, hostname, meter_values) for j in entry: data.append(j) print json.dumps(data, indent=4) if __name__ == '__main__': main()