You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2015/05/25 15:52:11 UTC

git commit: updated refs/heads/master to cde6ef9

Repository: cloudstack
Updated Branches:
  refs/heads/master b9a0b8807 -> cde6ef94b


CLOUDSTACK-8247: Pull average Cpu util report between polling

Pull average Cpu util report between polling intervals instead of since boot
instead of using values since uptime

(cherry picked from commit 04176eaf171b46638be99b2f675aa2f09e99e1b8)
Signed-off-by: Rohit Yadav <ro...@shapeblue.com>

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

This closes #297


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/cde6ef94
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/cde6ef94
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/cde6ef94

Branch: refs/heads/master
Commit: cde6ef94b8de72cf541520f71c99c3931756920a
Parents: b9a0b88
Author: Rohit Yadav <ro...@shapeblue.com>
Authored: Fri May 22 12:20:50 2015 +0100
Committer: Rohit Yadav <ro...@shapeblue.com>
Committed: Mon May 25 15:52:00 2015 +0200

----------------------------------------------------------------------
 .../kvm/resource/LibvirtComputingResource.java  |  98 +++++++-------
 .../LibvirtGetHostStatsCommandWrapper.java      |  27 +---
 .../apache/cloudstack/utils/linux/CPUStat.java  | 104 +++++++++++++++
 .../resource/LibvirtComputingResourceTest.java  | 127 ++++++++++---------
 4 files changed, 231 insertions(+), 125 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cde6ef94/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 13f8dc5..df046da 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -16,50 +16,6 @@
 // under the License.
 package com.cloud.hypervisor.kvm.resource;
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.net.InetAddress;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
-import org.apache.cloudstack.storage.to.VolumeObjectTO;
-import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.log4j.Logger;
-import org.libvirt.Connect;
-import org.libvirt.Domain;
-import org.libvirt.DomainBlockStats;
-import org.libvirt.DomainInfo;
-import org.libvirt.DomainInfo.DomainState;
-import org.libvirt.DomainInterfaceStats;
-import org.libvirt.LibvirtException;
-import org.libvirt.NodeInfo;
-
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.HostVmStateReportEntry;
@@ -139,6 +95,50 @@ import com.cloud.utils.script.Script;
 import com.cloud.utils.ssh.SshHelper;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachine.PowerState;
+import org.apache.cloudstack.storage.to.PrimaryDataStoreTO;
+import org.apache.cloudstack.storage.to.VolumeObjectTO;
+import org.apache.cloudstack.utils.linux.CPUStat;
+import org.apache.cloudstack.utils.linux.MemStat;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.Logger;
+import org.libvirt.Connect;
+import org.libvirt.Domain;
+import org.libvirt.DomainBlockStats;
+import org.libvirt.DomainInfo;
+import org.libvirt.DomainInfo.DomainState;
+import org.libvirt.DomainInterfaceStats;
+import org.libvirt.LibvirtException;
+import org.libvirt.NodeInfo;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.net.InetAddress;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * LibvirtComputingResource execute requests on the computing/routing host using
@@ -261,6 +261,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
     protected boolean _disconnected = true;
     protected int _cmdsTimeout;
     protected int _stopTimeout;
+    protected CPUStat _cpuStat = new CPUStat();
+    protected MemStat _memStat = new MemStat();
 
     @Inject
     private LibvirtUtilitiesHelper libvirtUtilitiesHelper;
@@ -330,6 +332,14 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
         return libvirtUtilitiesHelper;
     }
 
