mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
CLOUDSTACK-7984: Collect network statistics for VMs on shared network (KVM implementation)
This commit is contained in:
parent
61208b5db2
commit
960cb84083
@ -482,4 +482,8 @@ public interface UserVmService {
|
||||
*/
|
||||
public boolean isDisplayResourceEnabled(Long vmId);
|
||||
|
||||
void collectVmDiskStatistics(UserVm userVm);
|
||||
|
||||
void collectVmNetworkStatistics (UserVm userVm);
|
||||
|
||||
}
|
||||
|
||||
26
api/src/com/cloud/vm/VmNetworkStats.java
Normal file
26
api/src/com/cloud/vm/VmNetworkStats.java
Normal file
@ -0,0 +1,26 @@
|
||||
// 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
|
||||
// with 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 com.cloud.vm;
|
||||
|
||||
public interface VmNetworkStats {
|
||||
// vm related network stats
|
||||
|
||||
public long getBytesSent();
|
||||
|
||||
public long getBytesReceived();
|
||||
|
||||
}
|
||||
@ -24,7 +24,7 @@ import java.util.List;
|
||||
|
||||
import com.cloud.agent.api.LogLevel.Log4jLevel;
|
||||
|
||||
@LogLevel(Log4jLevel.Trace)
|
||||
@LogLevel(Log4jLevel.Debug)
|
||||
public class GetVmDiskStatsAnswer extends Answer {
|
||||
|
||||
String hostName;
|
||||
|
||||
50
core/src/com/cloud/agent/api/GetVmNetworkStatsAnswer.java
Normal file
50
core/src/com/cloud/agent/api/GetVmNetworkStatsAnswer.java
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// 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
|
||||
// with 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 com.cloud.agent.api;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.agent.api.LogLevel.Log4jLevel;
|
||||
|
||||
@LogLevel(Log4jLevel.Debug)
|
||||
public class GetVmNetworkStatsAnswer extends Answer {
|
||||
|
||||
String hostName;
|
||||
HashMap<String, List<VmNetworkStatsEntry>> vmNetworkStatsMap;
|
||||
|
||||
public GetVmNetworkStatsAnswer(GetVmNetworkStatsCommand cmd, String details, String hostName, HashMap<String, List<VmNetworkStatsEntry>> vmNetworkStatsMap) {
|
||||
super(cmd, true, details);
|
||||
this.hostName = hostName;
|
||||
this.vmNetworkStatsMap = vmNetworkStatsMap;
|
||||
}
|
||||
|
||||
public String getHostName() {
|
||||
return hostName;
|
||||
}
|
||||
|
||||
public HashMap<String, List<VmNetworkStatsEntry>> getVmNetworkStatsMap() {
|
||||
return vmNetworkStatsMap;
|
||||
}
|
||||
|
||||
protected GetVmNetworkStatsAnswer() {
|
||||
//no-args constructor for json serialization-deserialization
|
||||
}
|
||||
}
|
||||
57
core/src/com/cloud/agent/api/GetVmNetworkStatsCommand.java
Normal file
57
core/src/com/cloud/agent/api/GetVmNetworkStatsCommand.java
Normal file
@ -0,0 +1,57 @@
|
||||
//
|
||||
// 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
|
||||
// with 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 com.cloud.agent.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.agent.api.LogLevel.Log4jLevel;
|
||||
|
||||
@LogLevel(Log4jLevel.Trace)
|
||||
public class GetVmNetworkStatsCommand extends Command {
|
||||
List<String> vmNames;
|
||||
String hostGuid;
|
||||
String hostName;
|
||||
|
||||
protected GetVmNetworkStatsCommand() {
|
||||
}
|
||||
|
||||
public GetVmNetworkStatsCommand(List<String> vmNames, String hostGuid, String hostName) {
|
||||
this.vmNames = vmNames;
|
||||
this.hostGuid = hostGuid;
|
||||
this.hostName = hostName;
|
||||
}
|
||||
|
||||
public List<String> getVmNames() {
|
||||
return vmNames;
|
||||
}
|
||||
|
||||
public String getHostGuid() {
|
||||
return this.hostGuid;
|
||||
}
|
||||
|
||||
public String getHostName() {
|
||||
return this.hostName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeInSequence() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
74
core/src/com/cloud/agent/api/VmNetworkStatsEntry.java
Normal file
74
core/src/com/cloud/agent/api/VmNetworkStatsEntry.java
Normal file
@ -0,0 +1,74 @@
|
||||
//
|
||||
// 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
|
||||
// with 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 com.cloud.agent.api;
|
||||
|
||||
import com.cloud.vm.VmNetworkStats;
|
||||
|
||||
public class VmNetworkStatsEntry implements VmNetworkStats {
|
||||
String vmName;
|
||||
String macAddress;
|
||||
long bytesSent;
|
||||
long bytesReceived;
|
||||
|
||||
public VmNetworkStatsEntry() {
|
||||
}
|
||||
|
||||
public VmNetworkStatsEntry(String vmName, String macAddress, long bytesSent, long bytesReceived) {
|
||||
this.bytesSent = bytesSent;
|
||||
this.bytesReceived = bytesReceived;
|
||||
this.vmName = vmName;
|
||||
this.macAddress = macAddress;
|
||||
}
|
||||
|
||||
public void setVmName(String vmName) {
|
||||
this.vmName = vmName;
|
||||
}
|
||||
|
||||
public String getVmName() {
|
||||
return vmName;
|
||||
}
|
||||
|
||||
public void setMacAddress(String macAddress) {
|
||||
this.macAddress = macAddress;
|
||||
}
|
||||
|
||||
public String getMacAddress() {
|
||||
return macAddress;
|
||||
}
|
||||
|
||||
public void setBytesSent(long bytesSent) {
|
||||
this.bytesSent = bytesSent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getBytesSent() {
|
||||
return bytesSent;
|
||||
}
|
||||
|
||||
public void setBytesReceived(long bytesReceived) {
|
||||
this.bytesReceived = bytesReceived;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getBytesReceived() {
|
||||
return bytesReceived;
|
||||
}
|
||||
|
||||
}
|
||||
@ -236,6 +236,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
@Inject
|
||||
protected UserVmDao _userVmDao;
|
||||
@Inject
|
||||
protected UserVmService _userVmService;
|
||||
@Inject
|
||||
protected CapacityManager _capacityMgr;
|
||||
@Inject
|
||||
protected NicDao _nicsDao;
|
||||
@ -3637,6 +3639,11 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
||||
final VMInstanceVO router = _vmDao.findById(vm.getId());
|
||||
|
||||
if (router.getState() == State.Running) {
|
||||
// collect vm network statistics before unplug a nic
|
||||
UserVmVO userVm = _userVmDao.findById(vm.getId());
|
||||
if (userVm != null && userVm.getType() == VirtualMachine.Type.User) {
|
||||
_userVmService.collectVmNetworkStatistics(userVm);
|
||||
}
|
||||
try {
|
||||
final Commands cmds = new Commands(Command.OnError.Stop);
|
||||
final UnPlugNicCommand unplugNicCmd = new UnPlugNicCommand(nic, vm.getName());
|
||||
|
||||
@ -89,6 +89,7 @@ import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupRoutingCommand;
|
||||
import com.cloud.agent.api.StartupStorageCommand;
|
||||
import com.cloud.agent.api.VmDiskStatsEntry;
|
||||
import com.cloud.agent.api.VmNetworkStatsEntry;
|
||||
import com.cloud.agent.api.VmStatsEntry;
|
||||
import com.cloud.agent.api.routing.IpAssocCommand;
|
||||
import com.cloud.agent.api.routing.IpAssocVpcCommand;
|
||||
@ -3114,6 +3115,30 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
|
||||
return command.execute();
|
||||
}
|
||||
|
||||
public List<VmNetworkStatsEntry> getVmNetworkStat(Connect conn, String vmName) throws LibvirtException {
|
||||
Domain dm = null;
|
||||
try {
|
||||
dm = getDomain(conn, vmName);
|
||||
|
||||
List<VmNetworkStatsEntry> stats = new ArrayList<VmNetworkStatsEntry>();
|
||||
|
||||
List<InterfaceDef> nics = getInterfaces(conn, vmName);
|
||||
|
||||
for (InterfaceDef nic : nics) {
|
||||
DomainInterfaceStats nicStats = dm.interfaceStats(nic.getDevName());
|
||||
String macAddress = nic.getMacAddress();
|
||||
VmNetworkStatsEntry stat = new VmNetworkStatsEntry(vmName, macAddress, nicStats.tx_bytes, nicStats.rx_bytes);
|
||||
stats.add(stat);
|
||||
}
|
||||
|
||||
return stats;
|
||||
} finally {
|
||||
if (dm != null) {
|
||||
dm.free();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<VmDiskStatsEntry> getVmDiskStat(final Connect conn, final String vmName) throws LibvirtException {
|
||||
Domain dm = null;
|
||||
try {
|
||||
|
||||
@ -0,0 +1,64 @@
|
||||
//
|
||||
// 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
|
||||
// with 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 com.cloud.hypervisor.kvm.resource.wrapper;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.libvirt.Connect;
|
||||
import org.libvirt.LibvirtException;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.GetVmNetworkStatsAnswer;
|
||||
import com.cloud.agent.api.GetVmNetworkStatsCommand;
|
||||
import com.cloud.agent.api.VmNetworkStatsEntry;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
|
||||
import com.cloud.resource.CommandWrapper;
|
||||
import com.cloud.resource.ResourceWrapper;
|
||||
|
||||
@ResourceWrapper(handles = GetVmNetworkStatsCommand.class)
|
||||
public final class LibvirtGetVmNetworkStatsCommandWrapper extends CommandWrapper<GetVmNetworkStatsCommand, Answer, LibvirtComputingResource> {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(LibvirtGetVmNetworkStatsCommandWrapper.class);
|
||||
|
||||
@Override
|
||||
public Answer execute(final GetVmNetworkStatsCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
||||
final List<String> vmNames = command.getVmNames();
|
||||
final LibvirtUtilitiesHelper libvirtUtilitiesHelper = libvirtComputingResource.getLibvirtUtilitiesHelper();
|
||||
|
||||
try {
|
||||
final HashMap<String, List<VmNetworkStatsEntry>> vmNetworkStatsNameMap = new HashMap<String, List<VmNetworkStatsEntry>>();
|
||||
final Connect conn = libvirtUtilitiesHelper.getConnection();
|
||||
for (final String vmName : vmNames) {
|
||||
final List<VmNetworkStatsEntry> statEntry = libvirtComputingResource.getVmNetworkStat(conn, vmName);
|
||||
if (statEntry == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
vmNetworkStatsNameMap.put(vmName, statEntry);
|
||||
}
|
||||
return new GetVmNetworkStatsAnswer(command, "", command.getHostName(), vmNetworkStatsNameMap);
|
||||
} catch (final LibvirtException e) {
|
||||
s_logger.debug("Can't get vm network stats: " + e.toString());
|
||||
return new GetVmNetworkStatsAnswer(command, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -139,6 +139,8 @@ import com.cloud.agent.api.GetStorageStatsAnswer;
|
||||
import com.cloud.agent.api.GetStorageStatsCommand;
|
||||
import com.cloud.agent.api.GetVmDiskStatsAnswer;
|
||||
import com.cloud.agent.api.GetVmDiskStatsCommand;
|
||||
import com.cloud.agent.api.GetVmNetworkStatsAnswer;
|
||||
import com.cloud.agent.api.GetVmNetworkStatsCommand;
|
||||
import com.cloud.agent.api.GetVmStatsAnswer;
|
||||
import com.cloud.agent.api.GetVmStatsCommand;
|
||||
import com.cloud.agent.api.GetVncPortAnswer;
|
||||
@ -407,6 +409,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
answer = execute((GetHostStatsCommand)cmd);
|
||||
} else if (clz == GetVmStatsCommand.class) {
|
||||
answer = execute((GetVmStatsCommand)cmd);
|
||||
} else if (clz == GetVmNetworkStatsCommand.class) {
|
||||
answer = execute((GetVmNetworkStatsCommand) cmd);
|
||||
} else if (clz == GetVmDiskStatsCommand.class) {
|
||||
answer = execute((GetVmDiskStatsCommand)cmd);
|
||||
} else if (clz == CheckHealthCommand.class) {
|
||||
@ -3206,6 +3210,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
return new GetVmDiskStatsAnswer(cmd, null, null, null);
|
||||
}
|
||||
|
||||
protected Answer execute(GetVmNetworkStatsCommand cmd) {
|
||||
return new GetVmNetworkStatsAnswer(cmd, null, null, null);
|
||||
}
|
||||
|
||||
protected Answer execute(CheckHealthCommand cmd) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Executing resource CheckHealthCommand: " + _gson.toJson(cmd));
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
//
|
||||
// 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
|
||||
// with 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 com.cloud.hypervisor.xenserver.resource.wrapper.xenbase;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.GetVmNetworkStatsAnswer;
|
||||
import com.cloud.agent.api.GetVmNetworkStatsCommand;
|
||||
import com.cloud.hypervisor.xenserver.resource.CitrixResourceBase;
|
||||
import com.cloud.resource.CommandWrapper;
|
||||
import com.cloud.resource.ResourceWrapper;
|
||||
|
||||
@ResourceWrapper(handles = GetVmNetworkStatsCommand.class)
|
||||
public final class CitrixGetVmNetworkStatsCommandWrapper extends CommandWrapper<GetVmNetworkStatsCommand, Answer, CitrixResourceBase> {
|
||||
|
||||
@Override
|
||||
public Answer execute(final GetVmNetworkStatsCommand command, final CitrixResourceBase citrixResourceBase) {
|
||||
return new GetVmNetworkStatsAnswer(command, null, null, null);
|
||||
}
|
||||
}
|
||||
@ -3266,7 +3266,7 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
} else if (usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_SENT || usageRecord.getUsageType() == UsageTypes.NETWORK_BYTES_RECEIVED) {
|
||||
//Device Type
|
||||
usageRecResponse.setType(usageRecord.getType());
|
||||
if (usageRecord.getType().equals("DomainRouter")) {
|
||||
if (usageRecord.getType().equals("DomainRouter") || usageRecord.getType().equals("UserVm")) {
|
||||
//Domain Router Id
|
||||
VMInstanceVO vm = _entityMgr.findByIdIncludingRemoved(VMInstanceVO.class, usageRecord.getUsageId().toString());
|
||||
if (vm != null) {
|
||||
|
||||
@ -869,6 +869,7 @@ public enum Config {
|
||||
"The interval (in milliseconds) when vm stats are retrieved from agents.",
|
||||
null),
|
||||
VmDiskStatsInterval("Advanced", ManagementServer.class, Integer.class, "vm.disk.stats.interval", "0", "Interval (in seconds) to report vm disk statistics.", null),
|
||||
VmNetworkStatsInterval("Advanced", ManagementServer.class, Integer.class, "vm.network.stats.interval", "0", "Interval (in seconds) to report vm network statistics (for Shared networks).", null),
|
||||
VmTransitionWaitInterval(
|
||||
"Advanced",
|
||||
ManagementServer.class,
|
||||
|
||||
@ -62,9 +62,13 @@ import com.cloud.agent.api.HostStatsEntry;
|
||||
import com.cloud.agent.api.PerformanceMonitorCommand;
|
||||
import com.cloud.agent.api.VgpuTypesInfo;
|
||||
import com.cloud.agent.api.VmDiskStatsEntry;
|
||||
import com.cloud.agent.api.VmNetworkStatsEntry;
|
||||
import com.cloud.agent.api.VmStatsEntry;
|
||||
import com.cloud.cluster.ManagementServerHostVO;
|
||||
import com.cloud.cluster.dao.ManagementServerHostDao;
|
||||
import com.cloud.dc.Vlan.VlanType;
|
||||
import com.cloud.dc.VlanVO;
|
||||
import com.cloud.dc.dao.VlanDao;
|
||||
import com.cloud.exception.StorageUnavailableException;
|
||||
import com.cloud.gpu.dao.HostGpuGroupsDao;
|
||||
import com.cloud.host.Host;
|
||||
@ -103,7 +107,9 @@ import com.cloud.storage.VolumeStats;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.StoragePoolHostDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
import com.cloud.user.UserStatisticsVO;
|
||||
import com.cloud.user.VmDiskStatisticsVO;
|
||||
import com.cloud.user.dao.UserStatisticsDao;
|
||||
import com.cloud.user.dao.VmDiskStatisticsDao;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
@ -117,11 +123,13 @@ import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.TransactionCallbackNoReturn;
|
||||
import com.cloud.utils.db.TransactionStatus;
|
||||
import com.cloud.utils.net.MacAddress;
|
||||
import com.cloud.vm.NicVO;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VmStats;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@ -186,6 +194,12 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
|
||||
@Inject
|
||||
private ManagementServerHostDao _msHostDao;
|
||||
@Inject
|
||||
private UserStatisticsDao _userStatsDao;
|
||||
@Inject
|
||||
private NicDao _nicDao;
|
||||
@Inject
|
||||
private VlanDao _vlanDao;
|
||||
@Inject
|
||||
private AutoScaleVmGroupDao _asGroupDao;
|
||||
@Inject
|
||||
private AutoScaleVmGroupVmMapDao _asGroupVmDao;
|
||||
@ -225,6 +239,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
|
||||
long volumeStatsInterval = -1L;
|
||||
long autoScaleStatsInterval = -1L;
|
||||
int vmDiskStatsInterval = 0;
|
||||
int vmNetworkStatsInterval = 0;
|
||||
List<Long> hostIds = null;
|
||||
private double _imageStoreCapacityThreshold = 0.90;
|
||||
|
||||
@ -272,6 +287,7 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
|
||||
volumeStatsInterval = NumbersUtil.parseLong(configs.get("volume.stats.interval"), -1L);
|
||||
autoScaleStatsInterval = NumbersUtil.parseLong(configs.get("autoscale.stats.interval"), 60000L);
|
||||
vmDiskStatsInterval = NumbersUtil.parseInt(configs.get("vm.disk.stats.interval"), 0);
|
||||
vmNetworkStatsInterval = NumbersUtil.parseInt(configs.get("vm.network.stats.interval"), 0);
|
||||
|
||||
/* URI to send statistics to. Currently only Graphite is supported */
|
||||
String externalStatsUri = configs.get("stats.output.uri");
|
||||
@ -335,8 +351,17 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
|
||||
_executor.scheduleAtFixedRate(new VmDiskStatsTask(), vmDiskStatsInterval, vmDiskStatsInterval, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
if (vmNetworkStatsInterval > 0) {
|
||||
if (vmNetworkStatsInterval < 300)
|
||||
vmNetworkStatsInterval = 300;
|
||||
_executor.scheduleAtFixedRate(new VmNetworkStatsTask(), vmNetworkStatsInterval, vmNetworkStatsInterval, TimeUnit.SECONDS);
|
||||
} else {
|
||||
s_logger.debug("vm.network.stats.interval - " + vmNetworkStatsInterval + " so not scheduling the vm network stats thread");
|
||||
}
|
||||
|
||||
//Schedule disk stats update task
|
||||
_diskStatsUpdateExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("DiskStatsUpdater"));
|
||||
|
||||
String aggregationRange = configs.get("usage.stats.job.aggregation.range");
|
||||
_usageAggregationRange = NumbersUtil.parseInt(aggregationRange, 1440);
|
||||
_usageTimeZone = configs.get("usage.aggregation.timezone");
|
||||
@ -641,11 +666,20 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
|
||||
class VmDiskStatsTask extends ManagedContextRunnable {
|
||||
@Override
|
||||
protected void runInContext() {
|
||||
//Check for ownership
|
||||
//msHost in UP state with min id should run the job
|
||||
ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L));
|
||||
if(msHost == null || (msHost.getMsid() != mgmtSrvrId)){
|
||||
s_logger.debug("Skipping collect vm disk stats from hosts");
|
||||
return;
|
||||
}
|
||||
// collect the vm disk statistics(total) from hypervisor. added by weizhou, 2013.03.
|
||||
try {
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
s_logger.debug("VmDiskStatsTask is running...");
|
||||
|
||||
SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
|
||||
sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
|
||||
sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance,
|
||||
@ -763,6 +797,121 @@ public class StatsCollector extends ManagerBase implements ComponentMethodInterc
|
||||
}
|
||||
}
|
||||
|
||||
class VmNetworkStatsTask extends ManagedContextRunnable {
|
||||
@Override
|
||||
protected void runInContext() {
|
||||
//Check for ownership
|
||||
//msHost in UP state with min id should run the job
|
||||
ManagementServerHostVO msHost = _msHostDao.findOneInUpState(new Filter(ManagementServerHostVO.class, "id", true, 0L, 1L));
|
||||
if(msHost == null || (msHost.getMsid() != mgmtSrvrId)){
|
||||
s_logger.debug("Skipping collect vm network stats from hosts");
|
||||
return;
|
||||
}
|
||||
// collect the vm network statistics(total) from hypervisor
|
||||
try {
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
s_logger.debug("VmNetworkStatsTask is running...");
|
||||
|
||||
SearchCriteria<HostVO> sc = _hostDao.createSearchCriteria();
|
||||
sc.addAnd("status", SearchCriteria.Op.EQ, Status.Up.toString());
|
||||
sc.addAnd("resourceState", SearchCriteria.Op.NIN, ResourceState.Maintenance, ResourceState.PrepareForMaintenance, ResourceState.ErrorInMaintenance);
|
||||
sc.addAnd("type", SearchCriteria.Op.EQ, Host.Type.Routing.toString());
|
||||
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) {
|
||||
if (vm.getType() == VirtualMachine.Type.User) // user vm
|
||||
vmIds.add(vm.getId());
|
||||
}
|
||||
|
||||
HashMap<Long, List<VmNetworkStatsEntry>> vmNetworkStatsById = _userVmMgr.getVmNetworkStatistics(host.getId(), host.getName(), vmIds);
|
||||
if (vmNetworkStatsById == null)
|
||||
continue;
|
||||
|
||||
Set<Long> vmIdSet = vmNetworkStatsById.keySet();
|
||||
for(Long vmId : vmIdSet)
|
||||
{
|
||||
List<VmNetworkStatsEntry> vmNetworkStats = vmNetworkStatsById.get(vmId);
|
||||
if (vmNetworkStats == null)
|
||||
continue;
|
||||
UserVmVO userVm = _userVmDao.findById(vmId);
|
||||
for (VmNetworkStatsEntry vmNetworkStat:vmNetworkStats) {
|
||||
SearchCriteria<NicVO> sc_nic = _nicDao.createSearchCriteria();
|
||||
sc_nic.addAnd("macAddress", SearchCriteria.Op.EQ, vmNetworkStat.getMacAddress());
|
||||
NicVO nic = _nicDao.search(sc_nic, null).get(0);
|
||||
List<VlanVO> vlan = _vlanDao.listVlansByNetworkId(nic.getNetworkId());
|
||||
if (vlan == null || vlan.size() == 0 || vlan.get(0).getVlanType() != VlanType.DirectAttached)
|
||||
continue; // only get network statistics for DirectAttached network (shared networks in Basic zone and Advanced zone with/without SG)
|
||||
UserStatisticsVO previousvmNetworkStats = _userStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), vmId, "UserVm");
|
||||
if (previousvmNetworkStats == null) {
|
||||
previousvmNetworkStats = new UserStatisticsVO(userVm.getAccountId(), userVm.getDataCenterId(),nic.getIPv4Address(), vmId, "UserVm", nic.getNetworkId());
|
||||
_userStatsDao.persist(previousvmNetworkStats);
|
||||
}
|
||||
UserStatisticsVO vmNetworkStat_lock = _userStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), vmId, "UserVm");
|
||||
|
||||
if ((vmNetworkStat.getBytesSent() == 0) && (vmNetworkStat.getBytesReceived() == 0)) {
|
||||
s_logger.debug("bytes sent and received are all 0. Not updating user_statistics");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vmNetworkStat_lock == null) {
|
||||
s_logger.warn("unable to find vm network stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and nicId:" + nic.getId());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (previousvmNetworkStats != null
|
||||
&& ((previousvmNetworkStats.getCurrentBytesSent() != vmNetworkStat_lock.getCurrentBytesSent())
|
||||
|| (previousvmNetworkStats.getCurrentBytesReceived() != vmNetworkStat_lock.getCurrentBytesReceived()))) {
|
||||
s_logger.debug("vm network stats changed from the time GetNmNetworkStatsCommand was sent. " +
|
||||
"Ignoring current answer. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() +
|
||||
" Sent(Bytes): " + vmNetworkStat.getBytesSent() + " Received(Bytes): " + vmNetworkStat.getBytesReceived());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vmNetworkStat_lock.getCurrentBytesSent() > vmNetworkStat.getBytesSent()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Sent # of bytes that's less than the last one. " +
|
||||
"Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() +
|
||||
" Reported: " + vmNetworkStat.getBytesSent() + " Stored: " + vmNetworkStat_lock.getCurrentBytesSent());
|
||||
}
|
||||
vmNetworkStat_lock.setNetBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent());
|
||||
}
|
||||
vmNetworkStat_lock.setCurrentBytesSent(vmNetworkStat.getBytesSent());
|
||||
|
||||
if (vmNetworkStat_lock.getCurrentBytesReceived() > vmNetworkStat.getBytesReceived()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Received # of bytes that's less than the last one. " +
|
||||
"Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() +
|
||||
" Reported: " + vmNetworkStat.getBytesReceived() + " Stored: " + vmNetworkStat_lock.getCurrentBytesReceived());
|
||||
}
|
||||
vmNetworkStat_lock.setNetBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived());
|
||||
}
|
||||
vmNetworkStat_lock.setCurrentBytesReceived(vmNetworkStat.getBytesReceived());
|
||||
|
||||
if (! _dailyOrHourly) {
|
||||
//update agg bytes
|
||||
vmNetworkStat_lock.setAggBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived());
|
||||
vmNetworkStat_lock.setAggBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent());
|
||||
}
|
||||
|
||||
_userStatsDao.update(vmNetworkStat_lock.getId(), vmNetworkStat_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Error while collecting vm network stats from hosts", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class StorageCollector extends ManagedContextRunnable {
|
||||
@Override
|
||||
protected void runInContext() {
|
||||
|
||||
@ -84,6 +84,7 @@ import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.vm.UserVmService;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
@ -205,6 +206,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
@Inject
|
||||
UserVmDao _userVmDao;
|
||||
@Inject
|
||||
UserVmService _userVmService;
|
||||
@Inject
|
||||
VolumeDataStoreDao _volumeStoreDao;
|
||||
@Inject
|
||||
VMInstanceDao _vmInstanceDao;
|
||||
@ -1799,6 +1802,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
Answer answer = null;
|
||||
|
||||
if (sendCommand) {
|
||||
// collect vm disk statistics before detach a volume
|
||||
UserVmVO userVm = _userVmDao.findById(vmId);
|
||||
if (userVm != null && userVm.getType() == VirtualMachine.Type.User) {
|
||||
_userVmService.collectVmDiskStatistics(userVm);
|
||||
}
|
||||
|
||||
DataTO volTO = volFactory.getVolume(volume.getId()).getTO();
|
||||
DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());
|
||||
|
||||
|
||||
@ -24,6 +24,7 @@ import org.apache.cloudstack.api.BaseCmd.HTTPMethod;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
import com.cloud.agent.api.VmDiskStatsEntry;
|
||||
import com.cloud.agent.api.VmNetworkStatsEntry;
|
||||
import com.cloud.agent.api.VmStatsEntry;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
@ -100,8 +101,6 @@ public interface UserVmManager extends UserVmService {
|
||||
|
||||
boolean setupVmForPvlan(boolean add, Long hostId, NicProfile nic);
|
||||
|
||||
void collectVmDiskStatistics(UserVmVO userVm);
|
||||
|
||||
UserVm updateVirtualMachine(long id, String displayName, String group, Boolean ha, Boolean isDisplayVmEnabled, Long osTypeId, String userData,
|
||||
Boolean isDynamicallyScalable, HTTPMethod httpMethod, String customId, String hostName, String instanceName, List<Long> securityGroupIdList) throws ResourceUnavailableException, InsufficientCapacityException;
|
||||
|
||||
@ -116,4 +115,6 @@ public interface UserVmManager extends UserVmService {
|
||||
void generateUsageEvent(VirtualMachine vm, boolean isDisplay, String eventType);
|
||||
|
||||
void persistDeviceBusInfo(UserVmVO paramUserVmVO, String paramString);
|
||||
|
||||
HashMap<Long, List<VmNetworkStatsEntry>> getVmNetworkStatistics(long hostId, String hostName, List<Long> vmIds);
|
||||
}
|
||||
|
||||
@ -99,6 +99,8 @@ import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.GetVmDiskStatsAnswer;
|
||||
import com.cloud.agent.api.GetVmDiskStatsCommand;
|
||||
import com.cloud.agent.api.GetVmIpAddressCommand;
|
||||
import com.cloud.agent.api.GetVmNetworkStatsAnswer;
|
||||
import com.cloud.agent.api.GetVmNetworkStatsCommand;
|
||||
import com.cloud.agent.api.GetVmStatsAnswer;
|
||||
import com.cloud.agent.api.GetVmStatsCommand;
|
||||
import com.cloud.agent.api.PvlanSetupCommand;
|
||||
@ -106,6 +108,7 @@ import com.cloud.agent.api.RestoreVMSnapshotAnswer;
|
||||
import com.cloud.agent.api.RestoreVMSnapshotCommand;
|
||||
import com.cloud.agent.api.StartAnswer;
|
||||
import com.cloud.agent.api.VmDiskStatsEntry;
|
||||
import com.cloud.agent.api.VmNetworkStatsEntry;
|
||||
import com.cloud.agent.api.VmStatsEntry;
|
||||
import com.cloud.agent.api.to.DiskTO;
|
||||
import com.cloud.agent.api.to.NicTO;
|
||||
@ -128,6 +131,9 @@ import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.dc.dao.DedicatedResourceDao;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.dc.dao.VlanDao;
|
||||
import com.cloud.dc.Vlan.VlanType;
|
||||
import com.cloud.dc.VlanVO;
|
||||
import com.cloud.deploy.DataCenterDeployment;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.deploy.DeploymentPlanner;
|
||||
@ -248,11 +254,13 @@ import com.cloud.user.ResourceLimitService;
|
||||
import com.cloud.user.SSHKeyPair;
|
||||
import com.cloud.user.SSHKeyPairVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserStatisticsVO;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.user.VmDiskStatisticsVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.SSHKeyPairDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.user.dao.UserStatisticsDao;
|
||||
import com.cloud.user.dao.VmDiskStatisticsDao;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.DateUtil;
|
||||
@ -454,6 +462,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
@Inject
|
||||
private ServiceOfferingDetailsDao serviceOfferingDetailsDao;
|
||||
@Inject
|
||||
private UserStatisticsDao _userStatsDao;
|
||||
@Inject
|
||||
private VlanDao _vlanDao;
|
||||
@Inject
|
||||
VolumeService _volService;
|
||||
@Inject
|
||||
VolumeDataFactory volFactory;
|
||||
@ -902,6 +914,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
|
||||
if (vm.getState() == State.Running && vm.getHostId() != null) {
|
||||
collectVmDiskStatistics(vm);
|
||||
collectVmNetworkStatistics(vm);
|
||||
DataCenterVO dc = _dcDao.findById(vm.getDataCenterId());
|
||||
try {
|
||||
if (dc.getNetworkType() == DataCenter.NetworkType.Advanced) {
|
||||
@ -3689,6 +3702,144 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Long, List<VmNetworkStatsEntry>> getVmNetworkStatistics(long hostId, String hostName, List<Long> vmIds) {
|
||||
HashMap<Long, List<VmNetworkStatsEntry>> vmNetworkStatsById = new HashMap<Long, List<VmNetworkStatsEntry>>();
|
||||
|
||||
if (vmIds.isEmpty()) {
|
||||
return vmNetworkStatsById;
|
||||
}
|
||||
|
||||
List<String> vmNames = new ArrayList<String>();
|
||||
|
||||
for (Long vmId : vmIds) {
|
||||
UserVmVO vm = _vmDao.findById(vmId);
|
||||
vmNames.add(vm.getInstanceName());
|
||||
}
|
||||
|
||||
Answer answer = _agentMgr.easySend(hostId, new GetVmNetworkStatsCommand(vmNames, _hostDao.findById(hostId).getGuid(), hostName));
|
||||
if (answer == null || !answer.getResult()) {
|
||||
s_logger.warn("Unable to obtain VM network statistics.");
|
||||
return null;
|
||||
} else {
|
||||
HashMap<String, List<VmNetworkStatsEntry>> vmNetworkStatsByName = ((GetVmNetworkStatsAnswer)answer).getVmNetworkStatsMap();
|
||||
|
||||
if (vmNetworkStatsByName == null) {
|
||||
s_logger.warn("Unable to obtain VM network statistics.");
|
||||
return null;
|
||||
}
|
||||
|
||||
for (String vmName : vmNetworkStatsByName.keySet()) {
|
||||
vmNetworkStatsById.put(vmIds.get(vmNames.indexOf(vmName)), vmNetworkStatsByName.get(vmName));
|
||||
}
|
||||
}
|
||||
|
||||
return vmNetworkStatsById;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectVmNetworkStatistics (final UserVm userVm) {
|
||||
if (!userVm.getHypervisorType().equals(HypervisorType.KVM))
|
||||
return;
|
||||
s_logger.debug("Collect vm network statistics from host before stopping Vm");
|
||||
long hostId = userVm.getHostId();
|
||||
List<String> vmNames = new ArrayList<String>();
|
||||
vmNames.add(userVm.getInstanceName());
|
||||
final HostVO host = _hostDao.findById(hostId);
|
||||
|
||||
GetVmNetworkStatsAnswer networkStatsAnswer = null;
|
||||
try {
|
||||
networkStatsAnswer = (GetVmNetworkStatsAnswer) _agentMgr.easySend(hostId, new GetVmNetworkStatsCommand(vmNames, host.getGuid(), host.getName()));
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Error while collecting network stats for vm: " + userVm.getHostName() + " from host: " + host.getName(), e);
|
||||
return;
|
||||
}
|
||||
if (networkStatsAnswer != null) {
|
||||
if (!networkStatsAnswer.getResult()) {
|
||||
s_logger.warn("Error while collecting network stats vm: " + userVm.getHostName() + " from host: " + host.getName() + "; details: " + networkStatsAnswer.getDetails());
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final GetVmNetworkStatsAnswer networkStatsAnswerFinal = networkStatsAnswer;
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
HashMap<String, List<VmNetworkStatsEntry>> vmNetworkStatsByName = networkStatsAnswerFinal.getVmNetworkStatsMap();
|
||||
if (vmNetworkStatsByName == null)
|
||||
return;
|
||||
List<VmNetworkStatsEntry> vmNetworkStats = vmNetworkStatsByName.get(userVm.getInstanceName());
|
||||
if (vmNetworkStats == null)
|
||||
return;
|
||||
|
||||
for (VmNetworkStatsEntry vmNetworkStat:vmNetworkStats) {
|
||||
SearchCriteria<NicVO> sc_nic = _nicDao.createSearchCriteria();
|
||||
sc_nic.addAnd("macAddress", SearchCriteria.Op.EQ, vmNetworkStat.getMacAddress());
|
||||
NicVO nic = _nicDao.search(sc_nic, null).get(0);
|
||||
List<VlanVO> vlan = _vlanDao.listVlansByNetworkId(nic.getNetworkId());
|
||||
if (vlan == null || vlan.size() == 0 || vlan.get(0).getVlanType() != VlanType.DirectAttached)
|
||||
break; // only get network statistics for DirectAttached network (shared networks in Basic zone and Advanced zone with/without SG)
|
||||
UserStatisticsVO previousvmNetworkStats = _userStatsDao.findBy(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), userVm.getId(), "UserVm");
|
||||
if (previousvmNetworkStats == null) {
|
||||
previousvmNetworkStats = new UserStatisticsVO(userVm.getAccountId(), userVm.getDataCenterId(),nic.getIPv4Address(), userVm.getId(), "UserVm", nic.getNetworkId());
|
||||
_userStatsDao.persist(previousvmNetworkStats);
|
||||
}
|
||||
UserStatisticsVO vmNetworkStat_lock = _userStatsDao.lock(userVm.getAccountId(), userVm.getDataCenterId(), nic.getNetworkId(), nic.getIPv4Address(), userVm.getId(), "UserVm");
|
||||
|
||||
if ((vmNetworkStat.getBytesSent() == 0) && (vmNetworkStat.getBytesReceived() == 0)) {
|
||||
s_logger.debug("bytes sent and received are all 0. Not updating user_statistics");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vmNetworkStat_lock == null) {
|
||||
s_logger.warn("unable to find vm network stats from host for account: " + userVm.getAccountId() + " with vmId: " + userVm.getId()+ " and nicId:" + nic.getId());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (previousvmNetworkStats != null
|
||||
&& ((previousvmNetworkStats.getCurrentBytesSent() != vmNetworkStat_lock.getCurrentBytesSent())
|
||||
|| (previousvmNetworkStats.getCurrentBytesReceived() != vmNetworkStat_lock.getCurrentBytesReceived()))) {
|
||||
s_logger.debug("vm network stats changed from the time GetNmNetworkStatsCommand was sent. " +
|
||||
"Ignoring current answer. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() +
|
||||
" Sent(Bytes): " + vmNetworkStat.getBytesSent() + " Received(Bytes): " + vmNetworkStat.getBytesReceived());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vmNetworkStat_lock.getCurrentBytesSent() > vmNetworkStat.getBytesSent()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Sent # of bytes that's less than the last one. " +
|
||||
"Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() +
|
||||
" Reported: " + vmNetworkStat.getBytesSent() + " Stored: " + vmNetworkStat_lock.getCurrentBytesSent());
|
||||
}
|
||||
vmNetworkStat_lock.setNetBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent());
|
||||
}
|
||||
vmNetworkStat_lock.setCurrentBytesSent(vmNetworkStat.getBytesSent());
|
||||
|
||||
if (vmNetworkStat_lock.getCurrentBytesReceived() > vmNetworkStat.getBytesReceived()) {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Received # of bytes that's less than the last one. " +
|
||||
"Assuming something went wrong and persisting it. Host: " + host.getName() + " . VM: " + vmNetworkStat.getVmName() +
|
||||
" Reported: " + vmNetworkStat.getBytesReceived() + " Stored: " + vmNetworkStat_lock.getCurrentBytesReceived());
|
||||
}
|
||||
vmNetworkStat_lock.setNetBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived());
|
||||
}
|
||||
vmNetworkStat_lock.setCurrentBytesReceived(vmNetworkStat.getBytesReceived());
|
||||
|
||||
if (! _dailyOrHourly) {
|
||||
//update agg bytes
|
||||
vmNetworkStat_lock.setAggBytesReceived(vmNetworkStat_lock.getNetBytesReceived() + vmNetworkStat_lock.getCurrentBytesReceived());
|
||||
vmNetworkStat_lock.setAggBytesSent(vmNetworkStat_lock.getNetBytesSent() + vmNetworkStat_lock.getCurrentBytesSent());
|
||||
}
|
||||
|
||||
_userStatsDao.update(vmNetworkStat_lock.getId(), vmNetworkStat_lock);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Unable to update vm network statistics for vm: " + userVm.getId() + " from host: " + hostId, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateUserData(String userData, HTTPMethod httpmethod) {
|
||||
byte[] decodedUserData = null;
|
||||
if (userData != null) {
|
||||
@ -4232,7 +4383,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectVmDiskStatistics(final UserVmVO userVm) {
|
||||
public void collectVmDiskStatistics(final UserVm userVm) {
|
||||
// support KVM only util 2013.06.25
|
||||
if (!userVm.getHypervisorType().equals(HypervisorType.KVM))
|
||||
return;
|
||||
@ -4748,6 +4899,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
UserVmVO uservm = _vmDao.findById(vmId);
|
||||
if (uservm != null) {
|
||||
collectVmDiskStatistics(uservm);
|
||||
collectVmNetworkStatistics(uservm);
|
||||
}
|
||||
_itMgr.migrate(vm.getUuid(), srcHostId, dest);
|
||||
VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
|
||||
@ -5871,8 +6023,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
@Override
|
||||
public void prepareStop(VirtualMachineProfile profile) {
|
||||
UserVmVO vm = _vmDao.findById(profile.getId());
|
||||
if (vm != null && vm.getState() == State.Stopping)
|
||||
if (vm != null && vm.getState() == State.Stopping) {
|
||||
collectVmDiskStatistics(vm);
|
||||
collectVmNetworkStatistics(vm);
|
||||
}
|
||||
}
|
||||
|
||||
private void encryptAndStorePassword(UserVmVO vm, String password) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user