#!/usr/bin/python # # cmsh commands to use this script # # # # note this did not work, we were trying to add new metrics to the PowerDistributionUnit class of entities # # Bright doesnt seem to treat PDU's like servers where you can add custom metrics, instead the solution is to standalone entities # # 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 # # create a multiplexer config to run the script only against 'entities' of type PowerDistributionUnit # executionmultiplexers # add type PowerDistributionUnit # commit # remove this configuration # monitoring setup # use ipower-pdu # executionmultiplexers # list # show PowerDistributionUnit # remove PowerDistributionUnit # exit # nodeexecutionfilters # list # show "Active head node" # remove "Active head node" # exit # # we back at 'monitoring setup' # list # show ipower-pdu # remove ipower-pdu 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, 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 session = Session(hostname=entity, 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(): # KWh removed, believe there is a snmp setting to adjust what you pay per hour that must be set for this to be meaningful, hopefully can be calculated in the bright gui? # meter_values = {'VRMS': {'unit': 'V', 'class': "ipower-pdu", 'value': 0, 'divide': 10}, 'IRMS': {'unit': 'A', 'class': "ipower-pdu", 'value': 0, 'divide': 100}, 'KWH': {'unit': 'KWH', 'class': "ipower-pdu", 'value': 0, 'divide': 1000000}, '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}} 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}} # shell invoked by bright with one argument --initialize when first classifying the json metric fields # subsequent invocations usually pass no arguments and the script uses a shell env variable (entity) to determine the script target host # the bright cli console indicated additional arguments can be passed # uncomment to test on command line - this relates to the execution multiplexers os.environ["CMD_HOSTNAME"] = "192.168.10.161" #os.environ["CMD_HOSTNAME"] = "10.0.255.101" #os.environ["CMD_HOSTNAME"] = "10.0.255.102" #os.environ["CMD_HOSTNAME"] = "10.0.255.103" #os.environ["CMD_HOSTNAME"] = "10.0.255.104" try: entity = os.environ["CMD_HOSTNAME"] except: sys.stderr.write('Target device not specified in environment\n') return if len(sys.argv) > 1 and sys.argv[1] == "--initialize": data = initialize(entity, meter_values) else: data = sample(entity, meter_values) print json.dumps(data, indent=4) if __name__ == '__main__': main()