+    public CPUStat getCPUStat() {
+        return _cpuStat;
+    }
+
+    public MemStat getMemStat() {
+        return _memStat;
+    }
+
     public VirtualRoutingResource getVirtRouterResource() {
         return _virtRouterResource;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cde6ef94/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java
index 198eb3b..80bd5fa 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtGetHostStatsCommandWrapper.java
@@ -19,9 +19,6 @@
 
 package com.cloud.hypervisor.kvm.resource.wrapper;
 
-import org.apache.cloudstack.utils.linux.MemStat;
-import org.apache.log4j.Logger;
-
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.GetHostStatsAnswer;
 import com.cloud.agent.api.GetHostStatsCommand;
@@ -30,8 +27,9 @@ import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
 import com.cloud.resource.CommandWrapper;
 import com.cloud.resource.ResourceWrapper;
 import com.cloud.utils.Pair;
-import com.cloud.utils.script.OutputInterpreter;
-import com.cloud.utils.script.Script;
+import org.apache.cloudstack.utils.linux.CPUStat;
+import org.apache.cloudstack.utils.linux.MemStat;
+import org.apache.log4j.Logger;
 
 @ResourceWrapper(handles =  GetHostStatsCommand.class)
 public final class LibvirtGetHostStatsCommandWrapper extends CommandWrapper<GetHostStatsCommand, Answer, LibvirtComputingResource> {
@@ -40,23 +38,10 @@ public final class LibvirtGetHostStatsCommandWrapper extends CommandWrapper<GetH
 
     @Override
     public Answer execute(final GetHostStatsCommand command, final LibvirtComputingResource libvirtComputingResource) {
-        final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
-        final String bashScriptPath = libvirtUtilitiesHelper.retrieveBashScriptPath();
-
-
-        final Script cpuScript = new Script(bashScriptPath, s_logger);
-        cpuScript.add("-c");
-        cpuScript.add("idle=$(top -b -n 1| awk -F, '/^[%]*[Cc]pu/{$0=$4; gsub(/[^0-9.,]+/,\"\"); print }'); echo $idle");
-
-        final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
-        String result = cpuScript.execute(parser);
-        if (result != null) {
-            s_logger.debug("Unable to get the host CPU state: " + result);
-            return new Answer(command, false, result);
-        }
-        final double cpuUtil = 100.0D - Double.parseDouble(parser.getLine());
+        CPUStat cpuStat = libvirtComputingResource.getCPUStat();
+        MemStat memStat = libvirtComputingResource.getMemStat();
 
-        MemStat memStat = new MemStat();
+        final double cpuUtil = cpuStat.getCpuUsedPercent();
         memStat.refresh();
         double totMem = memStat.getTotal();
         double freeMem = memStat.getAvailable();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cde6ef94/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/CPUStat.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/CPUStat.java b/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/CPUStat.java
new file mode 100644
index 0000000..38b7e8e
--- /dev/null
+++ b/plugins/hypervisors/kvm/src/org/apache/cloudstack/utils/linux/CPUStat.java
@@ -0,0 +1,104 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// the License.  You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.cloudstack.utils.linux;
+
+import org.apache.log4j.Logger;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Scanner;
+
+public class CPUStat {
+    private static final Logger s_logger = Logger.getLogger(CPUStat.class);
+
+    private Integer _cores;
+    private UptimeStats _lastStats;
+    private final String _sysfsCpuDir = "/sys/devices/system/cpu";
+    private final String _uptimeFile = "/proc/uptime";
+
+    class UptimeStats {
+        public Double upTime = 0d;
+        public Double cpuIdleTime = 0d;
+
+        public UptimeStats(Double upTime, Double cpuIdleTime) {
+            this.upTime = upTime;
+            this.cpuIdleTime = cpuIdleTime;
+        }
+    }
+
+    public CPUStat () {
+        init();
+    }
+
+    private void init() {
+        _cores = getCoresFromLinux();
+        _lastStats = getUptimeAndCpuIdleTime();
+    }
+
+    private UptimeStats getUptimeAndCpuIdleTime() {
+        UptimeStats uptime = new UptimeStats(0d, 0d);
+        try {
+            String[] stats =  new Scanner(new File(_uptimeFile)).useDelimiter("\\Z").next().split("\\s+");
+            uptime = new UptimeStats(Double.parseDouble(stats[0]), Double.parseDouble(stats[1]));
+        } catch (FileNotFoundException ex) {
+            s_logger.warn("File " + _uptimeFile + " not found:" + ex.toString());
+        }
+        return uptime;
+    }
+
+    private Integer getCoresFromLinux() {
+        Integer cpus = 0;
+        File cpuDir = new File(_sysfsCpuDir);
+        File[] files = cpuDir.listFiles();
+        if (files != null) {
+            for (File file : files) {
+                if (file.getName().matches("cpu\\d+")) {
+                    cpus++;
+                }
+            }
+        }
+        return cpus;
+    }
+
+    public Integer getCores() {
+        return _cores;
+    }
+
+    public Double getCpuUsedPercent() {
+        Double cpuUsed = 0d;
+        if (_cores == null || _cores == 0) {
+            _cores = getCoresFromLinux();
+        }
+
+        UptimeStats currentStats = getUptimeAndCpuIdleTime();
+        if (currentStats == null) {
+            return cpuUsed;
+        }
+
+        Double timeElapsed = currentStats.upTime - _lastStats.upTime;
+        Double cpuElapsed = (currentStats.cpuIdleTime - _lastStats.cpuIdleTime) / _cores;
+        if (timeElapsed > 0) {
+            cpuUsed = (1 - (cpuElapsed / timeElapsed)) * 100;
+        }
+        if (cpuUsed < 0) {
+            cpuUsed = 0d;
+        }
+        _lastStats = currentStats;
+        return cpuUsed;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cde6ef94/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
index 6d8dc80..5e6e852 100644
--- a/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
+++ b/plugins/hypervisors/kvm/test/com/cloud/hypervisor/kvm/resource/LibvirtComputingResourceTest.java
@@ -19,59 +19,6 @@
 
 package com.cloud.hypervisor.kvm.resource;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Random;
-import java.util.UUID;
-
-import javax.naming.ConfigurationException;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
-import org.apache.cloudstack.storage.command.AttachAnswer;
-import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
-import org.apache.commons.lang.SystemUtils;
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.libvirt.Connect;
-import org.libvirt.Domain;
-import org.libvirt.DomainBlockStats;
-import org.libvirt.DomainInfo;
-import org.libvirt.DomainInfo.DomainState;
-import org.libvirt.DomainInterfaceStats;
-import org.libvirt.LibvirtException;
-import org.libvirt.NodeInfo;
-import org.libvirt.StorageVol;
-import org.mockito.Matchers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
-
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.AttachIsoCommand;
 import com.cloud.agent.api.AttachVolumeCommand;
@@ -169,6 +116,59 @@ import com.cloud.vm.DiskProfile;
 import com.cloud.vm.VirtualMachine;
 import com.cloud.vm.VirtualMachine.PowerState;
 import com.cloud.vm.VirtualMachine.Type;
+import org.apache.cloudstack.storage.command.AttachAnswer;
+import org.apache.cloudstack.storage.command.AttachCommand;
+import org.apache.cloudstack.utils.linux.CPUStat;
+import org.apache.cloudstack.utils.linux.MemStat;
+import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
+import org.apache.commons.lang.SystemUtils;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.libvirt.Connect;
+import org.libvirt.Domain;
+import org.libvirt.DomainBlockStats;
+import org.libvirt.DomainInfo;
+import org.libvirt.DomainInfo.DomainState;
+import org.libvirt.DomainInterfaceStats;
+import org.libvirt.LibvirtException;
+import org.libvirt.NodeInfo;
+import org.libvirt.StorageVol;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+import javax.naming.ConfigurationException;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Random;
+import java.util.UUID;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
 public class LibvirtComputingResourceTest {
@@ -920,24 +920,31 @@ public class LibvirtComputingResourceTest {
     public void testGetHostStatsCommand() {
         // A bit difficult to test due to the logger being passed and the parser itself relying on the connection.
         // Have to spend some more time afterwards in order to refactor the wrapper itself.
-
         final LibvirtUtilitiesHelper libvirtUtilitiesHelper = Mockito.mock(LibvirtUtilitiesHelper.class);
-        final String bashScriptPath = "/path";
+        final CPUStat cpuStat = Mockito.mock(CPUStat.class);
+        final MemStat memStat = Mockito.mock(MemStat.class);
 
         final String uuid = "e8d6b4d0-bc6d-4613-b8bb-cb9e0600f3c6";
         final GetHostStatsCommand command = new GetHostStatsCommand(uuid, "summer", 1l);
 
-        when(libvirtComputingResource.getLibvirtUtilitiesHelper()).thenReturn(libvirtUtilitiesHelper);
-        when(libvirtUtilitiesHelper.retrieveBashScriptPath()).thenReturn(bashScriptPath);
+        when(libvirtComputingResource.getCPUStat()).thenReturn(cpuStat);
+        when(libvirtComputingResource.getMemStat()).thenReturn(memStat);
+        when(libvirtComputingResource.getNicStats(Mockito.anyString())).thenReturn(new Pair<Double, Double>(1.0d, 1.0d));
+        when(cpuStat.getCpuUsedPercent()).thenReturn(0.5d);
+        when(memStat.getAvailable()).thenReturn(1500.5d);
+        when(memStat.getTotal()).thenReturn(15000d);
 
         final LibvirtRequestWrapper wrapper = LibvirtRequestWrapper.getInstance();
         assertNotNull(wrapper);
 
         final Answer answer = wrapper.execute(command, libvirtComputingResource);
-        assertFalse(answer.getResult());
+        assertTrue(answer.getResult());
 
-        verify(libvirtComputingResource, times(1)).getLibvirtUtilitiesHelper();
-        verify(libvirtUtilitiesHelper, times(1)).retrieveBashScriptPath();
+        verify(libvirtComputingResource, times(1)).getCPUStat();
+        verify(libvirtComputingResource, times(1)).getMemStat();
+        verify(cpuStat, times(1)).getCpuUsedPercent();
+        verify(memStat, times(1)).getAvailable();
+        verify(memStat, times(1)).getTotal();
     }
 
     @Test