Skip to content

Commit dc0ba6b

Browse files
committed
Merge pull request #780 from maneesha-p/pull-19
CLOUDSTACK-8800 : Improved the listVirtualMachines API call to include memory utilization information for a VMfor xenserver,kvm and for vmware. * pr/780: CLOUDSTACK-8800 : Improved the listVirtualMachines API call to include memory utilization information for a VM for xenserver,kvm and for vmware. Signed-off-by: Kishan Kavala <kishan@apache.org>
2 parents 63f58dd + 732a852 commit dc0ba6b

File tree

10 files changed

+148
-13
lines changed

10 files changed

+148
-13
lines changed

api/src/com/cloud/vm/VmStats.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,10 @@ public interface VmStats {
3232

3333
public double getDiskWriteKBs();
3434

35+
public double getMemoryKBs();
36+
37+
public double getIntFreeMemoryKBs();
38+
39+
public double getTargetMemoryKBs();
40+
3541
}

api/src/org/apache/cloudstack/api/response/UserVmResponse.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,18 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp
196196
@Param(description = "the write (bytes) of disk on the vm")
197197
private Long diskKbsWrite;
198198

199+
@SerializedName("memorykbs")
200+
@Param(description = "the memory used by the vm")
201+
private Long memoryKBs;
202+
203+
@SerializedName("memoryintfreekbs")
204+
@Param(description = "the internal memory thats free in vm")
205+
private Long memoryIntFreeKBs;
206+
207+
@SerializedName("memorytargetkbs")
208+
@Param(description = "the target memory in vm")
209+
private Long memoryTargetKBs;
210+
199211
@SerializedName("diskioread")
200212
@Param(description = "the read (io) of disk on the vm")
201213
private Long diskIORead;
@@ -466,6 +478,18 @@ public Long getDiskKbsWrite() {
466478
return diskKbsWrite;
467479
}
468480

481+
public Long getMemoryKBs() {
482+
return memoryKBs;
483+
}
484+
485+
public Long getMemoryIntFreeKBs() {
486+
return memoryIntFreeKBs;
487+
}
488+
489+
public Long getMemoryTargetKBs() {
490+
return memoryTargetKBs;
491+
}
492+
469493
public Long getDiskIORead() {
470494
return diskIORead;
471495
}
@@ -645,6 +669,18 @@ public void setDiskIORead(Long diskIORead) {
645669
this.diskIORead = diskIORead;
646670
}
647671

672+
public void setMemoryKBs(Long memoryKBs) {
673+
this.memoryKBs = memoryKBs;
674+
}
675+
676+
public void setMemoryIntFreeKBs(Long memoryIntFreeKBs) {
677+
this.memoryIntFreeKBs = memoryIntFreeKBs;
678+
}
679+
680+
public void setMemoryTargetKBs(Long memoryTargetKBs) {
681+
this.memoryTargetKBs = memoryTargetKBs;
682+
}
683+
648684
public void setDiskIOWrite(Long diskIOWrite) {
649685
this.diskIOWrite = diskIOWrite;
650686
}

