From 8aa0f3d4925475505a376f7c1b2205ac895857e9 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Thu, 4 Apr 2019 16:08:54 +0530 Subject: [PATCH 01/10] volume: export disk read/write bytes+iops via volumes and volume metrics API This re-uses an existing volume stats dao/table to display the volume specific disk read/write bytes and iops statistics via the listVolumes and listVolumeMetrics API, as well as display granular metrics in the UI. TODO: implement support for VMware and possibly for XenServer? Signed-off-by: Rohit Yadav --- .../apache/cloudstack/api/ApiConstants.java | 5 ++ .../api/response/UserVmResponse.java | 8 +-- .../api/response/VolumeResponse.java | 65 ++++++++++++++++--- .../vmware/resource/VmwareResource.java | 1 + .../CitrixGetVmDiskStatsCommandWrapper.java | 1 + .../metrics/MetricsServiceImpl.java | 63 +++++++++--------- .../response/VmMetricsResponse.java | 9 +-- .../response/VolumeMetricsResponse.java | 14 +++- .../api/query/dao/VolumeJoinDaoImpl.java | 12 ++++ .../java/com/cloud/server/StatsCollector.java | 4 +- .../java/com/cloud/vm/UserVmManagerImpl.java | 3 +- ui/scripts/metrics.js | 15 +++++ 12 files changed, 150 insertions(+), 50 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index 71a201f5bd89..eb43d1539b88 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -91,6 +91,11 @@ public class ApiConstants { public static final String DIRECT_DOWNLOAD = "directdownload"; public static final String DISK_OFFERING_ID = "diskofferingid"; public static final String NEW_DISK_OFFERING_ID = "newdiskofferingid"; + public static final String DISK_KBS_READ = "diskkbsread"; + public static final String DISK_KBS_WRITE = "diskkbswrite"; + public static final String DISK_IO_READ = "diskioread"; + public static final String DISK_IO_WRITE = "diskiowrite"; + public static final String DISK_IO_PSTOTAL = "diskiopstotal"; public static final String DISK_SIZE = "disksize"; public static final String UTILIZATION = "utilization"; public static final String DRIVER = "driver"; diff --git a/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java index 8db4f853243c..be057542fc3e 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/UserVmResponse.java @@ -188,11 +188,11 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co @Param(description = "the outgoing network traffic on the host") private Long networkKbsWrite; - @SerializedName("diskkbsread") + @SerializedName(ApiConstants.DISK_KBS_READ) @Param(description = "the read (bytes) of disk on the vm") private Long diskKbsRead; - @SerializedName("diskkbswrite") + @SerializedName(ApiConstants.DISK_KBS_WRITE) @Param(description = "the write (bytes) of disk on the vm") private Long diskKbsWrite; @@ -208,11 +208,11 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co @Param(description = "the target memory in vm") private Long memoryTargetKBs; - @SerializedName("diskioread") + @SerializedName(ApiConstants.DISK_IO_READ) @Param(description = "the read (io) of disk on the vm") private Long diskIORead; - @SerializedName("diskiowrite") + @SerializedName(ApiConstants.DISK_IO_WRITE) @Param(description = "the write (io) of disk on the vm") private Long diskIOWrite; diff --git a/api/src/main/java/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VolumeResponse.java index d845e4148083..01d2c9b3d8f1 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/VolumeResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/VolumeResponse.java @@ -16,17 +16,18 @@ // under the License. package org.apache.cloudstack.api.response; -import com.cloud.serializer.Param; -import com.cloud.storage.Volume; -import com.google.gson.annotations.SerializedName; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.Set; + import org.apache.cloudstack.acl.RoleType; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.BaseResponseWithTagInformation; import org.apache.cloudstack.api.EntityReference; -import java.util.Date; -import java.util.LinkedHashSet; -import java.util.Set; +import com.cloud.serializer.Param; +import com.cloud.storage.Volume; +import com.google.gson.annotations.SerializedName; @EntityReference(value = Volume.class) @SuppressWarnings("unused") @@ -152,13 +153,29 @@ public class VolumeResponse extends BaseResponseWithTagInformation implements Co private Long bytesWriteRate; @SerializedName("diskIopsReadRate") - @Param(description = "io requests read rate of the disk volume") + @Param(description = "io requests read rate of the disk volume per the disk offering") private Long iopsReadRate; @SerializedName("diskIopsWriteRate") - @Param(description = "io requests write rate of the disk volume") + @Param(description = "io requests write rate of the disk volume per the disk offering") private Long iopsWriteRate; + @SerializedName(ApiConstants.DISK_KBS_READ) + @Param(description = "the read (bytes) of disk on the vm") + private Long diskKbsRead; + + @SerializedName(ApiConstants.DISK_KBS_WRITE) + @Param(description = "the write (bytes) of disk on the vm") + private Long diskKbsWrite; + + @SerializedName(ApiConstants.DISK_IO_READ) + @Param(description = "the read (io) of disk on the vm") + private Long diskIORead; + + @SerializedName(ApiConstants.DISK_IO_WRITE) + @Param(description = "the write (io) of disk on the vm") + private Long diskIOWrite; + @SerializedName(ApiConstants.HYPERVISOR) @Param(description = "Hypervisor the volume belongs to") private String hypervisor; @@ -395,10 +412,42 @@ public void setIopsWriteRate(Long iopsWriteRate) { this.iopsWriteRate = iopsWriteRate; } + public Long getDiskKbsRead() { + return diskKbsRead; + } + + public void setDiskKbsRead(Long diskKbsRead) { + this.diskKbsRead = diskKbsRead; + } + + public Long getDiskKbsWrite() { + return diskKbsWrite; + } + + public void setDiskKbsWrite(Long diskKbsWrite) { + this.diskKbsWrite = diskKbsWrite; + } + public Long getIopsWriteRate() { return iopsWriteRate; } + public Long getDiskIORead() { + return diskIORead; + } + + public void setDiskIORead(Long diskIORead) { + this.diskIORead = diskIORead; + } + + public Long getDiskIOWrite() { + return diskIOWrite; + } + + public void setDiskIOWrite(Long diskIOWrite) { + this.diskIOWrite = diskIOWrite; + } + public void setHypervisor(String hypervisor) { this.hypervisor = hypervisor; } diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 37d27c855bc4..89ee50899e9c 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -3496,6 +3496,7 @@ protected Answer execute(GetVmStatsCommand cmd) { } protected Answer execute(GetVmDiskStatsCommand cmd) { + // TODO: implement for Vmware return new GetVmDiskStatsAnswer(cmd, null, null, null); } diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java index 04090ce7436f..7e0124d4e04e 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java @@ -31,6 +31,7 @@ public final class CitrixGetVmDiskStatsCommandWrapper extends CommandWrapper listVolumeMetrics(List volume metricsResponse.setDiskSizeGB(volumeResponse.getSize()); metricsResponse.setStorageType(volumeResponse.getStorageType(), volumeResponse.getVolumeType()); + metricsResponse.setDiskIopsTotal(volumeResponse.getDiskIORead(), volumeResponse.getDiskIOWrite()); metricsResponses.add(metricsResponse); } return metricsResponses; diff --git a/plugins/metrics/src/main/java/org/apache/cloudstack/response/VmMetricsResponse.java b/plugins/metrics/src/main/java/org/apache/cloudstack/response/VmMetricsResponse.java index a4057aeb0590..4ac388ddb997 100644 --- a/plugins/metrics/src/main/java/org/apache/cloudstack/response/VmMetricsResponse.java +++ b/plugins/metrics/src/main/java/org/apache/cloudstack/response/VmMetricsResponse.java @@ -17,13 +17,14 @@ package org.apache.cloudstack.response; -import com.cloud.serializer.Param; -import com.google.gson.annotations.SerializedName; +import java.util.Set; + import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.api.response.NicResponse; import org.apache.cloudstack.api.response.UserVmResponse; -import java.util.Set; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; public class VmMetricsResponse extends UserVmResponse { @SerializedName(ApiConstants.IP_ADDRESS) @@ -54,7 +55,7 @@ public class VmMetricsResponse extends UserVmResponse { @Param(description = "disk write in MiB") private String diskWrite; - @SerializedName("diskiopstotal") + @SerializedName(ApiConstants.DISK_IO_PSTOTAL) @Param(description = "the total disk iops") private Long diskIopsTotal; diff --git a/plugins/metrics/src/main/java/org/apache/cloudstack/response/VolumeMetricsResponse.java b/plugins/metrics/src/main/java/org/apache/cloudstack/response/VolumeMetricsResponse.java index ef8515f13965..47d7a7cca652 100644 --- a/plugins/metrics/src/main/java/org/apache/cloudstack/response/VolumeMetricsResponse.java +++ b/plugins/metrics/src/main/java/org/apache/cloudstack/response/VolumeMetricsResponse.java @@ -17,16 +17,22 @@ package org.apache.cloudstack.response; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.response.VolumeResponse; + import com.cloud.serializer.Param; import com.google.common.base.Strings; import com.google.gson.annotations.SerializedName; -import org.apache.cloudstack.api.response.VolumeResponse; public class VolumeMetricsResponse extends VolumeResponse { @SerializedName("sizegb") @Param(description = "disk size in GiB") private String diskSizeGB; + @SerializedName(ApiConstants.DISK_IO_PSTOTAL) + @Param(description = "the total disk iops") + private Long diskIopsTotal; + public void setStorageType(final String storageType, final String volumeType) { if (!Strings.isNullOrEmpty(storageType) && !Strings.isNullOrEmpty(volumeType)) { this.setStorageType(String.format("%s (%s)", storageType.substring(0, 1).toUpperCase() + storageType.substring(1), volumeType)); @@ -38,4 +44,10 @@ public void setDiskSizeGB(final Long size) { this.diskSizeGB = String.format("%.2f GB", size / (1024.0 * 1024.0 * 1024.0)); } } + + public void setDiskIopsTotal(final Long diskIoRead, final Long diskIoWrite) { + if (diskIoRead != null && diskIoWrite != null) { + this.diskIopsTotal = diskIoRead + diskIoWrite; + } + } } diff --git a/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java index 6ed9be945edd..d6aa53d048d2 100644 --- a/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java +++ b/server/src/main/java/com/cloud/api/query/dao/VolumeJoinDaoImpl.java @@ -36,6 +36,8 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; import com.cloud.storage.Volume; import com.cloud.user.AccountManager; +import com.cloud.user.VmDiskStatisticsVO; +import com.cloud.user.dao.VmDiskStatisticsDao; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -47,6 +49,8 @@ public class VolumeJoinDaoImpl extends GenericDaoBaseWithTagInformation volSearch; @@ -102,6 +106,14 @@ public VolumeResponse newVolumeResponse(ResponseView view, VolumeJoinVO volume) } else { volResponse.setVirtualMachineDisplayName(volume.getVmName()); } + + VmDiskStatisticsVO diskStats = vmDiskStatsDao.findBy(volume.getAccountId(), volume.getDataCenterId(), instanceId, volume.getId()); + if (diskStats != null) { + volResponse.setDiskIORead(diskStats.getCurrentIORead()); + volResponse.setDiskIOWrite(diskStats.getCurrentIOWrite()); + volResponse.setDiskKbsRead((long) (diskStats.getCurrentBytesRead() / 1024.0)); + volResponse.setDiskKbsWrite((long) (diskStats.getCurrentBytesWrite() / 1024.0)); + } } if (volume.getProvisioningType() != null) { diff --git a/server/src/main/java/com/cloud/server/StatsCollector.java b/server/src/main/java/com/cloud/server/StatsCollector.java index 80b745e3480b..d5ae511b5f20 100644 --- a/server/src/main/java/com/cloud/server/StatsCollector.java +++ b/server/src/main/java/com/cloud/server/StatsCollector.java @@ -689,14 +689,14 @@ public void doInTransactionWithoutResult(TransactionStatus status) { s_logger.debug("VmDiskStatsTask is running..."); SearchCriteria sc = createSearchCriteriaForHostTypeRoutingStateUpAndNotInMaintenance(); - sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, HypervisorType.KVM); // support KVM only util 2013.06.25 + sc.addAnd("hypervisorType", SearchCriteria.Op.IN, HypervisorType.KVM, HypervisorType.VMware); // TODO: Support VMware support KVM only util 2013.06.25 List hosts = _hostDao.search(sc, null); for (HostVO host : hosts) { List vms = _userVmDao.listRunningByHostId(host.getId()); List vmIds = new ArrayList(); - for (UserVmVO vm : vms) { + for (UserVmVO vm : vms) { if (vm.getType() == VirtualMachine.Type.User) // user vm vmIds.add(vm.getId()); } diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 68b45e1af7c3..1dc38b164d83 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4613,7 +4613,8 @@ public UserVm destroyVm(long vmId, boolean expunge) throws ResourceUnavailableEx @Override public void collectVmDiskStatistics(final UserVm userVm) { // support KVM only util 2013.06.25 - if (!userVm.getHypervisorType().equals(HypervisorType.KVM)) { + // TODO: Implement support for VMware? + if (!(userVm.getHypervisorType().equals(HypervisorType.KVM) || userVm.getHypervisorType().equals(HypervisorType.VMware))) { return; } s_logger.debug("Collect vm disk statistics from host before stopping Vm"); diff --git a/ui/scripts/metrics.js b/ui/scripts/metrics.js index 19d011815ce4..94f069525991 100644 --- a/ui/scripts/metrics.js +++ b/ui/scripts/metrics.js @@ -590,6 +590,21 @@ storage: { label: 'label.metrics.storagepool' }, + disk: { + label: 'label.metrics.disk.usage', + collapsible: true, + columns: { + diskioread: { + label: 'label.metrics.disk.read' + }, + diskiowrite: { + label: 'label.metrics.disk.write' + }, + diskiopstotal: { + label: 'label.metrics.disk.iops.total' + } + } + } }, dataProvider: function(args) { var data = {listAll: true}; From c5102569be339accba76f0fc3e39eabadf240e52 Mon Sep 17 00:00:00 2001 From: Anurag Awasthi Date: Thu, 11 Apr 2019 19:05:54 +0530 Subject: [PATCH 02/10] Add support to VMWare for collecting VM Disk Statistics --- .../vmware/resource/VmwareResource.java | 227 +++++++++++++----- 1 file changed, 164 insertions(+), 63 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 89ee50899e9c..dcc6ebde4db7 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -43,68 +43,6 @@ import javax.naming.ConfigurationException; -import org.apache.commons.lang.math.NumberUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; -import org.apache.log4j.NDC; -import org.joda.time.Duration; - -import com.google.gson.Gson; -import com.vmware.vim25.AboutInfo; -import com.vmware.vim25.BoolPolicy; -import com.vmware.vim25.ComputeResourceSummary; -import com.vmware.vim25.CustomFieldStringValue; -import com.vmware.vim25.DVPortConfigInfo; -import com.vmware.vim25.DVPortConfigSpec; -import com.vmware.vim25.DasVmPriority; -import com.vmware.vim25.DatastoreSummary; -import com.vmware.vim25.DistributedVirtualPort; -import com.vmware.vim25.DistributedVirtualSwitchPortConnection; -import com.vmware.vim25.DistributedVirtualSwitchPortCriteria; -import com.vmware.vim25.DynamicProperty; -import com.vmware.vim25.GuestInfo; -import com.vmware.vim25.HostCapability; -import com.vmware.vim25.HostHostBusAdapter; -import com.vmware.vim25.HostInternetScsiHba; -import com.vmware.vim25.ManagedObjectReference; -import com.vmware.vim25.ObjectContent; -import com.vmware.vim25.OptionValue; -import com.vmware.vim25.PerfCounterInfo; -import com.vmware.vim25.PerfEntityMetric; -import com.vmware.vim25.PerfEntityMetricBase; -import com.vmware.vim25.PerfMetricId; -import com.vmware.vim25.PerfMetricIntSeries; -import com.vmware.vim25.PerfMetricSeries; -import com.vmware.vim25.PerfQuerySpec; -import com.vmware.vim25.PerfSampleInfo; -import com.vmware.vim25.RuntimeFaultFaultMsg; -import com.vmware.vim25.ToolsUnavailableFaultMsg; -import com.vmware.vim25.VMwareDVSPortSetting; -import com.vmware.vim25.VimPortType; -import com.vmware.vim25.VirtualDevice; -import com.vmware.vim25.VirtualDeviceBackingInfo; -import com.vmware.vim25.VirtualDeviceConfigSpec; -import com.vmware.vim25.VirtualDeviceConfigSpecOperation; -import com.vmware.vim25.VirtualDisk; -import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo; -import com.vmware.vim25.VirtualEthernetCard; -import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo; -import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo; -import com.vmware.vim25.VirtualEthernetCardOpaqueNetworkBackingInfo; -import com.vmware.vim25.VirtualMachineConfigSpec; -import com.vmware.vim25.VirtualMachineFileInfo; -import com.vmware.vim25.VirtualMachineFileLayoutEx; -import com.vmware.vim25.VirtualMachineFileLayoutExFileInfo; -import com.vmware.vim25.VirtualMachineGuestOsIdentifier; -import com.vmware.vim25.VirtualMachinePowerState; -import com.vmware.vim25.VirtualMachineRelocateSpec; -import com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator; -import com.vmware.vim25.VirtualMachineRuntimeInfo; -import com.vmware.vim25.VirtualMachineToolsStatus; -import com.vmware.vim25.VirtualMachineVideoCard; -import com.vmware.vim25.VirtualUSBController; -import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec; - import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.storage.command.CopyCommand; import org.apache.cloudstack.storage.command.StorageSubSystemCommand; @@ -114,6 +52,11 @@ import org.apache.cloudstack.storage.to.TemplateObjectTO; import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.math.NumberUtils; +import org.apache.log4j.Logger; +import org.apache.log4j.NDC; +import org.joda.time.Duration; import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; @@ -211,6 +154,7 @@ import com.cloud.agent.api.UpgradeSnapshotCommand; import com.cloud.agent.api.ValidateSnapshotAnswer; import com.cloud.agent.api.ValidateSnapshotCommand; +import com.cloud.agent.api.VmDiskStatsEntry; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.VolumeStatsEntry; import com.cloud.agent.api.check.CheckSshAnswer; @@ -310,6 +254,61 @@ import com.cloud.vm.VirtualMachine.PowerState; import com.cloud.vm.VirtualMachineName; import com.cloud.vm.VmDetailConstants; +import com.google.gson.Gson; +import com.vmware.vim25.AboutInfo; +import com.vmware.vim25.BoolPolicy; +import com.vmware.vim25.ComputeResourceSummary; +import com.vmware.vim25.CustomFieldStringValue; +import com.vmware.vim25.DVPortConfigInfo; +import com.vmware.vim25.DVPortConfigSpec; +import com.vmware.vim25.DasVmPriority; +import com.vmware.vim25.DatastoreSummary; +import com.vmware.vim25.DistributedVirtualPort; +import com.vmware.vim25.DistributedVirtualSwitchPortConnection; +import com.vmware.vim25.DistributedVirtualSwitchPortCriteria; +import com.vmware.vim25.DynamicProperty; +import com.vmware.vim25.GuestInfo; +import com.vmware.vim25.HostCapability; +import com.vmware.vim25.HostHostBusAdapter; +import com.vmware.vim25.HostInternetScsiHba; +import com.vmware.vim25.ManagedObjectReference; +import com.vmware.vim25.ObjectContent; +import com.vmware.vim25.OptionValue; +import com.vmware.vim25.PerfCounterInfo; +import com.vmware.vim25.PerfEntityMetric; +import com.vmware.vim25.PerfEntityMetricBase; +import com.vmware.vim25.PerfMetricId; +import com.vmware.vim25.PerfMetricIntSeries; +import com.vmware.vim25.PerfMetricSeries; +import com.vmware.vim25.PerfQuerySpec; +import com.vmware.vim25.PerfSampleInfo; +import com.vmware.vim25.RuntimeFaultFaultMsg; +import com.vmware.vim25.ToolsUnavailableFaultMsg; +import com.vmware.vim25.VMwareDVSPortSetting; +import com.vmware.vim25.VimPortType; +import com.vmware.vim25.VirtualDevice; +import com.vmware.vim25.VirtualDeviceBackingInfo; +import com.vmware.vim25.VirtualDeviceConfigSpec; +import com.vmware.vim25.VirtualDeviceConfigSpecOperation; +import com.vmware.vim25.VirtualDisk; +import com.vmware.vim25.VirtualDiskFlatVer2BackingInfo; +import com.vmware.vim25.VirtualEthernetCard; +import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo; +import com.vmware.vim25.VirtualEthernetCardNetworkBackingInfo; +import com.vmware.vim25.VirtualEthernetCardOpaqueNetworkBackingInfo; +import com.vmware.vim25.VirtualMachineConfigSpec; +import com.vmware.vim25.VirtualMachineFileInfo; +import com.vmware.vim25.VirtualMachineFileLayoutEx; +import com.vmware.vim25.VirtualMachineFileLayoutExFileInfo; +import com.vmware.vim25.VirtualMachineGuestOsIdentifier; +import com.vmware.vim25.VirtualMachinePowerState; +import com.vmware.vim25.VirtualMachineRelocateSpec; +import com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator; +import com.vmware.vim25.VirtualMachineRuntimeInfo; +import com.vmware.vim25.VirtualMachineToolsStatus; +import com.vmware.vim25.VirtualMachineVideoCard; +import com.vmware.vim25.VirtualUSBController; +import com.vmware.vim25.VmwareDistributedVirtualSwitchVlanIdSpec; public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService, VirtualRouterDeployer { private static final Logger s_logger = Logger.getLogger(VmwareResource.class); @@ -3496,7 +3495,109 @@ protected Answer execute(GetVmStatsCommand cmd) { } protected Answer execute(GetVmDiskStatsCommand cmd) { - // TODO: implement for Vmware + try { + final VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); + final ManagedObjectReference perfMgr = getServiceContext().getServiceContent().getPerfManager(); + VimPortType service = getServiceContext().getService(); + + PerfCounterInfo rdReqPerfCounterInfo = null; + PerfCounterInfo rdBytesPerfCounterInfo = null; + PerfCounterInfo wtReqPerfCounterInfo = null; + PerfCounterInfo wtBytesPerfCounterInfo = null; + + List cInfo = getServiceContext().getVimClient().getDynamicProperty(perfMgr, "perfCounter"); + for (PerfCounterInfo info : cInfo) { + if ("virtualdisk".equalsIgnoreCase(info.getGroupInfo().getKey())) { + if ("read".equalsIgnoreCase(info.getNameInfo().getKey())) { + rdReqPerfCounterInfo = info; + } + if ("write".equalsIgnoreCase(info.getNameInfo().getKey())) { + wtReqPerfCounterInfo = info; + } + if ("readIOSize".equalsIgnoreCase(info.getNameInfo().getKey())) { + rdBytesPerfCounterInfo = info; + } + if ("writeIOSize".equalsIgnoreCase(info.getNameInfo().getKey())) { + wtBytesPerfCounterInfo = info; + } + } + } + + final ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter(); + final DatacenterMO dcMo = new DatacenterMO(getServiceContext(), dcMor); + + final HashMap> vmStatsMap = new HashMap<>(); + for (final String vmName : cmd.getVmNames()) { + final VirtualMachineMO vmMo = dcMo.findVm(vmName); + final List diskStats = new ArrayList<>(); + for (VirtualDisk disk : vmMo.getAllDiskDevice()) { + // TODO Get UUID, PATH of VirtualDisk + String diskUuid = "123", diskPath = "something"; + + final ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, diskUuid); + final ArrayList diskMetricsIds = new ArrayList(); + final List perfMetrics = service.queryAvailablePerfMetric(perfMgr, morDs, null, null, null); + if (perfMetrics != null) { + for (int index = 0; index < perfMetrics.size(); ++index) { + if (((rdReqPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == rdReqPerfCounterInfo.getKey())) + || ((rdBytesPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == rdBytesPerfCounterInfo.getKey())) + || ((wtReqPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == wtReqPerfCounterInfo.getKey())) + || ((wtBytesPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == wtBytesPerfCounterInfo.getKey()))) { + diskMetricsIds.add(perfMetrics.get(index)); + } + } + } + + long readReq = 0; + long readBytes = 0; + long writeReq = 0; + long writeBytes = 0; + + if (diskMetricsIds.size() != 0) { + final PerfQuerySpec qSpec = new PerfQuerySpec(); + qSpec.setEntity(morDs); + final PerfMetricId[] availableMetricIds = diskMetricsIds.toArray(new PerfMetricId[0]); + qSpec.getMetricId().addAll(Arrays.asList(availableMetricIds)); + final List qSpecs = new ArrayList(); + qSpecs.add(qSpec); + + for (PerfEntityMetricBase perfValue : service.queryPerf(perfMgr, qSpecs)) { + final List values = ((PerfEntityMetric)perfValue).getValue(); + for (PerfMetricSeries value : values) { + if (value instanceof PerfMetricIntSeries) { + List valIntSeries = ((PerfMetricIntSeries)value).getValue(); + if (valIntSeries.size() > 0) { + long averageVal = 0; + for (long val : valIntSeries) { + averageVal += val; + } + averageVal /= valIntSeries.size(); + if (value.getId().getCounterId() == rdReqPerfCounterInfo.getKey()) { + readReq = averageVal; + } else if (value.getId().getCounterId() == rdBytesPerfCounterInfo.getKey()) { + readBytes = averageVal; + } else if (value.getId().getCounterId() == wtReqPerfCounterInfo.getKey()) { + writeReq = averageVal; + } else if (value.getId().getCounterId() == wtBytesPerfCounterInfo.getKey()) { + writeBytes = averageVal; + } + } + } + } + } + } + diskStats.add(new VmDiskStatsEntry(vmName, diskPath, writeReq, readReq, writeBytes, readBytes)); + } + if (diskStats.size() > 0) { + vmStatsMap.put(vmName, diskStats); + } + } + if (vmStatsMap.size() > 0) { + return new GetVmDiskStatsAnswer(cmd, "", cmd.getHostName(), vmStatsMap); + } + } catch (Exception e) { + s_logger.error("Unable to execute GetVmDiskStatsCommand due to " + VmwareHelper.getExceptionMessage(e), e); + } return new GetVmDiskStatsAnswer(cmd, null, null, null); } From 0b72f5529333d378eb72fe25f41ba7d7fef09897 Mon Sep 17 00:00:00 2001 From: Anurag Awasthi Date: Fri, 12 Apr 2019 08:49:39 +0530 Subject: [PATCH 03/10] Use vDiskId for UUID --- .../cloud/hypervisor/vmware/resource/VmwareResource.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index dcc6ebde4db7..365453319125 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -3531,8 +3531,8 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { final VirtualMachineMO vmMo = dcMo.findVm(vmName); final List diskStats = new ArrayList<>(); for (VirtualDisk disk : vmMo.getAllDiskDevice()) { - // TODO Get UUID, PATH of VirtualDisk - String diskUuid = "123", diskPath = "something"; + // TODO verify if the UUID, PATH of VirtualDisk is correct + String diskUuid = disk.getVDiskId().getId(); final ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, diskUuid); final ArrayList diskMetricsIds = new ArrayList(); @@ -3586,7 +3586,7 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { } } } - diskStats.add(new VmDiskStatsEntry(vmName, diskPath, writeReq, readReq, writeBytes, readBytes)); + diskStats.add(new VmDiskStatsEntry(vmName, diskUuid, writeReq, readReq, writeBytes, readBytes)); } if (diskStats.size() > 0) { vmStatsMap.put(vmName, diskStats); From 1db44c28346e35fdb8cc69da90e72e3e9d34b064 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Mon, 15 Apr 2019 18:11:13 +0530 Subject: [PATCH 04/10] wip perf count/stats code Signed-off-by: Rohit Yadav --- .../vmware/resource/VmwareResource.java | 162 ++++++++++++------ .../hypervisor/vmware/util/VmwareHelper.java | 12 ++ 2 files changed, 117 insertions(+), 57 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 365453319125..81bad02aaa8f 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -209,6 +209,7 @@ import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO; import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper; import com.cloud.hypervisor.vmware.mo.NetworkDetails; +import com.cloud.hypervisor.vmware.mo.PerfManagerMO; import com.cloud.hypervisor.vmware.mo.TaskMO; import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType; import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder; @@ -3498,27 +3499,34 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { try { final VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); final ManagedObjectReference perfMgr = getServiceContext().getServiceContent().getPerfManager(); + final PerfManagerMO perfManagerMO = new PerfManagerMO(getServiceContext(), perfMgr); VimPortType service = getServiceContext().getService(); - PerfCounterInfo rdReqPerfCounterInfo = null; - PerfCounterInfo rdBytesPerfCounterInfo = null; - PerfCounterInfo wtReqPerfCounterInfo = null; - PerfCounterInfo wtBytesPerfCounterInfo = null; + PerfCounterInfo diskReadIOPerfCounterInfo = null; + PerfCounterInfo diskWriteIOPerfCounterInfo = null; + PerfCounterInfo diskReadKbsPerfCounterInfo = null; + PerfCounterInfo diskWriteKbsPerfCounterInfo = null; + List perfCounterKeys = new ArrayList<>(); - List cInfo = getServiceContext().getVimClient().getDynamicProperty(perfMgr, "perfCounter"); + // https://pubs.vmware.com/vsphere-5-5/topic/com.vmware.wssdk.apiref.doc/virtual_disk_counters.html + List cInfo = perfManagerMO.getCounterInfo(); for (PerfCounterInfo info : cInfo) { if ("virtualdisk".equalsIgnoreCase(info.getGroupInfo().getKey())) { - if ("read".equalsIgnoreCase(info.getNameInfo().getKey())) { - rdReqPerfCounterInfo = info; + if ("numberReadAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) { + diskReadIOPerfCounterInfo = info; + perfCounterKeys.add(info.getKey()); } - if ("write".equalsIgnoreCase(info.getNameInfo().getKey())) { - wtReqPerfCounterInfo = info; + if ("numberWriteAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) { + diskWriteIOPerfCounterInfo = info; + perfCounterKeys.add(info.getKey()); } - if ("readIOSize".equalsIgnoreCase(info.getNameInfo().getKey())) { - rdBytesPerfCounterInfo = info; + if ("read".equalsIgnoreCase(info.getNameInfo().getKey())) { + diskReadKbsPerfCounterInfo = info; + perfCounterKeys.add(info.getKey()); } - if ("writeIOSize".equalsIgnoreCase(info.getNameInfo().getKey())) { - wtBytesPerfCounterInfo = info; + if ("write".equalsIgnoreCase(info.getNameInfo().getKey())) { + diskWriteKbsPerfCounterInfo = info; + perfCounterKeys.add(info.getKey()); } } } @@ -3531,19 +3539,12 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { final VirtualMachineMO vmMo = dcMo.findVm(vmName); final List diskStats = new ArrayList<>(); for (VirtualDisk disk : vmMo.getAllDiskDevice()) { - // TODO verify if the UUID, PATH of VirtualDisk is correct - String diskUuid = disk.getVDiskId().getId(); - - final ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, diskUuid); final ArrayList diskMetricsIds = new ArrayList(); - final List perfMetrics = service.queryAvailablePerfMetric(perfMgr, morDs, null, null, null); + final List perfMetrics = service.queryAvailablePerfMetric(perfMgr, vmMo.getMor(), null, null, null); if (perfMetrics != null) { - for (int index = 0; index < perfMetrics.size(); ++index) { - if (((rdReqPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == rdReqPerfCounterInfo.getKey())) - || ((rdBytesPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == rdBytesPerfCounterInfo.getKey())) - || ((wtReqPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == wtReqPerfCounterInfo.getKey())) - || ((wtBytesPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == wtBytesPerfCounterInfo.getKey()))) { - diskMetricsIds.add(perfMetrics.get(index)); + for (PerfMetricId perfMetricId : perfMetrics) { + if (perfCounterKeys.contains(perfMetricId.getCounterId())) { + diskMetricsIds.add(perfMetricId); } } } @@ -3555,7 +3556,7 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { if (diskMetricsIds.size() != 0) { final PerfQuerySpec qSpec = new PerfQuerySpec(); - qSpec.setEntity(morDs); + qSpec.setEntity(vmMo.getMor()); final PerfMetricId[] availableMetricIds = diskMetricsIds.toArray(new PerfMetricId[0]); qSpec.getMetricId().addAll(Arrays.asList(availableMetricIds)); final List qSpecs = new ArrayList(); @@ -3567,26 +3568,26 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { if (value instanceof PerfMetricIntSeries) { List valIntSeries = ((PerfMetricIntSeries)value).getValue(); if (valIntSeries.size() > 0) { - long averageVal = 0; + long sumVal = 0; for (long val : valIntSeries) { - averageVal += val; + sumVal += val; } - averageVal /= valIntSeries.size(); - if (value.getId().getCounterId() == rdReqPerfCounterInfo.getKey()) { - readReq = averageVal; - } else if (value.getId().getCounterId() == rdBytesPerfCounterInfo.getKey()) { - readBytes = averageVal; - } else if (value.getId().getCounterId() == wtReqPerfCounterInfo.getKey()) { - writeReq = averageVal; - } else if (value.getId().getCounterId() == wtBytesPerfCounterInfo.getKey()) { - writeBytes = averageVal; + //sumVal /= valIntSeries.size(); + if (value.getId().getCounterId() == diskReadIOPerfCounterInfo.getKey()) { + readReq = sumVal; + } else if (value.getId().getCounterId() == diskWriteIOPerfCounterInfo.getKey()) { + readBytes = sumVal; + } else if (value.getId().getCounterId() == diskReadKbsPerfCounterInfo.getKey()) { + writeReq = sumVal; + } else if (value.getId().getCounterId() == diskWriteKbsPerfCounterInfo.getKey()) { + writeBytes = sumVal; } } } } } } - diskStats.add(new VmDiskStatsEntry(vmName, diskUuid, writeReq, readReq, writeBytes, readBytes)); + diskStats.add(new VmDiskStatsEntry(vmName, VmwareHelper.getDiskDeviceFileName(disk), writeReq, readReq, writeBytes, readBytes)); } if (diskStats.size() > 0) { vmStatsMap.put(vmName, diskStats); @@ -5988,15 +5989,41 @@ private HashMap getVmStats(List vmNames) throws Ex VimPortType service = getServiceContext().getService(); PerfCounterInfo rxPerfCounterInfo = null; PerfCounterInfo txPerfCounterInfo = null; + PerfCounterInfo diskReadIOPerfCounterInfo = null; + PerfCounterInfo diskWriteIOPerfCounterInfo = null; + PerfCounterInfo diskReadKbsPerfCounterInfo = null; + PerfCounterInfo diskWriteKbsPerfCounterInfo = null; + List perfCounterKeys = new ArrayList<>(); List cInfo = getServiceContext().getVimClient().getDynamicProperty(perfMgr, "perfCounter"); for (PerfCounterInfo info : cInfo) { + if ("net".equalsIgnoreCase(info.getGroupInfo().getKey())) { if ("transmitted".equalsIgnoreCase(info.getNameInfo().getKey())) { txPerfCounterInfo = info; + perfCounterKeys.add(info.getKey()); } if ("received".equalsIgnoreCase(info.getNameInfo().getKey())) { rxPerfCounterInfo = info; + perfCounterKeys.add(info.getKey()); + } + } + if ("virtualdisk".equalsIgnoreCase(info.getGroupInfo().getKey())) { + if ("numberReadAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) { + diskReadIOPerfCounterInfo = info; + perfCounterKeys.add(info.getKey()); + } + if ("numberWriteAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) { + diskWriteIOPerfCounterInfo = info; + perfCounterKeys.add(info.getKey()); + } + if ("read".equalsIgnoreCase(info.getNameInfo().getKey())) { + diskReadKbsPerfCounterInfo = info; + perfCounterKeys.add(info.getKey()); + } + if ("write".equalsIgnoreCase(info.getNameInfo().getKey())) { + diskWriteKbsPerfCounterInfo = info; + perfCounterKeys.add(info.getKey()); } } } @@ -6015,7 +6042,7 @@ private HashMap getVmStats(List vmNames) throws Ex final String allocatedCpuStr = "summary.runtime.maxCpuUsage"; ObjectContent[] ocs = - hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", numCpuStr, cpuUseStr ,guestMemUseStr ,memLimitStr ,memMbStr,allocatedCpuStr ,instanceNameCustomField}); + hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", numCpuStr, cpuUseStr, guestMemUseStr, memLimitStr, memMbStr,allocatedCpuStr, instanceNameCustomField}); if (ocs != null && ocs.length > 0) { for (ObjectContent oc : ocs) { @@ -6036,7 +6063,7 @@ private HashMap getVmStats(List vmNames) throws Ex } else if (objProp.getName().contains(instanceNameCustomField)) { if (objProp.getVal() != null) vmInternalCSName = ((CustomFieldStringValue)objProp.getVal()).getValue(); - } else if (objProp.getName().equals(guestMemusage)) { + } else if (objProp.getName().equals(guestMemUseStr)) { guestMemusage = objProp.getVal().toString(); } else if (objProp.getName().equals(numCpuStr)) { numberCPUs = objProp.getVal().toString(); @@ -6066,60 +6093,81 @@ private HashMap getVmStats(List vmNames) throws Ex ManagedObjectReference vmMor = hyperHost.findVmOnHyperHost(name).getMor(); assert (vmMor != null); - ArrayList vmNetworkMetrics = new ArrayList(); + ArrayList perfMetricIds = new ArrayList(); // get all the metrics from the available sample period List perfMetrics = service.queryAvailablePerfMetric(perfMgr, vmMor, null, null, null); if (perfMetrics != null) { - for (int index = 0; index < perfMetrics.size(); ++index) { - if (((rxPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == rxPerfCounterInfo.getKey())) - || ((txPerfCounterInfo != null) && (perfMetrics.get(index).getCounterId() == txPerfCounterInfo.getKey()))) { - vmNetworkMetrics.add(perfMetrics.get(index)); + for (PerfMetricId perfMetricId : perfMetrics) { + int counterId = perfMetricId.getCounterId(); + if (perfCounterKeys.contains(counterId)) { + perfMetricIds.add(perfMetricId); } } } double networkReadKBs = 0; double networkWriteKBs = 0; + double diskReadIops = 0; + double diskWriteIops = 0; + double diskReadKbs = 0; + double diskWriteKbs = 0; long sampleDuration = 0; - if (vmNetworkMetrics.size() != 0) { + if (perfMetricIds.size() != 0) { PerfQuerySpec qSpec = new PerfQuerySpec(); qSpec.setEntity(vmMor); - PerfMetricId[] availableMetricIds = vmNetworkMetrics.toArray(new PerfMetricId[0]); + PerfMetricId[] availableMetricIds = perfMetricIds.toArray(new PerfMetricId[0]); qSpec.getMetricId().addAll(Arrays.asList(availableMetricIds)); List qSpecs = new ArrayList(); qSpecs.add(qSpec); List values = service.queryPerf(perfMgr, qSpecs); - for (int i = 0; i < values.size(); ++i) { - List infos = ((PerfEntityMetric)values.get(i)).getSampleInfo(); + for (PerfEntityMetricBase perfEntityMetricBase : values) { + List infos = ((PerfEntityMetric) perfEntityMetricBase).getSampleInfo(); if (infos != null && infos.size() > 0) { int endMs = infos.get(infos.size() - 1).getTimestamp().getSecond() * 1000 + infos.get(infos.size() - 1).getTimestamp().getMillisecond(); int beginMs = infos.get(0).getTimestamp().getSecond() * 1000 + infos.get(0).getTimestamp().getMillisecond(); sampleDuration = (endMs - beginMs) / 1000; - List vals = ((PerfEntityMetric)values.get(i)).getValue(); - for (int vi = 0; ((vals != null) && (vi < vals.size())); ++vi) { - if (vals.get(vi) instanceof PerfMetricIntSeries) { - PerfMetricIntSeries val = (PerfMetricIntSeries)vals.get(vi); + List vals = ((PerfEntityMetric) perfEntityMetricBase).getValue(); + for (PerfMetricSeries series : vals) { + if (series instanceof PerfMetricIntSeries) { + PerfMetricIntSeries val = (PerfMetricIntSeries) series; List perfValues = val.getValue(); Long sumRate = 0L; for (int j = 0; j < infos.size(); j++) { // Size of the array matches the size as the PerfSampleInfo sumRate += perfValues.get(j); } Long averageRate = sumRate / infos.size(); - if (vals.get(vi).getId().getCounterId() == rxPerfCounterInfo.getKey()) { + if (series.getId().getCounterId() == rxPerfCounterInfo.getKey()) { networkReadKBs = sampleDuration * averageRate; //get the average RX rate multiplied by sampled duration } - if (vals.get(vi).getId().getCounterId() == txPerfCounterInfo.getKey()) { - networkWriteKBs = sampleDuration * averageRate;//get the average TX rate multiplied by sampled duration + if (series.getId().getCounterId() == txPerfCounterInfo.getKey()) { + networkWriteKBs = sampleDuration * averageRate; //get the average TX rate multiplied by sampled duration + } + if (series.getId().getCounterId() == diskReadIOPerfCounterInfo.getKey()) { + diskReadIops += sumRate; + } + if (series.getId().getCounterId() == diskWriteIOPerfCounterInfo.getKey()) { + diskWriteIops += sumRate; + } + if (series.getId().getCounterId() == diskReadKbsPerfCounterInfo.getKey()) { + diskReadKbs += sumRate; + } + if (series.getId().getCounterId() == diskWriteKbsPerfCounterInfo.getKey()) { + diskWriteKbs += sumRate; } } } } } } - vmResponseMap.put(name, new VmStatsEntry( NumberUtils.toDouble(memkb)*1024,NumberUtils.toDouble(guestMemusage)*1024,NumberUtils.toDouble(memlimit)*1024, - maxCpuUsage, networkReadKBs, networkWriteKBs, NumberUtils.toInt(numberCPUs), "vm")); + final VmStatsEntry vmStats = new VmStatsEntry( NumberUtils.toDouble(memkb)*1024,NumberUtils.toDouble(guestMemusage)*1024,NumberUtils.toDouble(memlimit)*1024, + maxCpuUsage, networkReadKBs, networkWriteKBs, NumberUtils.toInt(numberCPUs), "vm"); + vmStats.setDiskReadIOs(diskReadIops); + vmStats.setDiskWriteIOs(diskWriteIops); + vmStats.setDiskReadKBs(diskReadKbs); + vmStats.setDiskWriteKBs(diskWriteKbs); + vmResponseMap.put(name, vmStats); } } diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java index bb7f3c5a140b..00f0fc6952ea 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java @@ -637,6 +637,18 @@ public static VirtualDevice prepareUSBControllerDevice() { return usbController; } + public static String getDiskDeviceFileName(VirtualDisk diskDevice) { + VirtualDeviceBackingInfo backingInfo = diskDevice.getBacking(); + if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) { + final String vmdkName = ((VirtualDiskFlatVer2BackingInfo)backingInfo).getFileName().replace(".vmdk", ""); + if (vmdkName.contains("/")) { + return vmdkName.split("/", 2)[1]; + } + return vmdkName; + } + return null; + } + public static ManagedObjectReference getDiskDeviceDatastore(VirtualDisk diskDevice) throws Exception { VirtualDeviceBackingInfo backingInfo = diskDevice.getBacking(); assert (backingInfo instanceof VirtualDiskFlatVer2BackingInfo); From 05c16852a82a1d10bce53b84e7d549e8adff489f Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Tue, 16 Apr 2019 00:38:36 +0530 Subject: [PATCH 05/10] implement perf counter Signed-off-by: Rohit Yadav --- .../vmware/resource/VmwareResource.java | 44 ++++++++----------- .../vmware/mo/VirtualMachineMO.java | 2 +- .../hypervisor/vmware/util/VmwareHelper.java | 9 ++++ 3 files changed, 29 insertions(+), 26 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 81bad02aaa8f..ea40bb264420 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -209,7 +209,6 @@ import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO; import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper; import com.cloud.hypervisor.vmware.mo.NetworkDetails; -import com.cloud.hypervisor.vmware.mo.PerfManagerMO; import com.cloud.hypervisor.vmware.mo.TaskMO; import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType; import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder; @@ -3499,34 +3498,28 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { try { final VmwareHypervisorHost hyperHost = getHyperHost(getServiceContext()); final ManagedObjectReference perfMgr = getServiceContext().getServiceContent().getPerfManager(); - final PerfManagerMO perfManagerMO = new PerfManagerMO(getServiceContext(), perfMgr); VimPortType service = getServiceContext().getService(); PerfCounterInfo diskReadIOPerfCounterInfo = null; PerfCounterInfo diskWriteIOPerfCounterInfo = null; PerfCounterInfo diskReadKbsPerfCounterInfo = null; PerfCounterInfo diskWriteKbsPerfCounterInfo = null; - List perfCounterKeys = new ArrayList<>(); // https://pubs.vmware.com/vsphere-5-5/topic/com.vmware.wssdk.apiref.doc/virtual_disk_counters.html - List cInfo = perfManagerMO.getCounterInfo(); + List cInfo = getServiceContext().getVimClient().getDynamicProperty(perfMgr, "perfCounter"); for (PerfCounterInfo info : cInfo) { if ("virtualdisk".equalsIgnoreCase(info.getGroupInfo().getKey())) { if ("numberReadAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) { diskReadIOPerfCounterInfo = info; - perfCounterKeys.add(info.getKey()); } if ("numberWriteAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) { diskWriteIOPerfCounterInfo = info; - perfCounterKeys.add(info.getKey()); } if ("read".equalsIgnoreCase(info.getNameInfo().getKey())) { diskReadKbsPerfCounterInfo = info; - perfCounterKeys.add(info.getKey()); } if ("write".equalsIgnoreCase(info.getNameInfo().getKey())) { diskWriteKbsPerfCounterInfo = info; - perfCounterKeys.add(info.getKey()); } } } @@ -3539,30 +3532,31 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { final VirtualMachineMO vmMo = dcMo.findVm(vmName); final List diskStats = new ArrayList<>(); for (VirtualDisk disk : vmMo.getAllDiskDevice()) { - final ArrayList diskMetricsIds = new ArrayList(); - final List perfMetrics = service.queryAvailablePerfMetric(perfMgr, vmMo.getMor(), null, null, null); - if (perfMetrics != null) { - for (PerfMetricId perfMetricId : perfMetrics) { - if (perfCounterKeys.contains(perfMetricId.getCounterId())) { - diskMetricsIds.add(perfMetricId); - } - } - } - + final String diskBusName = vmMo.getDeviceBusName(vmMo.getAllDeviceList(), disk); long readReq = 0; long readBytes = 0; long writeReq = 0; long writeBytes = 0; + final ArrayList diskMetricsIds = new ArrayList(); + if (diskReadIOPerfCounterInfo != null) { + diskMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadIOPerfCounterInfo, diskBusName)); + } + if (diskWriteIOPerfCounterInfo != null) { + diskMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteIOPerfCounterInfo, diskBusName)); + } + if (diskReadKbsPerfCounterInfo != null) { + diskMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadKbsPerfCounterInfo, diskBusName)); + } + if (diskWriteKbsPerfCounterInfo != null) { + diskMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteKbsPerfCounterInfo, diskBusName)); + } + if (diskMetricsIds.size() != 0) { final PerfQuerySpec qSpec = new PerfQuerySpec(); qSpec.setEntity(vmMo.getMor()); - final PerfMetricId[] availableMetricIds = diskMetricsIds.toArray(new PerfMetricId[0]); - qSpec.getMetricId().addAll(Arrays.asList(availableMetricIds)); - final List qSpecs = new ArrayList(); - qSpecs.add(qSpec); - - for (PerfEntityMetricBase perfValue : service.queryPerf(perfMgr, qSpecs)) { + qSpec.getMetricId().addAll(diskMetricsIds); + for (PerfEntityMetricBase perfValue : service.queryPerf(perfMgr, Collections.singletonList(qSpec))) { final List values = ((PerfEntityMetric)perfValue).getValue(); for (PerfMetricSeries value : values) { if (value instanceof PerfMetricIntSeries) { @@ -3572,7 +3566,7 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { for (long val : valIntSeries) { sumVal += val; } - //sumVal /= valIntSeries.size(); + sumVal /= valIntSeries.size(); if (value.getId().getCounterId() == diskReadIOPerfCounterInfo.getKey()) { readReq = sumVal; } else if (value.getId().getCounterId() == diskWriteIOPerfCounterInfo.getKey()) { diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index 52ead5c8535e..fbb1bb1efa0b 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -2709,7 +2709,7 @@ public List> getDiskDatastorePathChain(Virt return pathList; } - private String getDeviceBusName(List allDevices, VirtualDevice theDevice) throws Exception { + public String getDeviceBusName(List allDevices, VirtualDevice theDevice) throws Exception { for (VirtualDevice device : allDevices) { if (device.getKey() == theDevice.getControllerKey().intValue()) { if (device instanceof VirtualIDEController) { diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java index 00f0fc6952ea..103ffc56a2cf 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java @@ -41,6 +41,8 @@ import com.vmware.vim25.MethodFault; import com.vmware.vim25.ObjectContent; import com.vmware.vim25.OptionValue; +import com.vmware.vim25.PerfCounterInfo; +import com.vmware.vim25.PerfMetricId; import com.vmware.vim25.ResourceAllocationInfo; import com.vmware.vim25.VirtualCdrom; import com.vmware.vim25.VirtualCdromIsoBackingInfo; @@ -637,6 +639,13 @@ public static VirtualDevice prepareUSBControllerDevice() { return usbController; } + public static PerfMetricId createPerfMetricId(PerfCounterInfo counterInfo, String instance) { + PerfMetricId metricId = new PerfMetricId(); + metricId.setCounterId(counterInfo.getKey()); + metricId.setInstance(instance); + return metricId; + } + public static String getDiskDeviceFileName(VirtualDisk diskDevice) { VirtualDeviceBackingInfo backingInfo = diskDevice.getBacking(); if (backingInfo instanceof VirtualDiskFlatVer2BackingInfo) { From 68c94f51be1a81ddd1aeff97e80876b62f5de304 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Tue, 16 Apr 2019 15:00:17 +0530 Subject: [PATCH 06/10] fix perf stats gathering wrt both disks and VM Signed-off-by: Rohit Yadav --- .../vmware/resource/VmwareResource.java | 214 ++++++++++-------- .../hypervisor/vmware/util/VmwareHelper.java | 14 ++ 2 files changed, 130 insertions(+), 98 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index ea40bb264420..2b73a1fe42ca 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -42,6 +42,7 @@ import java.util.UUID; import javax.naming.ConfigurationException; +import javax.xml.datatype.XMLGregorianCalendar; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.storage.command.CopyCommand; @@ -281,7 +282,6 @@ import com.vmware.vim25.PerfMetricIntSeries; import com.vmware.vim25.PerfMetricSeries; import com.vmware.vim25.PerfQuerySpec; -import com.vmware.vim25.PerfSampleInfo; import com.vmware.vim25.RuntimeFaultFaultMsg; import com.vmware.vim25.ToolsUnavailableFaultMsg; import com.vmware.vim25.VMwareDVSPortSetting; @@ -3500,6 +3500,10 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { final ManagedObjectReference perfMgr = getServiceContext().getServiceContent().getPerfManager(); VimPortType service = getServiceContext().getService(); + final int intervalSeconds = 300; + final XMLGregorianCalendar startTime = VmwareHelper.getXMLGregorianCalendar(new Date(), intervalSeconds); + final XMLGregorianCalendar endTime = VmwareHelper.getXMLGregorianCalendar(new Date(), 0); + PerfCounterInfo diskReadIOPerfCounterInfo = null; PerfCounterInfo diskWriteIOPerfCounterInfo = null; PerfCounterInfo diskReadKbsPerfCounterInfo = null; @@ -3508,7 +3512,7 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { // https://pubs.vmware.com/vsphere-5-5/topic/com.vmware.wssdk.apiref.doc/virtual_disk_counters.html List cInfo = getServiceContext().getVimClient().getDynamicProperty(perfMgr, "perfCounter"); for (PerfCounterInfo info : cInfo) { - if ("virtualdisk".equalsIgnoreCase(info.getGroupInfo().getKey())) { + if ("virtualdisk".equalsIgnoreCase(info.getGroupInfo().getKey()) && "average".equalsIgnoreCase(info.getRollupType().value())) { if ("numberReadAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) { diskReadIOPerfCounterInfo = info; } @@ -3531,57 +3535,69 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { for (final String vmName : cmd.getVmNames()) { final VirtualMachineMO vmMo = dcMo.findVm(vmName); final List diskStats = new ArrayList<>(); - for (VirtualDisk disk : vmMo.getAllDiskDevice()) { + for (final VirtualDisk disk : vmMo.getAllDiskDevice()) { final String diskBusName = vmMo.getDeviceBusName(vmMo.getAllDeviceList(), disk); long readReq = 0; long readBytes = 0; long writeReq = 0; long writeBytes = 0; - final ArrayList diskMetricsIds = new ArrayList(); + final ArrayList perfMetricsIds = new ArrayList(); if (diskReadIOPerfCounterInfo != null) { - diskMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadIOPerfCounterInfo, diskBusName)); + perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadIOPerfCounterInfo, diskBusName)); } if (diskWriteIOPerfCounterInfo != null) { - diskMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteIOPerfCounterInfo, diskBusName)); + perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteIOPerfCounterInfo, diskBusName)); } if (diskReadKbsPerfCounterInfo != null) { - diskMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadKbsPerfCounterInfo, diskBusName)); + perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadKbsPerfCounterInfo, diskBusName)); } if (diskWriteKbsPerfCounterInfo != null) { - diskMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteKbsPerfCounterInfo, diskBusName)); + perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteKbsPerfCounterInfo, diskBusName)); } - if (diskMetricsIds.size() != 0) { + if (perfMetricsIds.size() > 0) { final PerfQuerySpec qSpec = new PerfQuerySpec(); qSpec.setEntity(vmMo.getMor()); - qSpec.getMetricId().addAll(diskMetricsIds); - for (PerfEntityMetricBase perfValue : service.queryPerf(perfMgr, Collections.singletonList(qSpec))) { + qSpec.setFormat("normal"); + qSpec.setIntervalId(intervalSeconds); + qSpec.setStartTime(startTime); + qSpec.setEndTime(endTime); + qSpec.getMetricId().addAll(perfMetricsIds); + + for (final PerfEntityMetricBase perfValue : service.queryPerf(perfMgr, Collections.singletonList(qSpec))) { + if (!(perfValue instanceof PerfEntityMetric)) { + continue; + } final List values = ((PerfEntityMetric)perfValue).getValue(); - for (PerfMetricSeries value : values) { - if (value instanceof PerfMetricIntSeries) { - List valIntSeries = ((PerfMetricIntSeries)value).getValue(); - if (valIntSeries.size() > 0) { - long sumVal = 0; - for (long val : valIntSeries) { - sumVal += val; - } - sumVal /= valIntSeries.size(); - if (value.getId().getCounterId() == diskReadIOPerfCounterInfo.getKey()) { - readReq = sumVal; - } else if (value.getId().getCounterId() == diskWriteIOPerfCounterInfo.getKey()) { - readBytes = sumVal; - } else if (value.getId().getCounterId() == diskReadKbsPerfCounterInfo.getKey()) { - writeReq = sumVal; - } else if (value.getId().getCounterId() == diskWriteKbsPerfCounterInfo.getKey()) { - writeBytes = sumVal; - } + if (values == null || values.isEmpty()) { + continue; + } + for (final PerfMetricSeries value : values) { + if (!(value instanceof PerfMetricIntSeries) || !value.getId().getInstance().equals(diskBusName)) { + continue; + } + final List perfStats = ((PerfMetricIntSeries)value).getValue(); + if (perfStats.size() > 0) { + long sum = 0; + for (long val : perfStats) { + sum += val; + } + long avg = sum / perfStats.size(); + if (value.getId().getCounterId() == diskReadIOPerfCounterInfo.getKey()) { + readReq = avg; + } else if (value.getId().getCounterId() == diskWriteIOPerfCounterInfo.getKey()) { + writeReq = avg; + } else if (value.getId().getCounterId() == diskReadKbsPerfCounterInfo.getKey()) { + readBytes = avg; + } else if (value.getId().getCounterId() == diskWriteKbsPerfCounterInfo.getKey()) { + writeBytes = avg; } } } } } - diskStats.add(new VmDiskStatsEntry(vmName, VmwareHelper.getDiskDeviceFileName(disk), writeReq, readReq, writeBytes, readBytes)); + diskStats.add(new VmDiskStatsEntry(vmName, VmwareHelper.getDiskDeviceFileName(disk), writeReq, readReq, 1024 * writeBytes, 1024 * readBytes)); } if (diskStats.size() > 0) { vmStatsMap.put(vmName, diskStats); @@ -5981,43 +5997,40 @@ private HashMap getVmStats(List vmNames) throws Ex HashMap vmResponseMap = new HashMap(); ManagedObjectReference perfMgr = getServiceContext().getServiceContent().getPerfManager(); VimPortType service = getServiceContext().getService(); + PerfCounterInfo rxPerfCounterInfo = null; PerfCounterInfo txPerfCounterInfo = null; PerfCounterInfo diskReadIOPerfCounterInfo = null; PerfCounterInfo diskWriteIOPerfCounterInfo = null; PerfCounterInfo diskReadKbsPerfCounterInfo = null; PerfCounterInfo diskWriteKbsPerfCounterInfo = null; - List perfCounterKeys = new ArrayList<>(); + + final int intervalSeconds = 60; + final XMLGregorianCalendar startTime = VmwareHelper.getXMLGregorianCalendar(new Date(), intervalSeconds); + final XMLGregorianCalendar endTime = VmwareHelper.getXMLGregorianCalendar(new Date(), 0); List cInfo = getServiceContext().getVimClient().getDynamicProperty(perfMgr, "perfCounter"); for (PerfCounterInfo info : cInfo) { - - if ("net".equalsIgnoreCase(info.getGroupInfo().getKey())) { + if ("net".equalsIgnoreCase(info.getGroupInfo().getKey()) && "average".equalsIgnoreCase(info.getRollupType().value())) { if ("transmitted".equalsIgnoreCase(info.getNameInfo().getKey())) { txPerfCounterInfo = info; - perfCounterKeys.add(info.getKey()); } if ("received".equalsIgnoreCase(info.getNameInfo().getKey())) { rxPerfCounterInfo = info; - perfCounterKeys.add(info.getKey()); } } if ("virtualdisk".equalsIgnoreCase(info.getGroupInfo().getKey())) { if ("numberReadAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) { diskReadIOPerfCounterInfo = info; - perfCounterKeys.add(info.getKey()); } if ("numberWriteAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) { diskWriteIOPerfCounterInfo = info; - perfCounterKeys.add(info.getKey()); } if ("read".equalsIgnoreCase(info.getNameInfo().getKey())) { diskReadKbsPerfCounterInfo = info; - perfCounterKeys.add(info.getKey()); } if ("write".equalsIgnoreCase(info.getNameInfo().getKey())) { diskWriteKbsPerfCounterInfo = info; - perfCounterKeys.add(info.getKey()); } } } @@ -6035,8 +6048,9 @@ private HashMap getVmStats(List vmNames) throws Ex final String memMbStr = "config.hardware.memoryMB"; final String allocatedCpuStr = "summary.runtime.maxCpuUsage"; - ObjectContent[] ocs = - hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", numCpuStr, cpuUseStr, guestMemUseStr, memLimitStr, memMbStr,allocatedCpuStr, instanceNameCustomField}); + ObjectContent[] ocs = hyperHost.getVmPropertiesOnHyperHost(new String[] { + "name", numCpuStr, cpuUseStr, guestMemUseStr, memLimitStr, memMbStr,allocatedCpuStr, instanceNameCustomField + }); if (ocs != null && ocs.length > 0) { for (ObjectContent oc : ocs) { @@ -6073,7 +6087,6 @@ private HashMap getVmStats(List vmNames) throws Ex } maxCpuUsage = (maxCpuUsage/allocatedCpu)*100; - new VirtualMachineMO(hyperHost.getContext(), oc.getObj()); if (vmInternalCSName != null) { name = vmInternalCSName; } else { @@ -6087,74 +6100,79 @@ private HashMap getVmStats(List vmNames) throws Ex ManagedObjectReference vmMor = hyperHost.findVmOnHyperHost(name).getMor(); assert (vmMor != null); - ArrayList perfMetricIds = new ArrayList(); - // get all the metrics from the available sample period - List perfMetrics = service.queryAvailablePerfMetric(perfMgr, vmMor, null, null, null); - if (perfMetrics != null) { - for (PerfMetricId perfMetricId : perfMetrics) { - int counterId = perfMetricId.getCounterId(); - if (perfCounterKeys.contains(counterId)) { - perfMetricIds.add(perfMetricId); - } - } - } - double networkReadKBs = 0; double networkWriteKBs = 0; double diskReadIops = 0; double diskWriteIops = 0; double diskReadKbs = 0; double diskWriteKbs = 0; - long sampleDuration = 0; - if (perfMetricIds.size() != 0) { - PerfQuerySpec qSpec = new PerfQuerySpec(); + final ArrayList perfMetricsIds = new ArrayList(); + if (rxPerfCounterInfo != null) { + perfMetricsIds.add(VmwareHelper.createPerfMetricId(rxPerfCounterInfo, "*")); + } + if (txPerfCounterInfo != null) { + perfMetricsIds.add(VmwareHelper.createPerfMetricId(txPerfCounterInfo, "*")); + } + if (diskReadIOPerfCounterInfo != null) { + perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadIOPerfCounterInfo, "*")); + } + if (diskWriteIOPerfCounterInfo != null) { + perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteIOPerfCounterInfo, "*")); + } + if (diskReadKbsPerfCounterInfo != null) { + perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadKbsPerfCounterInfo, "*")); + } + if (diskWriteKbsPerfCounterInfo != null) { + perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteKbsPerfCounterInfo, "*")); + } + + if (perfMetricsIds.size() > 0) { + final PerfQuerySpec qSpec = new PerfQuerySpec(); qSpec.setEntity(vmMor); - PerfMetricId[] availableMetricIds = perfMetricIds.toArray(new PerfMetricId[0]); - qSpec.getMetricId().addAll(Arrays.asList(availableMetricIds)); - List qSpecs = new ArrayList(); - qSpecs.add(qSpec); - List values = service.queryPerf(perfMgr, qSpecs); - - for (PerfEntityMetricBase perfEntityMetricBase : values) { - List infos = ((PerfEntityMetric) perfEntityMetricBase).getSampleInfo(); - if (infos != null && infos.size() > 0) { - int endMs = infos.get(infos.size() - 1).getTimestamp().getSecond() * 1000 + infos.get(infos.size() - 1).getTimestamp().getMillisecond(); - int beginMs = infos.get(0).getTimestamp().getSecond() * 1000 + infos.get(0).getTimestamp().getMillisecond(); - sampleDuration = (endMs - beginMs) / 1000; - List vals = ((PerfEntityMetric) perfEntityMetricBase).getValue(); - for (PerfMetricSeries series : vals) { - if (series instanceof PerfMetricIntSeries) { - PerfMetricIntSeries val = (PerfMetricIntSeries) series; - List perfValues = val.getValue(); - Long sumRate = 0L; - for (int j = 0; j < infos.size(); j++) { // Size of the array matches the size as the PerfSampleInfo - sumRate += perfValues.get(j); - } - Long averageRate = sumRate / infos.size(); - if (series.getId().getCounterId() == rxPerfCounterInfo.getKey()) { - networkReadKBs = sampleDuration * averageRate; //get the average RX rate multiplied by sampled duration - } - if (series.getId().getCounterId() == txPerfCounterInfo.getKey()) { - networkWriteKBs = sampleDuration * averageRate; //get the average TX rate multiplied by sampled duration - } - if (series.getId().getCounterId() == diskReadIOPerfCounterInfo.getKey()) { - diskReadIops += sumRate; - } - if (series.getId().getCounterId() == diskWriteIOPerfCounterInfo.getKey()) { - diskWriteIops += sumRate; - } - if (series.getId().getCounterId() == diskReadKbsPerfCounterInfo.getKey()) { - diskReadKbs += sumRate; - } - if (series.getId().getCounterId() == diskWriteKbsPerfCounterInfo.getKey()) { - diskWriteKbs += sumRate; - } - } + qSpec.setFormat("normal"); + qSpec.setIntervalId(intervalSeconds); + qSpec.setStartTime(startTime); + qSpec.setEndTime(endTime); + qSpec.getMetricId().addAll(perfMetricsIds); + final List perfValues = service.queryPerf(perfMgr, Collections.singletonList(qSpec)); + for (final PerfEntityMetricBase perfValue : perfValues) { + if (!(perfValue instanceof PerfEntityMetric)) { + continue; + } + final List seriesList = ((PerfEntityMetric) perfValue).getValue(); + for (final PerfMetricSeries series : seriesList) { + if (!(series instanceof PerfMetricIntSeries)) { + continue; + } + final List values = ((PerfMetricIntSeries) series).getValue(); + double sum = 0; + for (final Long value : values) { + sum += value; + } + double avg = sum / values.size(); + if (series.getId().getCounterId() == rxPerfCounterInfo.getKey()) { + networkReadKBs = avg; + } + if (series.getId().getCounterId() == txPerfCounterInfo.getKey()) { + networkWriteKBs = avg; + } + if (series.getId().getCounterId() == diskReadIOPerfCounterInfo.getKey()) { + diskReadIops = avg; + } + if (series.getId().getCounterId() == diskWriteIOPerfCounterInfo.getKey()) { + diskWriteIops = avg; + } + if (series.getId().getCounterId() == diskReadKbsPerfCounterInfo.getKey()) { + diskReadKbs = avg; + } + if (series.getId().getCounterId() == diskWriteKbsPerfCounterInfo.getKey()) { + diskWriteKbs = avg; } } } } + final VmStatsEntry vmStats = new VmStatsEntry( NumberUtils.toDouble(memkb)*1024,NumberUtils.toDouble(guestMemusage)*1024,NumberUtils.toDouble(memlimit)*1024, maxCpuUsage, networkReadKBs, networkWriteKBs, NumberUtils.toInt(numberCPUs), "vm"); vmStats.setDiskReadIOs(diskReadIops); diff --git a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java index 103ffc56a2cf..6477eb1ecee1 100644 --- a/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java +++ b/vmware-base/src/main/java/com/cloud/hypervisor/vmware/util/VmwareHelper.java @@ -25,11 +25,16 @@ import java.io.StringWriter; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Date; +import java.util.GregorianCalendar; import java.util.List; import java.util.Random; import java.util.UUID; import javax.annotation.Nonnull; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; @@ -794,4 +799,13 @@ public static boolean isControllerOsRecommended(String dataDiskController) { return DiskControllerType.getType(dataDiskController) == DiskControllerType.osdefault; } + public static XMLGregorianCalendar getXMLGregorianCalendar(final Date date, final int offsetSeconds) throws DatatypeConfigurationException { + if (offsetSeconds > 0) { + date.setTime(date.getTime() - offsetSeconds * 1000); + } + final GregorianCalendar gregorianCalendar = new GregorianCalendar(); + gregorianCalendar.setTime(date); + return DatatypeFactory.newInstance().newXMLGregorianCalendar(gregorianCalendar); + } + } From df251461518eb8244707293d9a96858584bdf330 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Tue, 16 Apr 2019 15:07:46 +0530 Subject: [PATCH 07/10] use only series for the vm instance name as counter instance name Signed-off-by: Rohit Yadav --- .../vmware/resource/VmwareResource.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 2b73a1fe42ca..2e894042d0b1 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -3589,15 +3589,15 @@ protected Answer execute(GetVmDiskStatsCommand cmd) { } else if (value.getId().getCounterId() == diskWriteIOPerfCounterInfo.getKey()) { writeReq = avg; } else if (value.getId().getCounterId() == diskReadKbsPerfCounterInfo.getKey()) { - readBytes = avg; + readBytes = avg * 1024; } else if (value.getId().getCounterId() == diskWriteKbsPerfCounterInfo.getKey()) { - writeBytes = avg; + writeBytes = avg * 1024; } } } } } - diskStats.add(new VmDiskStatsEntry(vmName, VmwareHelper.getDiskDeviceFileName(disk), writeReq, readReq, 1024 * writeBytes, 1024 * readBytes)); + diskStats.add(new VmDiskStatsEntry(vmName, VmwareHelper.getDiskDeviceFileName(disk), writeReq, readReq, writeBytes, readBytes)); } if (diskStats.size() > 0) { vmStatsMap.put(vmName, diskStats); @@ -6005,7 +6005,7 @@ private HashMap getVmStats(List vmNames) throws Ex PerfCounterInfo diskReadKbsPerfCounterInfo = null; PerfCounterInfo diskWriteKbsPerfCounterInfo = null; - final int intervalSeconds = 60; + final int intervalSeconds = 300; final XMLGregorianCalendar startTime = VmwareHelper.getXMLGregorianCalendar(new Date(), intervalSeconds); final XMLGregorianCalendar endTime = VmwareHelper.getXMLGregorianCalendar(new Date(), 0); @@ -6109,10 +6109,10 @@ private HashMap getVmStats(List vmNames) throws Ex final ArrayList perfMetricsIds = new ArrayList(); if (rxPerfCounterInfo != null) { - perfMetricsIds.add(VmwareHelper.createPerfMetricId(rxPerfCounterInfo, "*")); + perfMetricsIds.add(VmwareHelper.createPerfMetricId(rxPerfCounterInfo, "")); } if (txPerfCounterInfo != null) { - perfMetricsIds.add(VmwareHelper.createPerfMetricId(txPerfCounterInfo, "*")); + perfMetricsIds.add(VmwareHelper.createPerfMetricId(txPerfCounterInfo, "")); } if (diskReadIOPerfCounterInfo != null) { perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadIOPerfCounterInfo, "*")); @@ -6121,10 +6121,10 @@ private HashMap getVmStats(List vmNames) throws Ex perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteIOPerfCounterInfo, "*")); } if (diskReadKbsPerfCounterInfo != null) { - perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadKbsPerfCounterInfo, "*")); + perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadKbsPerfCounterInfo, "")); } if (diskWriteKbsPerfCounterInfo != null) { - perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteKbsPerfCounterInfo, "*")); + perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteKbsPerfCounterInfo, "")); } if (perfMetricsIds.size() > 0) { @@ -6158,10 +6158,10 @@ private HashMap getVmStats(List vmNames) throws Ex networkWriteKBs = avg; } if (series.getId().getCounterId() == diskReadIOPerfCounterInfo.getKey()) { - diskReadIops = avg; + diskReadIops += avg; } if (series.getId().getCounterId() == diskWriteIOPerfCounterInfo.getKey()) { - diskWriteIops = avg; + diskWriteIops += avg; } if (series.getId().getCounterId() == diskReadKbsPerfCounterInfo.getKey()) { diskReadKbs = avg; From 07c5d1b9d482a2c111b43e8b15b6a837b43a7a4a Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Wed, 17 Apr 2019 13:10:00 +0530 Subject: [PATCH 08/10] Update CitrixGetVmDiskStatsCommandWrapper.java --- .../wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java index 7e0124d4e04e..d15e0a717275 100644 --- a/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java +++ b/plugins/hypervisors/xenserver/src/main/java/com/cloud/hypervisor/xenserver/resource/wrapper/xenbase/CitrixGetVmDiskStatsCommandWrapper.java @@ -31,7 +31,6 @@ public final class CitrixGetVmDiskStatsCommandWrapper extends CommandWrapper Date: Wed, 17 Apr 2019 13:10:36 +0530 Subject: [PATCH 09/10] Update StatsCollector.java --- server/src/main/java/com/cloud/server/StatsCollector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/main/java/com/cloud/server/StatsCollector.java b/server/src/main/java/com/cloud/server/StatsCollector.java index d5ae511b5f20..933379e96f09 100644 --- a/server/src/main/java/com/cloud/server/StatsCollector.java +++ b/server/src/main/java/com/cloud/server/StatsCollector.java @@ -689,7 +689,7 @@ public void doInTransactionWithoutResult(TransactionStatus status) { s_logger.debug("VmDiskStatsTask is running..."); SearchCriteria sc = createSearchCriteriaForHostTypeRoutingStateUpAndNotInMaintenance(); - sc.addAnd("hypervisorType", SearchCriteria.Op.IN, HypervisorType.KVM, HypervisorType.VMware); // TODO: Support VMware support KVM only util 2013.06.25 + sc.addAnd("hypervisorType", SearchCriteria.Op.IN, HypervisorType.KVM, HypervisorType.VMware); List hosts = _hostDao.search(sc, null); for (HostVO host : hosts) { From 80dcb4b85a3716283d4e1ce2d537cf9a7c32bb97 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Wed, 17 Apr 2019 13:11:22 +0530 Subject: [PATCH 10/10] Update UserVmManagerImpl.java --- server/src/main/java/com/cloud/vm/UserVmManagerImpl.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index 1dc38b164d83..7e37c19cd106 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -4612,8 +4612,7 @@ public UserVm destroyVm(long vmId, boolean expunge) throws ResourceUnavailableEx @Override public void collectVmDiskStatistics(final UserVm userVm) { - // support KVM only util 2013.06.25 - // TODO: Implement support for VMware? + // Only supported for KVM and VMware if (!(userVm.getHypervisorType().equals(HypervisorType.KVM) || userVm.getHypervisorType().equals(HypervisorType.VMware))) { return; } @@ -6623,4 +6622,4 @@ private void deleteVolumesFromVm(List volumes) { } } } -} \ No newline at end of file +}