本文通过代码举例虚拟机cpu的使用情况来演示如何遍历搜寻VirtualMachine的对象,以及根据这个对象进行性能指标的见识。希望可以取到举一反三的效果。
首先下面先罗列出如何更具虚拟机的名称获得VirtualMachine的ManagedObjectReference对象。
private static TraversalSpec getVmTraversalSpec() { TraversalSpec vAppToVM = new TraversalSpec(); vAppToVM.setName("vAppToVM"); vAppToVM.setType("VirtualApp"); vAppToVM.setPath("vm"); TraversalSpec vAppToVApp = new TraversalSpec(); vAppToVApp.setName("vAppToVApp"); vAppToVApp.setType("VirtualApp"); vAppToVApp.setPath("resourcePool"); SelectionSpec vAppRecursion = new SelectionSpec(); vAppRecursion.setName("vAppToVApp"); SelectionSpec vmInVApp = new SelectionSpec(); vmInVApp.setName("vAppToVM"); List<SelectionSpec> vAppToVMSS = new ArrayList<SelectionSpec>(); vAppToVMSS.add(vAppRecursion); vAppToVMSS.add(vmInVApp); vAppToVApp.getSelectSet().addAll(vAppToVMSS); SelectionSpec sSpec = new SelectionSpec(); sSpec.setName("VisitFolders"); TraversalSpec dataCenterToVMFolder = new TraversalSpec(); dataCenterToVMFolder.setName("DataCenterToVMFolder"); dataCenterToVMFolder.setType("Datacenter"); dataCenterToVMFolder.setPath("vmFolder"); dataCenterToVMFolder.setSkip(false); dataCenterToVMFolder.getSelectSet().add(sSpec); TraversalSpec traversalSpec = new TraversalSpec(); traversalSpec.setName("VisitFolders"); traversalSpec.setType("Folder"); traversalSpec.setPath("childEntity"); traversalSpec.setSkip(false); List<SelectionSpec> sSpecArr = new ArrayList<SelectionSpec>(); sSpecArr.add(sSpec); sSpecArr.add(dataCenterToVMFolder); sSpecArr.add(vAppToVM); sSpecArr.add(vAppToVApp); traversalSpec.getSelectSet().addAll(sSpecArr); return traversalSpec; }
private static ManagedObjectReference getVmByVmName(String vmName) { ManagedObjectReference retVal = null; ManagedObjectReference rootFolder = serviceContent.getRootFolder(); try { TraversalSpec tSpec = getVmTraversalSpec(); PropertySpec propertySpec = new PropertySpec(); propertySpec.setAll(Boolean.FALSE); propertySpec.getPathSet().add("name"); propertySpec.setType("VirtualMachine"); ObjectSpec objectSpec = new ObjectSpec(); objectSpec.setObj(rootFolder); objectSpec.setSkip(Boolean.TRUE); objectSpec.getSelectSet().add(tSpec); PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec(); propertyFilterSpec.getPropSet().add(propertySpec); propertyFilterSpec.getObjectSet().add(objectSpec); List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>(1); listpfs.add(propertyFilterSpec); List<ObjectContent> listobjcont = retrievePropertiesAllObjects(listpfs); if (listobjcont != null) { for (ObjectContent oc : listobjcont) { ManagedObjectReference mr = oc.getObj(); String vmnm = null; List<DynamicProperty> dps = oc.getPropSet(); if (dps != null) { for (DynamicProperty dp : dps) { vmnm = (String) dp.getVal(); } } if (vmnm != null && vmnm.equals(vmName)) { retVal = mr; break; } } } } catch (SOAPFaultException sfe) { printSoapFaultException(sfe); } catch (Exception e) { e.printStackTrace(); } return retVal; }然后根据上面的VirtualMachine的ManagedObjectReference对象获取虚拟机的实时性能信息:
private static List<List<Long>> getVmData(String vmName, String nameInfo, String groupInfo) throws RuntimeFaultFaultMsg, DatatypeConfigurationException { List<List<Long>> list = new ArrayList<List<Long>>(); ManagedObjectReference vmmor = getVmByVmName(vmName); if (vmmor != null) { List<PerfCounterInfo> cInfo = getPerfCounters(); int i = 0; Map<Integer, PerfCounterInfo> counters = new HashMap<Integer, PerfCounterInfo>(); for (Iterator<PerfCounterInfo> it = cInfo.iterator(); it.hasNext();) { PerfCounterInfo pcInfo = (PerfCounterInfo) it.next(); counters.put(new Integer(pcInfo.getKey()), pcInfo); } List<PerfMetricId> listpermeid = vimPort.queryAvailablePerfMetric(perfManager, vmmor, null, null, new Integer(20)); ArrayList<PerfMetricId> mMetrics = new ArrayList<PerfMetricId>(); if (listpermeid != null) { for (int index = 0; index < listpermeid.size(); ++index) { if (counters.containsKey(new Integer(listpermeid.get(index).getCounterId()))) { mMetrics.add(listpermeid.get(index)); } } } PerfQuerySpec qSpec = new PerfQuerySpec(); qSpec.setEntity(vmmor); qSpec.setMaxSample(new Integer(10)); qSpec.getMetricId().addAll(mMetrics); qSpec.setIntervalId(new Integer(20)); List<PerfQuerySpec> qSpecs = new ArrayList<PerfQuerySpec>(); qSpecs.add(qSpec); List<PerfEntityMetricBase> listpemb = vimPort.queryPerf(perfManager, qSpecs); List<PerfEntityMetricBase> pValues = listpemb; for (i = 0; i < pValues.size(); i++) { List<PerfMetricSeries> listpems = ((PerfEntityMetric) pValues.get(i)).getValue(); List<PerfSampleInfo> listinfo = ((PerfEntityMetric) pValues.get(i)).getSampleInfo(); for (int vi = 0; vi < listpems.size(); ++vi) { String printInf = ""; PerfCounterInfo pci = (PerfCounterInfo) counters.get(new Integer(listpems.get(vi).getId().getCounterId())); if (pci != null) { if (pci.getNameInfo().getKey().equalsIgnoreCase(nameInfo) && pci.getGroupInfo().getKey().equalsIgnoreCase(groupInfo)) { printInf += vi + ":" + pci.getNameInfo().getSummary() + ":" + pci.getNameInfo().getKey() + ":" + pci.getNameInfo().getLabel() + ":" + pci.getGroupInfo().getKey() + ":" + pci.getGroupInfo().getLabel() + ":" + pci.getGroupInfo().getSummary() + " "; for (PerfMetricId pmi : mMetrics) { int counterId = pmi.getCounterId(); if (counterId == listpems.get(vi).getId().getCounterId()) { printInf += "[" + pmi.getCounterId() + ":" + pmi.getInstance() + "] "; } } if (listpems.get(vi) instanceof PerfMetricIntSeries) { PerfMetricIntSeries val = (PerfMetricIntSeries) listpems.get(vi); List<Long> lislon = val.getValue(); for (Long k : lislon) { printInf += k + " "; } list.add(lislon); } printInf += " " + pci.getUnitInfo().getKey() + " " + pci.getUnitInfo().getLabel() + " " + pci.getUnitInfo().getSummary(); System.out.println(printInf); } } } } } return list; }
真正获取cpu使用情况的方法只是调用上面的方法做一些简单的处理:
public static double getVmCpuUsageByVmName(String VmName) throws RuntimeFaultFaultMsg, DatatypeConfigurationException { double ans = 0.0; List<List<Long>> list = getVmData(VmName, "usage", "cpu"); long maxInner = 0; int times = 0; for (List<Long> listOuter : list) { long tempInner = 0; for (long inner : listOuter) { tempInner += inner; } if (tempInner > maxInner) { maxInner = tempInner; times = listOuter.size(); } } if (times != 0) { ans = (double) maxInner / times; } ans = ans / 100; return ans; }
这里的虚拟机cpu使用情况是百分制的,而且vsphere sdk返回的百分比的结果都是要除以100的,譬如真实结果是5%,那么vsphere sdk返回的就是500,需要做一下处理。
接下来获取cpu的可用量:
public static double getVmCpuEntitlementByVmName(String VmName) throws RuntimeFaultFaultMsg, DatatypeConfigurationException { double ans = 0; List<List<Long>> list = getVmData(VmName, "entitlement", "cpu"); long maxInner = 0; int times = 0; for (List<Long> listOuter : list) { long tempInner = 0; for (long inner : listOuter) { tempInner += inner; } if (tempInner > maxInner) { maxInner = tempInner; times = listOuter.size(); } } if (times != 0) { ans = (double) maxInner / times; } return ans; }细心的读者可能发现的差别,这里只需要修改nameinfo以及groupinfo即可以获取不同的结果。
有一些监控数据不是实时获取的,通过上面的方法是获取不到的,比如:获取虚拟机cpu的个数,类似这种比较固定的信息,或者说配置信息更,就要另辟蹊径了。
public static int getVmCpuNumByVmName(String VmName) throws RuntimeFaultFaultMsg, InvalidPropertyFaultMsg { int ans = 0; String cpuNum = getVmPropertyByVmName("summary.config.numCpu", VmName); ans = Integer.valueOf(cpuNum); return ans; }
private static String getVmPropertyByVmName(String property, String VmName) throws RuntimeFaultFaultMsg, InvalidPropertyFaultMsg { String ans = null; RetrieveResult props = getRetrieveResultObjectWithProperty("VirtualMachine", property); if (props != null) { Boolean flag = false; if (property.compareToIgnoreCase("name") < 0) { for (ObjectContent oc : props.getObjects()) { if (flag == true) { break; } String path = null; List<DynamicProperty> dps = oc.getPropSet(); if (dps != null) { for (DynamicProperty dp : dps) { path = dp.getName(); if (path.equalsIgnoreCase(property)) { String val = String.valueOf(dp.getVal()); ans = val; } if (path.equalsIgnoreCase("name")) { String value = (String) dp.getVal(); if (value.equals(VmName)) { flag = true; break; } } } } } } else { for (ObjectContent oc : props.getObjects()) { if (flag == true) { break; } String path = null; List<DynamicProperty> dps = oc.getPropSet(); if (dps != null) { for (DynamicProperty dp : dps) { path = dp.getName(); if (path.equalsIgnoreCase("name")) { String value = (String) dp.getVal(); if (value.equals(VmName)) { flag = true; } } if (path.equalsIgnoreCase(property)) { String val = String.valueOf(dp.getVal()); if (flag == true) { ans = val; break; } } } } } } } return ans; }
private static RetrieveResult getRetrieveResultObjectWithProperty(String MorName, String property) throws InvalidPropertyFaultMsg, RuntimeFaultFaultMsg { ManagedObjectReference viewMgrRef = serviceContent.getViewManager(); ManagedObjectReference propColl = serviceContent.getPropertyCollector(); List<String> vmList = new ArrayList<String>(); vmList.add(MorName); ManagedObjectReference cViewRef = vimPort.createContainerView(viewMgrRef, serviceContent.getRootFolder(), vmList, true); ObjectSpec oSpec = new ObjectSpec(); oSpec.setObj(cViewRef); oSpec.setSkip(true); TraversalSpec tSpec = new TraversalSpec(); tSpec.setName("traversalEntities"); tSpec.setPath("view"); tSpec.setSkip(false); tSpec.setType("ContainerView"); oSpec.getSelectSet().add(tSpec); PropertySpec pSpec = new PropertySpec(); pSpec.setType(MorName); pSpec.getPathSet().add("name"); PropertySpec pSpecRPr = new PropertySpec(); pSpecRPr.setType(MorName); pSpecRPr.getPathSet().add(property); PropertyFilterSpec fSpec = new PropertyFilterSpec(); fSpec.getObjectSet().add(oSpec); fSpec.getPropSet().add(pSpec); fSpec.getPropSet().add(pSpecRPr); List<PropertyFilterSpec> fSpecList = new ArrayList<PropertyFilterSpec>(); fSpecList.add(fSpec); RetrieveOptions ro = new RetrieveOptions(); RetrieveResult props = vimPort.retrievePropertiesEx(propColl, fSpecList, ro); return props; }这样就可以获取虚拟机的cpu个数的信息。
附加一个方法(获取vCenter下所有虚拟机的名称)
public static List<String> getVmNames() { List<String> list = new ArrayList<String>(); ManagedObjectReference rootFolder = serviceContent.getRootFolder(); try { TraversalSpec tSpec = getVmTraversalSpec(); PropertySpec propertySpec = new PropertySpec(); propertySpec.setAll(Boolean.FALSE); propertySpec.getPathSet().add("name"); propertySpec.setType("VirtualMachine"); ObjectSpec objectSpec = new ObjectSpec(); objectSpec.setObj(rootFolder); objectSpec.setSkip(Boolean.TRUE); objectSpec.getSelectSet().add(tSpec); PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec(); propertyFilterSpec.getPropSet().add(propertySpec); propertyFilterSpec.getObjectSet().add(objectSpec); List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>(1); listpfs.add(propertyFilterSpec); List<ObjectContent> listobjcont = retrievePropertiesAllObjects(listpfs); if (listobjcont != null) { for (ObjectContent oc : listobjcont) { String vmnm = null; List<DynamicProperty> dps = oc.getPropSet(); if (dps != null) { for (DynamicProperty dp : dps) { vmnm = (String) dp.getVal(); if (vmnm != null) { list.add(vmnm); } } } } } } catch (SOAPFaultException sfe) { printSoapFaultException(sfe); } catch (Exception e) { e.printStackTrace(); } return list; }关于主机(HostSystem)信息的获取将在下一篇文章中呈现。敬请期待。
Modified: 居然忘了写一个重要的函数了,这里赶紧补上:
private static List<PerfCounterInfo> getPerfCounters() { List<PerfCounterInfo> pciArr = null; try { PropertySpec propertySpec = new PropertySpec(); propertySpec.setAll(Boolean.FALSE); propertySpec.getPathSet().add("perfCounter"); propertySpec.setType("PerformanceManager"); List<PropertySpec> propertySpecs = new ArrayList<PropertySpec>(); propertySpecs.add(propertySpec); ObjectSpec objectSpec = new ObjectSpec(); objectSpec.setObj(perfManager); List<ObjectSpec> objectSpecs = new ArrayList<ObjectSpec>(); objectSpecs.add(objectSpec); PropertyFilterSpec propertyFilterSpec = new PropertyFilterSpec(); propertyFilterSpec.getPropSet().add(propertySpec); propertyFilterSpec.getObjectSet().add(objectSpec); List<PropertyFilterSpec> propertyFilterSpecs = new ArrayList<PropertyFilterSpec>(); propertyFilterSpecs.add(propertyFilterSpec); List<PropertyFilterSpec> listpfs = new ArrayList<PropertyFilterSpec>(10); listpfs.add(propertyFilterSpec); List<ObjectContent> listobjcont = retrievePropertiesAllObjects(listpfs); if (listobjcont != null) { for (ObjectContent oc : listobjcont) { List<DynamicProperty> dps = oc.getPropSet(); if (dps != null) { for (DynamicProperty dp : dps) { List<PerfCounterInfo> pcinfolist = ((ArrayOfPerfCounterInfo) dp.getVal()).getPerfCounterInfo(); pciArr = pcinfolist; } } } } } catch (SOAPFaultException sfe) { printSoapFaultException(sfe); } catch (Exception e) { e.printStackTrace(); } return pciArr; }