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 a29ecb418f13..4ceccaaae121 100755 --- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java +++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java @@ -61,6 +61,7 @@ import javax.ejb.Local; import javax.naming.ConfigurationException; +import org.apache.cloudstack.utils.linux.CPUStat; import org.apache.cloudstack.utils.linux.MemStat; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -464,6 +465,7 @@ protected String getDefaultScriptsDir() { protected int _timeout; protected int _cmdsTimeout; protected int _stopTimeout; + private CPUStat _cpuStat = new CPUStat(); private MemStat _memStat = new MemStat(); protected static final HashMap s_powerStatesTable; @@ -3266,17 +3268,7 @@ private Answer execute(CheckHealthCommand cmd) { } private Answer execute(GetHostStatsCommand cmd) { - final Script cpuScript = new Script("/bin/bash", 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(cmd, false, result); - } - double cpuUtil = (100.0D - Double.parseDouble(parser.getLine())); + double cpuUtil = _cpuStat.getCpuUsedPercent(); _memStat.refresh(); double totMem = _memStat.getTotal(); 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 000000000000..38b7e8ef9e6c --- /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; + } +}