This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/master by this push:
     new 14bff7b  server: export granular volume bytes and iops metrics (#3259)
14bff7b is described below

commit 14bff7bd034a5697c50a6755c420f121d8a58754
Author: Rohit Yadav <rohit.ya...@shapeblue.com>
AuthorDate: Thu Jun 27 09:18:10 2019 +0530

    server: export granular volume bytes and iops metrics (#3259)
    
    Problem: The VM metrics has aggregated volume bytes read/write and iops 
metrics but not on per volume basis.
    Root Cause: The volume stats sub-system is not used to export the metrics, 
the support is not available for VMware.
    Solution: Use the volume stats sub-system and DB table to export the 
metrics via the listVolumes and listVolumeMetrics API, and implement support 
for VMware and fix issue with network and disk metrics in the VM metrics view.
    
    Signed-off-by: Rohit Yadav <rohit.ya...@shapeblue.com>
---
 .../org/apache/cloudstack/api/ApiConstants.java    |   5 +
 .../cloudstack/api/response/UserVmResponse.java    |   8 +-
 .../cloudstack/api/response/VolumeResponse.java    |  65 +++-
 .../hypervisor/vmware/resource/VmwareResource.java | 386 +++++++++++++++------
 .../CitrixGetVmDiskStatsCommandWrapper.java        |   2 +-
 .../cloudstack/metrics/MetricsServiceImpl.java     |  65 ++--
 .../cloudstack/response/VmMetricsResponse.java     |   9 +-
 .../cloudstack/response/VolumeMetricsResponse.java |  14 +-
 .../com/cloud/api/query/dao/VolumeJoinDaoImpl.java |  12 +
 .../main/java/com/cloud/server/StatsCollector.java |   4 +-
 .../main/java/com/cloud/vm/UserVmManagerImpl.java  |   6 +-
 ui/scripts/metrics.js                              |  15 +
 .../hypervisor/vmware/mo/VirtualMachineMO.java     |   2 +-
 .../cloud/hypervisor/vmware/util/VmwareHelper.java |  35 ++
 14 files changed, 461 insertions(+), 167 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 7502b18..3c1d7bb 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 bbf6b6c..8a2f1a1 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 d845e41..01d2c9b 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 class VolumeResponse extends 
BaseResponseWithTagInformation implements Co
         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 3d6732c..c195712 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,68 +42,7 @@ import java.util.TimeZone;
 import java.util.UUID;
 
 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 javax.xml.datatype.XMLGregorianCalendar;
 
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.storage.command.CopyCommand;
@@ -114,6 +53,11 @@ import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
 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 +155,7 @@ import com.cloud.agent.api.UnregisterVMCommand;
 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 +255,60 @@ import com.cloud.vm.VirtualMachine;
 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.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);
@@ -3469,6 +3468,120 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
     }
 
     protected Answer execute(GetVmDiskStatsCommand cmd) {
+        try {
+            final VmwareHypervisorHost hyperHost = 
getHyperHost(getServiceContext());
+            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;
+            PerfCounterInfo diskWriteKbsPerfCounterInfo = null;
+
+            // 
https://pubs.vmware.com/vsphere-5-5/topic/com.vmware.wssdk.apiref.doc/virtual_disk_counters.html
+            List<PerfCounterInfo> cInfo = 
getServiceContext().getVimClient().getDynamicProperty(perfMgr, "perfCounter");
+            for (PerfCounterInfo info : cInfo) {
+                if 
("virtualdisk".equalsIgnoreCase(info.getGroupInfo().getKey()) && 
"average".equalsIgnoreCase(info.getRollupType().value())) {
+                    if 
("numberReadAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) {
+                        diskReadIOPerfCounterInfo = info;
+                    }
+                    if 
("numberWriteAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) {
+                        diskWriteIOPerfCounterInfo = info;
+                    }
+                    if ("read".equalsIgnoreCase(info.getNameInfo().getKey())) {
+                        diskReadKbsPerfCounterInfo = info;
+                    }
+                    if ("write".equalsIgnoreCase(info.getNameInfo().getKey())) 
{
+                        diskWriteKbsPerfCounterInfo = info;
+                    }
+                }
+            }
+
+            final ManagedObjectReference dcMor = 
hyperHost.getHyperHostDatacenter();
+            final DatacenterMO dcMo = new DatacenterMO(getServiceContext(), 
dcMor);
+
+            final HashMap<String, List<VmDiskStatsEntry>> vmStatsMap = new 
HashMap<>();
+            for (final String vmName : cmd.getVmNames()) {
+                final VirtualMachineMO vmMo = dcMo.findVm(vmName);
+                final List<VmDiskStatsEntry> diskStats = new ArrayList<>();
+                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<PerfMetricId> perfMetricsIds = new 
ArrayList<PerfMetricId>();
+                    if (diskReadIOPerfCounterInfo != null) {
+                        
perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadIOPerfCounterInfo, 
diskBusName));
+                    }
+                    if (diskWriteIOPerfCounterInfo != null) {
+                        
perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteIOPerfCounterInfo, 
diskBusName));
+                    }
+                    if (diskReadKbsPerfCounterInfo != null) {
+                        
perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskReadKbsPerfCounterInfo, 
diskBusName));
+                    }
+                    if (diskWriteKbsPerfCounterInfo != null) {
+                        
perfMetricsIds.add(VmwareHelper.createPerfMetricId(diskWriteKbsPerfCounterInfo, 
diskBusName));
+                    }
+
+                    if (perfMetricsIds.size() > 0) {
+                        final PerfQuerySpec qSpec = new PerfQuerySpec();
+                        qSpec.setEntity(vmMo.getMor());
+                        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<PerfMetricSeries> values = 
((PerfEntityMetric)perfValue).getValue();
+                            if (values == null || values.isEmpty()) {
+                                continue;
+                            }
+                            for (final PerfMetricSeries value : values) {
+                                if (!(value instanceof PerfMetricIntSeries) || 
!value.getId().getInstance().equals(diskBusName)) {
+                                    continue;
+                                }
+                                final List<Long> 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 * 1024;
+                                    } else if (value.getId().getCounterId() == 
diskWriteKbsPerfCounterInfo.getKey()) {
+                                        writeBytes = avg * 1024;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    diskStats.add(new VmDiskStatsEntry(vmName, 
VmwareHelper.getDiskDeviceFileName(disk), 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);
     }
 
@@ -5857,12 +5970,21 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
         HashMap<String, VmStatsEntry> vmResponseMap = new HashMap<String, 
VmStatsEntry>();
         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;
+
+        final int intervalSeconds = 300;
+        final XMLGregorianCalendar startTime = 
VmwareHelper.getXMLGregorianCalendar(new Date(), intervalSeconds);
+        final XMLGregorianCalendar endTime = 
VmwareHelper.getXMLGregorianCalendar(new Date(), 0);
 
         List<PerfCounterInfo> 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;
                 }
@@ -5870,6 +5992,20 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                     rxPerfCounterInfo = info;
                 }
             }