core/src/com/cloud/agent/api/VmStatsEntry.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,19 @@ public class VmStatsEntry implements VmStats {
3030
double diskWriteIOs;
3131
double diskReadKBs;
3232
double diskWriteKBs;
33+
double memoryKBs;
34+
double intfreememoryKBs;
35+
double targetmemoryKBs;
3336
int numCPUs;
3437
String entityType;
3538

3639
public VmStatsEntry() {
3740
}
3841

39-
public VmStatsEntry(double cpuUtilization, double networkReadKBs, double networkWriteKBs, int numCPUs, String entityType) {
42+
public VmStatsEntry(double memoryKBs,double intfreememoryKBs,double targetmemoryKBs, double cpuUtilization, double networkReadKBs, double networkWriteKBs, int numCPUs, String entityType) {
43+
this.memoryKBs = memoryKBs;
44+
this.intfreememoryKBs = intfreememoryKBs;
45+
this.targetmemoryKBs = targetmemoryKBs;
4046
this.cpuUtilization = cpuUtilization;
4147
this.networkReadKBs = networkReadKBs;
4248
this.networkWriteKBs = networkWriteKBs;
@@ -117,6 +123,33 @@ public void setDiskWriteKBs(double diskWriteKBs) {
117123
this.diskWriteKBs = diskWriteKBs;
118124
}
119125

126+
@Override
127+
public double getMemoryKBs() {
128+
return memoryKBs;
129+
}
130+
131+
public void setMemoryKBs(double memoryKBs) {
132+
this.memoryKBs = memoryKBs;
133+
}
134+
135+
@Override
136+
public double getIntFreeMemoryKBs() {
137+
return intfreememoryKBs;
138+
}
139+
140+
public void setIntFreeMemoryKBs(double intfreememoryKBs) {
141+
this.intfreememoryKBs = intfreememoryKBs;
142+
}
143+
144+
@Override
145+
public double getTargetMemoryKBs() {
146+
return targetmemoryKBs;
147+
}
148+
149+
public void setTargetMemoryKBs(double targetmemoryKBs) {
150+
this.targetmemoryKBs = targetmemoryKBs;
151+
}
152+
120153
public int getNumCPUs() {
121154
return numCPUs;
122155
}

plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java

100755100644
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import org.libvirt.Domain;
5858
import org.libvirt.DomainBlockStats;
5959
import org.libvirt.DomainInfo;
60+
import org.libvirt.MemoryStatistic;
6061
import org.libvirt.DomainInfo.DomainState;
6162
import org.libvirt.DomainInterfaceStats;
6263
import org.libvirt.LibvirtException;
@@ -190,6 +191,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
190191
private long _hvVersion;
191192
private long _kernelVersion;
192193
private int _timeout;
194+
private static final int NUMMEMSTATS =2;
193195

194196
private KVMHAMonitor _monitor;
195197
public static final String SSHKEYSPATH = "/root/.ssh";
@@ -3018,6 +3020,9 @@ private class VmStats {
30183020
long _ioWrote;
30193021
long _bytesRead;
30203022
long _bytesWrote;
3023+
long _intmemfree;
3024+
long _memory;
3025+
long _maxmemory;
30213026
Calendar _timestamp;
30223027
}
30233028

@@ -3026,11 +3031,16 @@ public VmStatsEntry getVmStat(final Connect conn, final String vmName) throws Li
30263031
try {
30273032
dm = getDomain(conn, vmName);
30283033
final DomainInfo info = dm.getInfo();
3034+
final MemoryStatistic[] mems = dm.memoryStats(NUMMEMSTATS); //number of memory statistics required.
30293035

30303036
final VmStatsEntry stats = new VmStatsEntry();
3037+
30313038
stats.setNumCPUs(info.nrVirtCpu);
30323039
stats.setEntityType("vm");
30333040

3041+
stats.setMemoryKBs(info.maxMem);
3042+
stats.setTargetMemoryKBs(info.memory);
3043+
stats.setIntFreeMemoryKBs((double) mems[0].getValue());
30343044
/* get cpu utilization */
30353045
VmStats oldStats = null;
30363046

@@ -3115,6 +3125,9 @@ public VmStatsEntry getVmStat(final Connect conn, final String vmName) throws Li
31153125
newStat._bytesRead = bytes_rd;
31163126
newStat._bytesWrote = bytes_wr;
31173127
newStat._timestamp = now;
3128+
newStat._intmemfree = mems[0].getValue();
3129+
newStat._memory = info.memory;
3130+
newStat._maxmemory = info.maxMem;
31183131
_vmStats.put(vmName, newStat);
31193132
return stats;
31203133
} finally {

plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@
6666
import org.libvirt.LibvirtException;
6767
import org.libvirt.NodeInfo;
6868
import org.libvirt.StorageVol;
69+
import org.libvirt.MemoryStatistic;
70+
6971
import org.mockito.Matchers;
7072
import org.mockito.Mock;
7173
import org.mockito.Mockito;
@@ -417,7 +419,10 @@ public void testGetVmStat() throws LibvirtException {
417419
final Connect connect = Mockito.mock(Connect.class);
418420
final Domain domain = Mockito.mock(Domain.class);
419421
final DomainInfo domainInfo = new DomainInfo();
422+
final MemoryStatistic[] domainMem = new MemoryStatistic[2];
423+
domainMem[0] = Mockito.mock(MemoryStatistic.class);
420424
Mockito.when(domain.getInfo()).thenReturn(domainInfo);
425+
Mockito.when(domain.memoryStats(2)).thenReturn(domainMem);
421426
Mockito.when(connect.domainLookupByName(VMNAME)).thenReturn(domain);
422427
final NodeInfo nodeInfo = new NodeInfo();
423428
nodeInfo.cpus = 8;
@@ -484,6 +489,10 @@ public List<DiskDef> getDisks(final Connect conn, final String vmName) {
484489
// IO traffic as generated by the logic above, must be greater than zero
485490
Assert.assertTrue(vmStat.getDiskReadKBs() > 0);
486491
Assert.assertTrue(vmStat.getDiskWriteKBs() > 0);
492+
// Memory limit of VM must be greater than zero
493+
Assert.assertTrue(vmStat.getIntFreeMemoryKBs() >= 0);
494+
Assert.assertTrue(vmStat.getMemoryKBs() >= 0);
495+
Assert.assertTrue(vmStat.getTargetMemoryKBs() >= vmStat.getMemoryKBs());
487496
}
488497

489498
@Test
@@ -5021,4 +5030,4 @@ public void testIsInterface () {
50215030
}
50225031
}
50235032
}
5024-
}
5033+
}

plugins/hypervisors/simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ public Answer getVmStats(final GetVmStatsCommand cmd) {
319319
final HashMap<String, VmStatsEntry> vmStatsNameMap = new HashMap<String, VmStatsEntry>();
320320
final List<String> vmNames = cmd.getVmNames();
321321
for (final String vmName : vmNames) {
322-
final VmStatsEntry entry = new VmStatsEntry(0, 0, 0, 0, "vm");
322+
final VmStatsEntry entry = new VmStatsEntry(0, 0, 0, 0, 0, 0, 0, "vm");
323323
entry.setNetworkReadKBs(32768); // default values 256 KBps
324324
entry.setNetworkWriteKBs(16384);
325325
entry.setCPUUtilization(10);

plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
import org.apache.cloudstack.storage.command.StorageSubSystemCommand;
101101
import org.apache.cloudstack.storage.to.TemplateObjectTO;
102102
import org.apache.cloudstack.storage.to.VolumeObjectTO;
103+
import org.apache.commons.lang.math.NumberUtils;
103104

104105
import com.cloud.agent.IAgentControl;
105106
import com.cloud.agent.api.Answer;
@@ -4944,15 +4945,24 @@ private HashMap<String, VmStatsEntry> getVmStats(List<String> vmNames) throws Ex
49444945
}
49454946
String instanceNameCustomField = "value[" + key + "]";
49464947

4948+
final String numCpuStr = "summary.config.numCpu";
4949+
final String cpuUseStr = "summary.quickStats.overallCpuUsage";
4950+
final String guestMemUseStr = "summary.quickStats.guestMemoryUsage";
4951+
final String memLimitStr = "resourceConfig.memoryAllocation.limit";
4952+
final String memMbStr = "config.hardware.memoryMB";
4953+
49474954
ObjectContent[] ocs =
4948-
hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", "summary.config.numCpu", "summary.quickStats.overallCpuUsage", instanceNameCustomField});
4955+
hyperHost.getVmPropertiesOnHyperHost(new String[] {"name", numCpuStr, cpuUseStr ,guestMemUseStr ,memLimitStr ,memMbStr, instanceNameCustomField});
49494956
if (ocs != null && ocs.length > 0) {
49504957
for (ObjectContent oc : ocs) {
49514958
List<DynamicProperty> objProps = oc.getPropSet();
49524959
if (objProps != null) {
49534960
String name = null;
49544961
String numberCPUs = null;
49554962
String maxCpuUsage = null;
4963+
String memlimit = null;
4964+
String memkb = null;
4965+
String guestMemusage = null;
49564966
String vmNameOnVcenter = null;
49574967
String vmInternalCSName = null;
49584968
for (DynamicProperty objProp : objProps) {
@@ -4961,10 +4971,16 @@ private HashMap<String, VmStatsEntry> getVmStats(List<String> vmNames) throws Ex
49614971
} else if (objProp.getName().contains(instanceNameCustomField)) {
49624972
if (objProp.getVal() != null)
49634973
vmInternalCSName = ((CustomFieldStringValue)objProp.getVal()).getValue();
4964-
} else if (objProp.getName().equals("summary.config.numCpu")) {
4974+
}else if(objProp.getName().equals(guestMemusage)){
4975+
guestMemusage = objProp.getVal().toString();
4976+
}else if (objProp.getName().equals(numCpuStr)) {
49654977
numberCPUs = objProp.getVal().toString();
4966-
} else if (objProp.getName().equals("summary.quickStats.overallCpuUsage")) {
4978+
} else if (objProp.getName().equals(cpuUseStr)) {
49674979
maxCpuUsage = objProp.getVal().toString();
4980+
} else if (objProp.getName().equals(memLimitStr)) {
4981+
memlimit = objProp.getVal().toString();
4982+
} else if (objProp.getName().equals(memMbStr)) {
4983+
memkb = objProp.getVal().toString();
49684984
}
49694985
}
49704986
new VirtualMachineMO(hyperHost.getContext(), oc.getObj());
@@ -5033,7 +5049,7 @@ private HashMap<String, VmStatsEntry> getVmStats(List<String> vmNames) throws Ex
50335049
}
50345050
}
50355051
}
5036-
vmResponseMap.put(name, new VmStatsEntry(Integer.parseInt(maxCpuUsage), networkReadKBs, networkWriteKBs, Integer.parseInt(numberCPUs), "vm"));
5052+
vmResponseMap.put(name, new VmStatsEntry( NumberUtils.toDouble(memkb)*1024,NumberUtils.toDouble(guestMemusage)*1024,NumberUtils.toDouble(memlimit)*1024, NumberUtils.toDouble(maxCpuUsage), networkReadKBs, networkWriteKBs, NumberUtils.toInt(numberCPUs), "vm"));
50375053
}
50385054
}
50395055
}

plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3278,7 +3278,7 @@ public HashMap<String, VmStatsEntry> getVmStats(final Connection conn, final Get
32783278
final HashMap<String, VmStatsEntry> vmResponseMap = new HashMap<String, VmStatsEntry>();
32793279

32803280
for (final String vmUUID : vmUUIDs) {
3281-
vmResponseMap.put(vmUUID, new VmStatsEntry(0, 0, 0, 0, "vm"));
3281+
vmResponseMap.put(vmUUID, new VmStatsEntry(0,0,0,0, 0, 0, 0, "vm"));
32823282
}
32833283

32843284
final Object[] rrdData = getRRDData(conn, 2); // call rrddata with 2 for
@@ -3332,7 +3332,14 @@ public HashMap<String, VmStatsEntry> getVmStats(final Connection conn, final Get
33323332
vmStatsAnswer.setDiskReadKBs(vmStatsAnswer.getDiskReadKBs() + getDataAverage(dataNode, col, numRows) / 1000);
33333333
} else if (param.matches("vbd_.*_write")) {
33343334
vmStatsAnswer.setDiskWriteKBs(vmStatsAnswer.getDiskWriteKBs() + getDataAverage(dataNode, col, numRows) / 1000);
3335+
} else if (param.contains("memory_internal_free")) {
3336+
vmStatsAnswer.setIntFreeMemoryKBs(vmStatsAnswer.getIntFreeMemoryKBs() + getDataAverage(dataNode, col, numRows) / 1024);
3337+
} else if (param.contains("memory_target")) {
3338+
vmStatsAnswer.setTargetMemoryKBs(vmStatsAnswer.getTargetMemoryKBs() + getDataAverage(dataNode, col, numRows) / 1024);
3339+
} else if (param.contains("memory")) {
3340+
vmStatsAnswer.setMemoryKBs(vmStatsAnswer.getMemoryKBs() + getDataAverage(dataNode, col, numRows) / 1024);
33353341
}
3342+
33363343
}
33373344
}
33383345

