diff --git a/src/vpoller/agent.py b/src/vpoller/agent.py index 87574ae..bdf5902 100644 --- a/src/vpoller/agent.py +++ b/src/vpoller/agent.py @@ -273,6 +273,147 @@ def get_vm_property(self, msg): } return result + + def _get_performance_manager(self): + """ + One-time method to set the PerformanceManager attribute + + Useful for setting up the PerformanceManager once and avoid + subsequent calls for acquiring a new PerformanceManager each time + we need to query performance counters. + + """ + if hasattr(self, 'pm'): + return + + self.pm = self.viserver.get_performance_manager() + + def get_vm_counter(self, msg): + """ + Get performance counters of an object of type VirtualMachine and return it. + + Example client message to get a VM performance counter could be: + + { + "method": "vm.counter.get", + "hostname": "vc01-test.example.org", + "name": "vm01.example.org", + "properties": [ + "cpu.system", + "mem.zipped" + ] + } + + Args: + msg (dict): The client message to process + + """ + + # + # TODO: Handle collection objects as part of the returned result + # + + if not self.msg_is_okay(msg, ('method', 'hostname', 'name', 'properties')): + return { "success": -1, "msg": "Incorrect or missing message properties" } + + # + # Performance Counter names we want to retrieve about the VirtualMachine object plus + # any other user-requested properties. + # + # Check the vSphere Web Services SDK API for more information on the properties + # + # https://www.vmware.com/support/developer/vc-sdk/ + # + counter_names = msg['properties'] + + logging.info('[%s] Retrieving %s for Virtual Machine %s', self.hostname, msg['properties'], msg['name']) + + # Locate the VirtualMachine MOR for which we want to get the performance counters + self.update_vm_mors() + mor = self.mors_cache['VirtualMachine']['objects'].get(msg['name']) + + if not mor: + return { 'success': -1, 'msg': 'Unable to find Virtual Machine %s' % msg['name'] } + + self._get_performance_manager() + + try: + result = self.pm.get_entity_statistic(entity=mor, counters=counter_names) + except Exception as e: + logging.warning('Cannot get counters for Virtual Machine %s: %s', msg['name'], e) + return { 'success': -1, 'msg': 'Cannot get counters for Virtual Machine %s: %s' % (msg['name'], e) } + + data = [] + + for eachCounter in result: + data.append( + { 'name': eachCounter.group + '.' + eachCounter.counter, + 'counter': eachCounter.counter, + 'group': eachCounter.group, + 'description': eachCounter.description, + 'unit': eachCounter.unit, + 'group_description': eachCounter.group_description, + 'unit_description': eachCounter.unit_description, + 'value': eachCounter.value + } + ) + + result = { + "success": 0, + "msg": "Successfully retrieved counters", + "result": data, + } + + return result + + def get_vm_counter_all(self, msg): + """ + Get all performance counters of an object of type VirtualMachine and return them. + + Example client message to get all VM performance counters could be: + + { + "method": "vm.counter.all", + "hostname": "vc01-test.example.org", + "name": "vm01.example.org", + } + + Args: + msg (dict): The client message to process + + """ + + # + # TODO: Handle collection objects as part of the returned result + # + + if not self.msg_is_okay(msg, ('method', 'hostname', 'name')): + return { "success": -1, "msg": "Incorrect or missing message properties" } + + logging.info('[%s] Retrieving all performance counters for %s', self.hostname, msg['name']) + + # Locate the VirtualMachine MOR for which we want to get the performance counters + self.update_vm_mors() + mor = self.mors_cache['VirtualMachine']['objects'].get(msg['name']) + + if not mor: + return { 'success': -1, 'msg': 'Unable to find Virtual Machine %s' % msg['name'] } + + self._get_performance_manager() + + try: + data = self.pm.get_entity_counters(entity=mor) + except Exception as e: + logging.warning('Cannot get counters for Virtual Machine %s: %s', msg['name'], e) + return { 'success': -1, 'msg': 'Cannot get counters for Virtual Machine %s: %s' % (msg['name'], e) } + + result = { + "success": 0, + "msg": "Successfully retrieved counters", + "result": data, + } + + return result def get_datacenter_property(self, msg): """ @@ -519,7 +660,6 @@ def discover_virtual_machines(self, msg): The returned data is a JSON object, containing the discovered Virtual Machines. """ - # # TODO: Handle collection objects as part of the returned result # diff --git a/src/vpoller/worker.py b/src/vpoller/worker.py index 93fa236..dbdba4b 100644 --- a/src/vpoller/worker.py +++ b/src/vpoller/worker.py @@ -298,6 +298,8 @@ def process_client_message(self, msg): 'datastore.discover': self.agents[vsphere_host].discover_datastores, 'vm.get': self.agents[vsphere_host].get_vm_property, 'vm.discover': self.agents[vsphere_host].discover_virtual_machines, + 'vm.counter.get': self.agents[vsphere_host].get_vm_counter, + 'vm.counter.all': self.agents[vsphere_host].get_vm_counter_all, 'datacenter.get': self.agents[vsphere_host].get_datacenter_property, 'datacenter.discover': self.agents[vsphere_host].discover_datacenters, 'cluster.get': self.agents[vsphere_host].get_cluster_property,