+            if ("virtualdisk".equalsIgnoreCase(info.getGroupInfo().getKey())) {
+                if 
("numberReadAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) {
+                    diskReadIOPerfCounterInfo = info;
+                }
+                if 
("numberWriteAveraged".equalsIgnoreCase(info.getNameInfo().getKey())) {
+                    diskWriteIOPerfCounterInfo = info;
+                }
+                if ("read".equalsIgnoreCase(info.getNameInfo().getKey())) {
+                    diskReadKbsPerfCounterInfo = info;
+                }
+                if ("write".equalsIgnoreCase(info.getNameInfo().getKey())) {
+                    diskWriteKbsPerfCounterInfo = info;
+                }
+            }
         }
 
         int key = ((HostMO)hyperHost).getCustomFieldKey("VirtualMachine", 
CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
@@ -5885,8 +6021,9 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
         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) {
@@ -5923,7 +6060,6 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                     }
 
                     maxCpuUsage = (maxCpuUsage/allocatedCpu)*100;
-                    new VirtualMachineMO(hyperHost.getContext(), oc.getObj());
                     if (vmInternalCSName != null) {
                         name = vmInternalCSName;
                     } else {
@@ -5937,60 +6073,86 @@ public class VmwareResource implements 
StoragePoolResource, ServerResource, Vmwa
                     ManagedObjectReference vmMor = 
hyperHost.findVmOnHyperHost(name).getMor();
                     assert (vmMor != null);
 
-                    ArrayList<PerfMetricId> vmNetworkMetrics = new 
ArrayList<PerfMetricId>();
-                    // get all the metrics from the available sample period
-                    List<PerfMetricId> 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));
-                            }
-                        }
-                    }
-
                     double networkReadKBs = 0;
                     double networkWriteKBs = 0;
