From 8e0e5acea7738da22b1822a9ed3426a392d79a5d Mon Sep 17 00:00:00 2001 From: SadiJr <31869303+SadiJr@users.noreply.github.com> Date: Thu, 26 Aug 2021 08:27:48 -0300 Subject: [PATCH] Externalize VMWare stats time window config (#5357) Co-authored-by: SadiJr <17a0db2854@firemailbox.club> --- .../vmware/manager/VmwareManager.java | 4 + .../vmware/manager/VmwareManagerImpl.java | 2 +- .../vmware/resource/VmwareResource.java | 166 ++++++++++-------- 3 files changed, 97 insertions(+), 75 deletions(-) diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java index 8cc328a7a38..6d1de67963c 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManager.java @@ -46,6 +46,10 @@ public interface VmwareManager { static final ConfigKey s_vmwareOVAPackageTimeout = new ConfigKey(Integer.class, "vmware.package.ova.timeout", "Advanced", "3600", "Vmware script timeout for ova packaging process", true, ConfigKey.Scope.Global, 1000); + public static final ConfigKey VMWARE_STATS_TIME_WINDOW = new ConfigKey("Advanced", Integer.class, "vmware.stats.time.window", "300", + "VMware interval window (in seconds) to collect metrics. If this is set to less than 20, then default (300 seconds) will be used. The interval used must be enabled in vCenter for this change to work, " + + "otherwise the collection of metrics will result in an error. Check VMWare docs to know how to enable metrics interval.", true); + String composeWorkerName(); String getSystemVMIsoFileNameOnDatastore(); diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java index e1e0d6b24ee..f3b6dcbfce2 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java @@ -270,7 +270,7 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw @Override public ConfigKey[] getConfigKeys() { - return new ConfigKey[] {s_vmwareNicHotplugWaitTimeout, s_vmwareCleanOldWorderVMs, templateCleanupInterval, s_vmwareSearchExcludeFolder, s_vmwareOVAPackageTimeout}; + return new ConfigKey[] {s_vmwareNicHotplugWaitTimeout, s_vmwareCleanOldWorderVMs, templateCleanupInterval, s_vmwareSearchExcludeFolder, s_vmwareOVAPackageTimeout, VMWARE_STATS_TIME_WINDOW}; } @Override public boolean configure(String name, Map params) throws ConfigurationException { 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 761b0ff7bf5..54aed10713c 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 @@ -3959,8 +3959,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa final ManagedObjectReference perfMgr = getServiceContext().getServiceContent().getPerfManager(); VimPortType service = getServiceContext().getService(); - final int intervalSeconds = 300; - final XMLGregorianCalendar startTime = VmwareHelper.getXMLGregorianCalendar(new Date(), intervalSeconds); + Integer windowInterval = getVmwareWindowTimeInterval(); + final XMLGregorianCalendar startTime = VmwareHelper.getXMLGregorianCalendar(new Date(), windowInterval); final XMLGregorianCalendar endTime = VmwareHelper.getXMLGregorianCalendar(new Date(), 0); PerfCounterInfo diskReadIOPerfCounterInfo = null; @@ -4016,45 +4016,50 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } 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); + try { + final PerfQuerySpec qSpec = new PerfQuerySpec(); + qSpec.setEntity(vmMo.getMor()); + qSpec.setFormat("normal"); + qSpec.setIntervalId(windowInterval); + 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(); - if (values == null || values.isEmpty()) { - continue; - } - for (final PerfMetricSeries value : values) { - if (!(value instanceof PerfMetricIntSeries) || !value.getId().getInstance().equals(diskBusName)) { + for (final PerfEntityMetricBase perfValue: service.queryPerf(perfMgr, Collections.singletonList(qSpec))) { + if (!(perfValue instanceof PerfEntityMetric)) { continue; } - final List perfStats = ((PerfMetricIntSeries) value).getValue(); - if (perfStats.size() > 0) { - long sum = 0; - for (long val : perfStats) { - sum += val; + final List 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; } - 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; + 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 * 1024; + } else if (value.getId().getCounterId() == diskWriteKbsPerfCounterInfo.getKey()) { + writeBytes = avg * 1024; + } } } } + } catch (Exception e) { + s_logger.error(String.format("Unable to execute PerfQuerySpec due to: [%s]. The window interval is enabled in vCenter?", VmwareHelper.getExceptionMessage(e)), e); } + } diskStats.add(new VmDiskStatsEntry(vmName, VmwareHelper.getDiskDeviceFileName(disk), writeReq, readReq, writeBytes, readBytes)); } @@ -6400,8 +6405,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa PerfCounterInfo diskReadKbsPerfCounterInfo = null; PerfCounterInfo diskWriteKbsPerfCounterInfo = null; - final int intervalSeconds = 300; - final XMLGregorianCalendar startTime = VmwareHelper.getXMLGregorianCalendar(new Date(), intervalSeconds); + Integer windowInterval = getVmwareWindowTimeInterval(); + final XMLGregorianCalendar startTime = VmwareHelper.getXMLGregorianCalendar(new Date(), windowInterval); final XMLGregorianCalendar endTime = VmwareHelper.getXMLGregorianCalendar(new Date(), 0); List cInfo = getServiceContext().getVimClient().getDynamicProperty(perfMgr, "perfCounter"); @@ -6523,48 +6528,52 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } if (perfMetricsIds.size() > 0) { - final PerfQuerySpec qSpec = new PerfQuerySpec(); - qSpec.setEntity(vmMor); - 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)) { + try { + final PerfQuerySpec qSpec = new PerfQuerySpec(); + qSpec.setEntity(vmMor); + qSpec.setFormat("normal"); + qSpec.setIntervalId(windowInterval); + 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 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 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; + } } } + } catch (Exception e) { + s_logger.error(String.format("Unable to execute PerfQuerySpec due to: [%s]. The window interval is enabled in vCenter?", VmwareHelper.getExceptionMessage(e)), e); } } @@ -7689,4 +7698,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa return new GetVmVncTicketAnswer(null, false, e.getLocalizedMessage()); } } -} + + private Integer getVmwareWindowTimeInterval() { + Integer windowInterval = VmwareManager.VMWARE_STATS_TIME_WINDOW.value(); + if (windowInterval == null || windowInterval < 20) { + s_logger.error(String.format("The window interval can't be [%s]. Therefore we will use the default value of [%s] seconds.", windowInterval, VmwareManager.VMWARE_STATS_TIME_WINDOW.defaultValue())); + windowInterval = Integer.valueOf(VmwareManager.VMWARE_STATS_TIME_WINDOW.defaultValue()); + } + return windowInterval; + } +} \ No newline at end of file