@@ -3348,6 +3355,7 @@ public HashMap<String, VmStatsEntry> getVmStats(final Connection conn, final Get
33483355
s_logger.debug("Vm cpu utilization " + vmStatsAnswer.getCPUUtilization());
33493356
}
33503357
}
3358+
33513359
return vmResponseMap;
33523360
}
33533361

@@ -5394,4 +5402,4 @@ public boolean attachConfigDriveToMigratedVm(Connection conn, String vmName, Str
53945402

53955403
}
53965404

5397-
}
5405+
}

server/src/com/cloud/api/query/dao/UserVmJoinDaoImpl.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,14 +207,21 @@ public UserVmResponse newUserVmResponse(ResponseView view, String objectName, Us
207207

208208
userVmResponse.setNetworkKbsWrite((long)vmStats.getNetworkWriteKBs());
209209

210-
if ((userVm.getHypervisorType() != null) && (userVm.getHypervisorType().equals(HypervisorType.KVM) || userVm.getHypervisorType().equals(HypervisorType.XenServer))) { // support KVM and XenServer only util 2013.06.25
210+
if ((userVm.getHypervisorType() != null) && (userVm.getHypervisorType().equals(HypervisorType.KVM) || userVm.getHypervisorType().equals(HypervisorType.XenServer) || userVm.getHypervisorType().equals(HypervisorType.VMware))) { // support KVM and XenServer only util 2013.06.25 . supporting Vmware from 2015.09.02
211211
userVmResponse.setDiskKbsRead((long)vmStats.getDiskReadKBs());
212212

213-
userVmResponse.setDiskKbsWrite((long)vmStats.getDiskWriteKBs());
213+
userVmResponse.setDiskKbsWrite((long) vmStats.getDiskWriteKBs());
214214

215-
userVmResponse.setDiskIORead((long)vmStats.getDiskReadIOs());
215+
userVmResponse.setDiskIORead((long) vmStats.getDiskReadIOs());
216+
217+
userVmResponse.setDiskIOWrite((long) vmStats.getDiskWriteIOs());
218+
219+
userVmResponse.setMemoryKBs((long) vmStats.getMemoryKBs());
220+
221+
userVmResponse.setMemoryIntFreeKBs((long) vmStats.getIntFreeMemoryKBs());
222+
223+
userVmResponse.setMemoryTargetKBs((long) vmStats.getTargetMemoryKBs());
216224

217-
userVmResponse.setDiskIOWrite((long)vmStats.getDiskWriteIOs());
218225
}
219226
}
220227
}