-                    long sampleDuration = 0;
+                    double diskReadIops = 0;
+                    double diskWriteIops = 0;
+                    double diskReadKbs = 0;
+                    double diskWriteKbs = 0;
+
+                    final ArrayList<PerfMetricId> perfMetricsIds = new 
ArrayList<PerfMetricId>();
+                    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 (vmNetworkMetrics.size() != 0) {
-                        PerfQuerySpec qSpec = new PerfQuerySpec();
+                    if (perfMetricsIds.size() > 0) {
+                        final PerfQuerySpec qSpec = new PerfQuerySpec();
                         qSpec.setEntity(vmMor);
-                        PerfMetricId[] availableMetricIds = 
vmNetworkMetrics.toArray(new PerfMetricId[0]);
-                        
qSpec.getMetricId().addAll(Arrays.asList(availableMetricIds));
-                        List<PerfQuerySpec> qSpecs = new 
ArrayList<PerfQuerySpec>();
-                        qSpecs.add(qSpec);
-                        List<PerfEntityMetricBase> values = 
service.queryPerf(perfMgr, qSpecs);
-
-                        for (int i = 0; i < values.size(); ++i) {
-                            List<PerfSampleInfo> infos = 
((PerfEntityMetric)values.get(i)).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<PerfMetricSeries> 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<Long> 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()) {
-                                            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
-                                        }
-                                    }
+                        qSpec.setFormat("normal");
+                        qSpec.setIntervalId(intervalSeconds);
+                        qSpec.setStartTime(startTime);
+                        qSpec.setEndTime(endTime);
+                        qSpec.getMetricId().addAll(perfMetricsIds);
+                        final List<PerfEntityMetricBase> perfValues = 
service.queryPerf(perfMgr, Collections.singletonList(qSpec));
+                        for (final PerfEntityMetricBase perfValue : 
perfValues) {
+                            if (!(perfValue instanceof PerfEntityMetric)) {
+                                continue;
+                            }
+                            final List<PerfMetricSeries> seriesList = 
((PerfEntityMetric) perfValue).getValue();
+                            for (final PerfMetricSeries series : seriesList) {
+                                if (!(series instanceof PerfMetricIntSeries)) {
+                                    continue;
+                                }
+                                final List<Long> 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;
                                 }
                             }
                         }
                     }
-                    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/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 04090ce..d15e0a7 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
@@ -33,4 +33,4 @@ public final class CitrixGetVmDiskStatsCommandWrapper extends 
CommandWrapper<Get
     public Answer execute(final GetVmDiskStatsCommand command, final 
CitrixResourceBase citrixResourceBase) {
         return new GetVmDiskStatsAnswer(command, null, null, null);
     }
-}
\ No newline at end of file
+}
diff --git 
a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
 
b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
index 029d909..9f20fc3 100644
--- 
a/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
+++ 
b/plugins/metrics/src/main/java/org/apache/cloudstack/metrics/MetricsServiceImpl.java
@@ -17,6 +17,39 @@
 
 package org.apache.cloudstack.metrics;
 
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.ListClustersMetricsCmd;
+import org.apache.cloudstack.api.ListHostsMetricsCmd;
+import org.apache.cloudstack.api.ListInfrastructureCmd;
+import org.apache.cloudstack.api.ListStoragePoolsMetricsCmd;
+import org.apache.cloudstack.api.ListVMsMetricsCmd;
+import org.apache.cloudstack.api.ListVolumesMetricsCmd;
+import org.apache.cloudstack.api.ListZonesMetricsCmd;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.ClusterResponse;
+import org.apache.cloudstack.api.response.HostResponse;
+import org.apache.cloudstack.api.response.StoragePoolResponse;
+import org.apache.cloudstack.api.response.UserVmResponse;
+import org.apache.cloudstack.api.response.VolumeResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.response.ClusterMetricsResponse;
+import org.apache.cloudstack.response.HostMetricsResponse;
+import org.apache.cloudstack.response.InfrastructureResponse;
+import org.apache.cloudstack.response.StoragePoolMetricsResponse;
+import org.apache.cloudstack.response.VmMetricsResponse;
+import org.apache.cloudstack.response.VolumeMetricsResponse;
+import org.apache.cloudstack.response.ZoneMetricsResponse;
+import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
+import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
+import org.apache.commons.beanutils.BeanUtils;
+
 import com.cloud.alert.AlertManager;
 import com.cloud.api.ApiDBUtils;
 import com.cloud.api.query.dao.HostJoinDao;
@@ -45,37 +78,6 @@ import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.dao.DomainRouterDao;
 import com.cloud.vm.dao.VMInstanceDao;
