class ServerMgrIPMIMonitoring(ServerMgrMonBasePlugin): def __init__(self, val, frequency, collectors_ip=None): ''' Constructor ''' ServerMgrMonBasePlugin.__init__(self) self.base_obj = ServerMgrMonBasePlugin() self.val = val self.freq = float(frequency) self._serverDb = None self._collectors_ip = collectors_ip # call_send function is the sending function of the sandesh object (send_inst) def call_send(self, send_inst): self.base_obj.log("info", "Sending UVE Info over Sandesh") send_inst.send() # send_ipmi_stats function packages and sends the IPMI info gathered from server polling # to the analytics node def send_ipmi_stats(self, ipmi_data, hostname): sm_ipmi_info = SMIpmiInfo() sm_ipmi_info.name = str(hostname) sm_ipmi_info.sensor_stats = [] sm_ipmi_info.sensor_state = [] for ipmidata in ipmi_data: ipmi_stats = IpmiSensor() ipmi_stats.sensor = ipmidata.sensor ipmi_stats.reading = ipmidata.reading ipmi_stats.status = ipmidata.status ipmi_stats.unit = ipmidata.unit ipmi_stats.sensor_type = ipmidata.sensor_type sm_ipmi_info.sensor_stats.append(ipmi_stats) sm_ipmi_info.sensor_state.append(ipmi_stats) ipmi_stats_trace = SMIpmiInfoTrace(data=sm_ipmi_info) self.call_send(ipmi_stats_trace) # sandesh_init function opens a sandesh connection to the analytics node's ip # (this is recevied from Server Mgr's config or cluster config). The function is called only once. # For this node, a list of collector ips is passed to the sandesh init_generator. def sandesh_init(self, collectors_ip_list=None): try: self.base_obj.log("info", "Initializing sandesh") # storage node module initialization part module = Module.IPMI_STATS_MGR module_name = ModuleNames[module] node_type = Module2NodeType[module] node_type_name = NodeTypeNames[node_type] instance_id = INSTANCE_ID_DEFAULT if collectors_ip_list: self.base_obj.log("info", "Collector IPs from config: "+str(collectors_ip_list)) collectors_ip_list = eval(collectors_ip_list) sandesh_global.init_generator( module_name, socket.gethostname(), node_type_name, instance_id, collectors_ip_list, module_name, HttpPortIpmiStatsmgr, ['contrail_sm_monitoring.ipmi']) else: raise ServerMgrException("Error during Sandesh Init: No collector ips or Discovery server/port given") except Exception as e: raise ServerMgrException("Error during Sandesh Init: " + str(e)) def return_collector_ip(self): return self._collectors_ip # The Thread's run function continually checks the list of servers in the Server Mgr DB and polls them. # It then calls other functions to send the information to the correct analytics server. def run(self): print "Starting monitoring thread" self.base_obj.log("info", "Starting monitoring thread") ipmi_data = [] supported_sensors = ['FAN|.*_FAN', '^PWR', '.*TEMP', '.*Temp', '.*_Power'] while True: servers = self._serverDb.get_server( None, detail=True) ipmi_list = list() hostname_list = list() server_ip_list = list() ipmi_username_list = list() ipmi_password_list = list() data = "" sensor_type = None if self._collectors_ip: for server in servers: server = dict(server) if 'ipmi_address' in server: if server['ipmi_address']: ipmi_list.append(server['ipmi_address']) else: continue else: continue if 'id' in server: if server['id']: hostname_list.append(server['id']) else: ipmi_list.pop() continue else: ipmi_list.pop() continue if 'ip_address' in server: if server['ip_address']: server_ip_list.append(server['ip_address']) else: ipmi_list.pop() hostname_list.pop() continue else: ipmi_list.pop() hostname_list.pop() continue if 'ipmi_username' in server and server['ipmi_username']: ipmi_username_list.append(server['ipmi_username']) else: ipmi_username_list.append(self._default_ipmi_username) if 'ipmi_password' in server and server['ipmi_password']: ipmi_password_list.append(server['ipmi_password']) else: ipmi_password_list.append(self._default_ipmi_password) self.base_obj.log("info", "Started IPMI Polling") for ip, hostname, username, password in \ zip(ipmi_list, hostname_list, ipmi_username_list, ipmi_password_list): ipmi_data = [] cmd = 'ipmitool -H %s -U %s -P %s sdr list all' % (ip, username, password) result = super(ServerMgrIPMIMonitoring, self).call_subprocess(cmd) if result is not None: fileoutput = cStringIO.StringIO(result) for line in fileoutput: reading = line.split("|") sensor = reading[0].strip() reading_value = reading[1].strip() status = reading[2].strip() for i in supported_sensors: if re.search(i, sensor) is not None: if 'FAN' in sensor: sensor_type = 'fan' elif 'PWR' in sensor or 'Power' in sensor: sensor_type = 'power' elif 'Temp' in sensor: sensor_type = 'temperature' value = reading_value.split() ipmidata = IpmiData() ipmidata.sensor = sensor ipmidata.status = status if status == "ns": pass elif status == "ok": ipmidata.reading = long(value[0].strip()) ipmidata.unit = value[len(value) - 1].strip() ipmidata.sensor_type = sensor_type ipmi_data.append(ipmidata) else: self.base_obj.log("info", "IPMI Polling failed for " + str(ip)) self.send_ipmi_stats(ipmi_data, hostname=hostname) else: self.base_obj.log("error", "IPMI Polling: No Analytics IP info found") self.base_obj.log("info", "Monitoring thread is sleeping for " + str(self.freq) + " seconds") time.sleep(self.freq) self.base_obj.log("info", "Monitoring thread woke up")