You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
5.5 KiB

from vim25.connection import Connection
from vim25.mo import ManagedObjectReference
import re
class MetricsCache(object):
def __init__(self, hostmoid, vmmoid, vm_metric_allowlist=[], vm_metric_denylist=[], host_metric_allowlist=[], host_metric_denylist=[]):
"""This class will set "fullcounters" to an dictionary with keys structured like so:
as a side note, this would be better stored as a set of listed objects for structure,
but I don't want to test pickling in hydra incase we ever go cross os... SO nested
dicts it is! This class also always assumes an active connection object.
fullcounters = {"hostmetrics":fullhostcounters,"vmmetrics":fullvmcounters, "vmrefreshrate":self.vmrefreshrate, "hostrefreshrate":self.hostrefreshRate}
Instantiated with kwargs:
@hostmoid - moid of the host to store a metric cache for
@vmmoid - moid of a vm currently residing on the host. Used to query vm counters. Should be a list at max 5 vms.
@vm_metric_allowlist - virtual machine metrics allow list
@vm_metric_denylist - virtual machine metrics deny list
@host_metric_allowlist - host system metrics allow list
@host_metric_denylist - host system metrics deny list
"""
self.perfManager = Connection.perfManager
self.hostmoid=hostmoid
self.vmmoid=vmmoid
self.vm_metric_allowlist = [re.compile(x) for x in vm_metric_allowlist]
self.vm_metric_denylist = [re.compile(x) for x in vm_metric_denylist]
self.host_metric_allowlist = [re.compile(x) for x in host_metric_allowlist]
self.host_metric_denylist = [re.compile(x) for x in host_metric_denylist]
self.hostsystem = Connection.vim25client.createExactManagedObject(mor=ManagedObjectReference(value=self.hostmoid, _type="HostSystem"))
self.vm = []
self.vmrefreshrate=0
count=0
if vmmoid:
for vm in vmmoid:
if count<=5:
currentvm = Connection.vim25client.createExactManagedObject(mor=ManagedObjectReference(value=vm, _type="VirtualMachine"))
currentvmrefreshrate = self._queryRefreshRate(currentvm)
if currentvmrefreshrate < self.vmrefreshrate or self.vmrefreshrate==0:
self.vmrefreshrate = currentvmrefreshrate
self.vm.append(currentvm)
count=count+1
else:
break
self.counterlistvm = self._queryVMCounters()
else:
self.vmrefreshrate=0
self.counterlistvm = []
self.hostrefreshRate = self._queryRefreshRate(self.hostsystem)
self.counterlisthost = self._queryHostCounters()
if self.counterlisthost:
self.fullcounters = self._getCounterListsNames()
else:
self.fullcounters = None
def _queryRefreshRate(self, entity):
pps = self.perfManager.queryPerfProviderSummary(entity)
return pps.refreshRate
def _queryHostCounters(self):
counterlisthost = set()
for counter in self.perfManager.queryAvailablePerfMetric(self.hostsystem, intervalId=self.hostrefreshRate):
counterlisthost.add(counter.counterId)
return counterlisthost
def _queryVMCounters(self):
counterlistvm = set()
for vm in self.vm:
for counter in self.perfManager.queryAvailablePerfMetric(vm, intervalId=self.vmrefreshrate):
counterlistvm.add(counter.counterId)
return counterlistvm
def _pruneAllowDenylists(self, listtoprune, allowlist, denylist):
'''
Must be passed as regex compiled python objects. re.compile("string").
Will return a list with items pruned. Items that match the allowlist AND are not
in the denylist will be returned. A blank allowlist will assume that all entries are allowed.
a blank denylist will assume no entries are denied.
'''
res = []
for metric in listtoprune:
processmetric=True
if allowlist and denylist:
#There is a allowlist pattern specified and a denylist pattern
processmetric=False
if [regexmatch for regexmatch in allowlist if regexmatch.match(metric['name'])] and not [regexmatch for regexmatch in denylist if regexmatch.match(metric['name'])]:
processmetric=True
elif allowlist and not denylist:
#There is a allow list and no denylist
processmetric=False
if [regexmatch for regexmatch in allowlist if regexmatch.match(metric['name'])]:
processmetric=True
elif not allowlist and denylist:
#There is no allowlist and there is a denylist
if [regexmatch for regexmatch in denylist if regexmatch.match(metric['name'])]:
processmetric=False
if processmetric:
res.append(metric)
return res
def _getCounterListsNames(self):
if self.counterlistvm:
counterlistvmnames=self.perfManager.queryPerfCounter(counterId=list(self.counterlistvm))
fullvmcounters = []
for counter in counterlistvmnames:
fullvmcounters.append({"id":counter.key, "name":"_".join(['p', counter.rollupType, counter.groupInfo.key, counter.nameInfo.key, counter.unitInfo.key]), "group":str(counter.groupInfo.key)})
if self.vm_metric_allowlist or self.vm_metric_denylist:
fullvmcounters = self._pruneAllowDenylists(fullvmcounters, self.vm_metric_allowlist, self.vm_metric_denylist)
else:
fullvmcounters = []
counterlisthostnames=self.perfManager.queryPerfCounter(counterId=list(self.counterlisthost))
fullhostcounters = []
for counter in counterlisthostnames:
fullhostcounters.append({"id":counter.key, "name":"_".join(['p', counter.rollupType, counter.groupInfo.key, counter.nameInfo.key, counter.unitInfo.key]), "group":str(counter.groupInfo.key)})
if self.host_metric_allowlist or self.host_metric_denylist:
fullhostcounters = self._pruneAllowDenylists(fullhostcounters, self.host_metric_allowlist, self.host_metric_denylist)
return {"hostmetrics":fullhostcounters,"vmmetrics":fullvmcounters, "vmrefreshrate":self.vmrefreshrate, "hostrefreshrate":self.hostrefreshRate}