-import org.apache.cloudstack.api.ApiErrorCode;
-import org.apache.cloudstack.api.ListClustersMetricsCmd;
-import org.apache.cloudstack.api.ListHostsMetricsCmd;
-import org.apache.cloudstack.api.ListInfrastructureCmd;
-import org.apache.cloudstack.api.ListStoragePoolsMetricsCmd;
-import org.apache.cloudstack.api.ListVMsMetricsCmd;
-import org.apache.cloudstack.api.ListVolumesMetricsCmd;
-import org.apache.cloudstack.api.ListZonesMetricsCmd;
-import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.response.ClusterResponse;
-import org.apache.cloudstack.api.response.HostResponse;
-import org.apache.cloudstack.api.response.StoragePoolResponse;
-import org.apache.cloudstack.api.response.UserVmResponse;
-import org.apache.cloudstack.api.response.VolumeResponse;
-import org.apache.cloudstack.api.response.ZoneResponse;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.response.ClusterMetricsResponse;
-import org.apache.cloudstack.response.HostMetricsResponse;
-import org.apache.cloudstack.response.InfrastructureResponse;
-import org.apache.cloudstack.response.StoragePoolMetricsResponse;
-import org.apache.cloudstack.response.VmMetricsResponse;
-import org.apache.cloudstack.response.VolumeMetricsResponse;
-import org.apache.cloudstack.response.ZoneMetricsResponse;
-import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.commons.beanutils.BeanUtils;
-
-import javax.inject.Inject;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
 
 public class MetricsServiceImpl extends ComponentLifecycleBase implements 
MetricsService {
 
@@ -163,6 +165,7 @@ public class MetricsServiceImpl extends 
ComponentLifecycleBase implements Metric
             }
 
             metricsResponse.setDiskSizeGB(volumeResponse.getSize());
+            metricsResponse.setDiskIopsTotal(volumeResponse.getDiskIORead(), 
volumeResponse.getDiskIOWrite());
             Account account = CallContext.current().getCallingAccount();
             if (accountMgr.isAdmin(account.getAccountId())) {
                 
metricsResponse.setStorageType(volumeResponse.getStorageType(), 
volumeResponse.getVolumeType());
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 a4057ae..4ac388d 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 ef8515f..47d7a7c 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 class VolumeMetricsResponse extends VolumeResponse {
             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 61e9752..c797735 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.VMTemplateHostVO;
 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<VolumeJo
     private ConfigurationDao  _configDao;
     @Inject
     public AccountManager _accountMgr;
+    @Inject
+    private VmDiskStatisticsDao vmDiskStatsDao;
 
     private final SearchBuilder<VolumeJoinVO> volSearch;
 
@@ -102,6 +106,14 @@ public class VolumeJoinDaoImpl extends 
GenericDaoBaseWithTagInformation<VolumeJo
             } 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 7ae7905..b81507a 100644
--- a/server/src/main/java/com/cloud/server/StatsCollector.java
+++ b/server/src/main/java/com/cloud/server/StatsCollector.java
@@ -690,14 +690,14 @@ public class StatsCollector extends ManagerBase 
implements ComponentMethodInterc
                         s_logger.debug("VmDiskStatsTask is running...");
 
                         SearchCriteria<HostVO> 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);
                         List<HostVO> hosts = _hostDao.search(sc, null);
 
                         for (HostVO host : hosts) {
                             List<UserVmVO> vms = 
_userVmDao.listRunningByHostId(host.getId());
                             List<Long> vmIds = new ArrayList<Long>();
 
-                            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 0727a2a..f3731ab 100644
--- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
@@ -4670,8 +4670,8 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
 
     @Override
     public void collectVmDiskStatistics(final UserVm userVm) {
-        // support KVM only util 2013.06.25
-        if (!userVm.getHypervisorType().equals(HypervisorType.KVM)) {
+        // Only supported for KVM and 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");
@@ -6684,4 +6684,4 @@ public class UserVmManagerImpl extends ManagerBase 
implements UserVmManager, Vir
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/ui/scripts/metrics.js b/ui/scripts/metrics.js
index c3c68e1..2784eab 100644
--- a/ui/scripts/metrics.js
+++ b/ui/scripts/metrics.js
@@ -607,6 +607,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) {
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 d9d03d1..6a42f7f 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 class VirtualMachineMO extends BaseMO {
         return pathList;
     }
 
-    private String getDeviceBusName(List<VirtualDevice> allDevices, 
VirtualDevice theDevice) throws Exception {
+    public String getDeviceBusName(List<VirtualDevice> 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 bb7f3c5..6477eb1 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.PrintWriter;
 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;
@@ -41,6 +46,8 @@ import com.vmware.vim25.ManagedObjectReference;
 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 +644,25 @@ public class VmwareHelper {
         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) {
+            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);
@@ -773,4 +799,13 @@ public class VmwareHelper {
         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);
+    }
+
 }

Reply via email to