server/src/com/cloud/server/StatsCollector.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,9 @@ protected void runInContext() {
464464
statsInMemory.setDiskReadIOs(statsInMemory.getDiskReadIOs() + statsForCurrentIteration.getDiskReadIOs());
465465
statsInMemory.setDiskWriteIOs(statsInMemory.getDiskWriteIOs() + statsForCurrentIteration.getDiskWriteIOs());
466466
statsInMemory.setDiskReadKBs(statsInMemory.getDiskReadKBs() + statsForCurrentIteration.getDiskReadKBs());
467+
statsInMemory.setMemoryKBs(statsForCurrentIteration.getMemoryKBs());
468+
statsInMemory.setIntFreeMemoryKBs(statsForCurrentIteration.getIntFreeMemoryKBs());
469+
statsInMemory.setTargetMemoryKBs(statsForCurrentIteration.getTargetMemoryKBs());
467470

468471
_VmStats.put(vmId, statsInMemory);
469472
}
@@ -484,6 +487,10 @@ protected void runInContext() {
484487
metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.read_kbs", statsForCurrentIteration.getDiskReadKBs());
485488
metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.write_iops", statsForCurrentIteration.getDiskWriteIOs());
486489
metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".disk.read_iops", statsForCurrentIteration.getDiskReadIOs());
490+
metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".memory.total_kbs", statsForCurrentIteration.getMemoryKBs());
491+
metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".memory.internalfree_kbs", statsForCurrentIteration.getIntFreeMemoryKBs());
492+
metrics.put(externalStatsPrefix + "cloudstack.stats.instances." + vmName + ".memory.target_kbs", statsForCurrentIteration.getTargetMemoryKBs());
493+
487494
}
488495

489496
}

0 commit comments

Comments
 (0)