CLOUDSTACK-9783: Improve metrics view performance

This improves the metrics view feature by improving the rendering performance
of metrics view tables, by reimplementing the logic at the backend and data
served via APIs. In large environments, the older implementation would
make several API calls that increases both network and database load.

List of APIs introduced for improving the performance:

    listClustersMetrics
    listHostsMetrics
    listInfrastructure
    listStoragePoolsMetrics
    listVMsMetrics
    listVolumesMetrics
    listZonesMetrics

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Rohit Yadav 2017-02-16 13:45:15 +05:30
parent b95bf8fcd8
commit 402253504e
42 changed files with 2922 additions and 920 deletions

View File

@ -48,6 +48,7 @@ env:
smoke/test_list_ids_parameter
smoke/test_loadbalance
smoke/test_login
smoke/test_metrics_api
smoke/test_multipleips_per_nic
smoke/test_network
smoke/test_network_acl

View File

@ -125,18 +125,22 @@ public class ListClustersCmd extends BaseListCmd {
return s_name;
}
@Override
public void execute() {
protected List<ClusterResponse> getClusterResponses() {
Pair<List<? extends Cluster>, Integer> result = _mgr.searchForClusters(this);
ListResponse<ClusterResponse> response = new ListResponse<ClusterResponse>();
List<ClusterResponse> clusterResponses = new ArrayList<ClusterResponse>();
for (Cluster cluster : result.first()) {
ClusterResponse clusterResponse = _responseGenerator.createClusterResponse(cluster, showCapacities);
clusterResponse.setObjectName("cluster");
clusterResponses.add(clusterResponse);
}
return clusterResponses;
}
response.setResponses(clusterResponses, result.second());
@Override
public void execute() {
List<ClusterResponse> clusterResponses = getClusterResponses();
ListResponse<ClusterResponse> response = new ListResponse<ClusterResponse>();
response.setResponses(clusterResponses, clusterResponses.size());
response.setResponseName(getCommandName());
this.setResponseObject(response);
}

View File

@ -132,6 +132,10 @@ public class ListHostsCmd extends BaseListCmd {
return state;
}
public void setType(String type) {
this.type = type;
}
public String getType() {
return type;
}
@ -198,19 +202,16 @@ public class ListHostsCmd extends BaseListCmd {
return ApiCommandJobType.Host;
}
@Override
public void execute() {
ListResponse<HostResponse> response = null;
protected ListResponse<HostResponse> getHostResponses() {
ListResponse<HostResponse> response = new ListResponse<>();
if (getVirtualMachineId() == null) {
response = _queryService.searchForServers(this);
} else {
Pair<List<? extends Host>, Integer> result;
Ternary<Pair<List<? extends Host>, Integer>, List<? extends Host>, Map<Host, Boolean>> hostsForMigration =
_mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal());
_mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal());
result = hostsForMigration.first();
List<? extends Host> hostsWithCapacity = hostsForMigration.second();
response = new ListResponse<HostResponse>();
List<HostResponse> hostResponses = new ArrayList<HostResponse>();
for (Host host : result.first()) {
HostResponse hostResponse = _responseGenerator.createHostResponse(host, getDetails());
@ -222,9 +223,14 @@ public class ListHostsCmd extends BaseListCmd {
hostResponse.setObjectName("host");
hostResponses.add(hostResponse);
}
response.setResponses(hostResponses, result.second());
}
return response;
}
@Override
public void execute() {
ListResponse<HostResponse> response = getHostResponses();
response.setResponseName(getCommandName());
this.setResponseObject(response);
}

View File

@ -458,4 +458,163 @@ public class HostResponse extends BaseResponse {
}
public String getName() {
return name;
}
public Status getState() {
return state;
}
public Date getDisconnectedOn() {
return disconnectedOn;
}
public Host.Type getHostType() {
return hostType;
}
public String getOsCategoryId() {
return osCategoryId;
}
public String getOsCategoryName() {
return osCategoryName;
}
public String getIpAddress() {
return ipAddress;
}
public String getZoneId() {
return zoneId;
}
public String getZoneName() {
return zoneName;
}
public String getPodId() {
return podId;
}
public String getPodName() {
return podName;
}
public String getVersion() {
return version;
}
public HypervisorType getHypervisor() {
return hypervisor;
}
public Integer getCpuSockets() {
return cpuSockets;
}
public Integer getCpuNumber() {
return cpuNumber;
}
public Long getCpuSpeed() {
return cpuSpeed;
}
public String getCpuUsed() {
return cpuUsed;
}
public Long getAverageLoad() {
return averageLoad;
}
public Long getNetworkKbsRead() {
return networkKbsRead;
}
public Long getNetworkKbsWrite() {
return networkKbsWrite;
}
public Long getMemoryTotal() {
return memoryTotal;
}
public Long getMemoryAllocated() {
return memoryAllocated;
}
public Long getMemoryUsed() {
return memoryUsed;
}
public List<GpuResponse> getGpuGroup() {
return gpuGroup;
}
public Long getDiskSizeTotal() {
return diskSizeTotal;
}
public Long getDiskSizeAllocated() {
return diskSizeAllocated;
}
public String getCapabilities() {
return capabilities;
}
public Date getLastPinged() {
return lastPinged;
}
public Long getManagementServerId() {
return managementServerId;
}
public String getClusterId() {
return clusterId;
}
public String getClusterName() {
return clusterName;
}
public String getClusterType() {
return clusterType;
}
public Boolean getLocalStorageActive() {
return localStorageActive;
}
public Date getCreated() {
return created;
}
public Date getRemoved() {
return removed;
}
public String getEvents() {
return events;
}
public Boolean getHasEnoughCapacity() {
return hasEnoughCapacity;
}
public Boolean getSuitableForMigration() {
return suitableForMigration;
}
public String getHypervisorVersion() {
return hypervisorVersion;
}
public Boolean getHaHost() {
return haHost;
}
}

View File

@ -16,15 +16,14 @@
// under the License.
package org.apache.cloudstack.api.response;
import java.util.List;
import com.cloud.serializer.Param;
import com.cloud.vm.Nic;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import com.cloud.serializer.Param;
import com.cloud.vm.Nic;
import com.google.gson.annotations.SerializedName;
import java.util.List;
@SuppressWarnings("unused")
@EntityReference(value = Nic.class)
@ -221,4 +220,79 @@ public class NicResponse extends BaseResponse {
this.nsxLogicalSwitchPort = nsxLogicalSwitchPort;
}
public String getNetworkId() {
return networkId;
}
public String getNetworkName() {
return networkName;
}
public String getNetmask() {
return netmask;
}
public String getGateway() {
return gateway;
}
public String getIsolationUri() {
return isolationUri;
}
public String getBroadcastUri() {
return broadcastUri;
}
public String getTrafficType() {
return trafficType;
}
public String getType() {
return type;
}
public Boolean getDefault() {
return isDefault;
}
public String getMacAddress() {
return macAddress;
}
public String getIpaddress() {
return ipaddress;
}
public String getIp6Gateway() {
return ip6Gateway;
}
public String getIp6Cidr() {
return ip6Cidr;
}
public String getIp6Address() {
return ip6Address;
}
public List<NicSecondaryIpResponse> getSecondaryIps() {
return secondaryIps;
}
public String getDeviceId() {
return deviceId;
}
public String getVmId() {
return vmId;
}
public String getNsxLogicalSwitch() {
return nsxLogicalSwitch;
}
public String getNsxLogicalSwitchPort() {
return nsxLogicalSwitchPort;
}
}

View File

@ -309,4 +309,12 @@ public class StoragePoolResponse extends BaseResponse {
public void setOverProvisionFactor(String overProvisionFactor) {
this.overProvisionFactor = overProvisionFactor;
}
public String getOverProvisionFactor() {
return overProvisionFactor;
}
public Boolean getSuitableForMigration() {
return suitableForMigration;
}
}

View File

@ -813,4 +813,28 @@ public class UserVmResponse extends BaseResponseWithTagInformation implements Co
public void setOsTypeId(Long osTypeId) {
this.osTypeId = osTypeId;
}
public Set<Long> getTagIds() {
return tagIds;
}
public void setTagIds(Set<Long> tagIds) {
this.tagIds = tagIds;
}
public Map getDetails() {
return details;
}
public Boolean getDynamicallyScalable() {
return isDynamicallyScalable;
}
public void setDynamicallyScalable(Boolean dynamicallyScalable) {
isDynamicallyScalable = dynamicallyScalable;
}
public Long getOsTypeId() {
return osTypeId;
}
}

View File

@ -16,18 +16,17 @@
// under the License.
package org.apache.cloudstack.api.response;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Set;
import com.cloud.serializer.Param;
import com.cloud.storage.Volume;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponseWithTagInformation;
import org.apache.cloudstack.api.EntityReference;
import com.cloud.serializer.Param;
import com.cloud.storage.Volume;
import com.google.gson.annotations.SerializedName;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Set;
@EntityReference(value = Volume.class)
@SuppressWarnings("unused")
@ -514,4 +513,140 @@ public class VolumeResponse extends BaseResponseWithTagInformation implements Co
public void setTags(Set<ResourceTagResponse> tags) {
this.tags = tags;
}
public String getName() {
return name;
}
public String getZoneId() {
return zoneId;
}
public String getZoneName() {
return zoneName;
}
public String getVolumeType() {
return volumeType;
}
public Long getDeviceId() {
return deviceId;
}
public String getVirtualMachineId() {
return virtualMachineId;
}
public String getVirtualMachineName() {
return virtualMachineName;
}
public String getVirtualMachineDisplayName() {
return virtualMachineDisplayName;
}
public String getVirtualMachineState() {
return virtualMachineState;
}
public String getProvisioningType() {
return provisioningType;
}
public Long getSize() {
return size;
}
public Long getMinIops() {
return minIops;
}
public Long getMaxIops() {
return maxIops;
}
public Date getCreated() {
return created;
}
public String getState() {
return state;
}
public String getAccountName() {
return accountName;
}
public String getProjectId() {
return projectId;
}
public String getProjectName() {
return projectName;
}
public String getDomainId() {
return domainId;
}
public String getDomainName() {
return domainName;
}
public String getStorageType() {
return storageType;
}
public String getHypervisor() {
return hypervisor;
}
public String getDiskOfferingId() {
return diskOfferingId;
}
public String getDiskOfferingName() {
return diskOfferingName;
}
public String getDiskOfferingDisplayText() {
return diskOfferingDisplayText;
}
public String getStoragePoolName() {
return storagePoolName;
}
public String getSnapshotId() {
return snapshotId;
}
public Date getAttached() {
return attached;
}
public String getServiceOfferingId() {
return serviceOfferingId;
}
public String getServiceOfferingName() {
return serviceOfferingName;
}
public String getServiceOfferingDisplayText() {
return serviceOfferingDisplayText;
}
public Boolean getExtractable() {
return extractable;
}
public String getStatus() {
return status;
}
public Boolean getDisplayVolume() {
return displayVolume;
}
}

View File

@ -239,4 +239,92 @@ public class ZoneResponse extends BaseResponse {
}
this.resourceDetails = new HashMap<>(details);
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public String getDns1() {
return dns1;
}
public String getDns2() {
return dns2;
}
public String getInternalDns1() {
return internalDns1;
}
public String getInternalDns2() {
return internalDns2;
}
public String getGuestCidrAddress() {
return guestCidrAddress;
}
public String getStatus() {
return status;
}
public String getDisplayText() {
return displayText;
}
public String getDomain() {
return domain;
}
public String getDomainId() {
return domainId;
}
public String getDomainName() {
return domainName;
}
public String getNetworkType() {
return networkType;
}
public boolean isSecurityGroupsEnabled() {
return securityGroupsEnabled;
}
public String getAllocationState() {
return allocationState;
}
public String getZoneToken() {
return zoneToken;
}
public String getDhcpProvider() {
return dhcpProvider;
}
public List<CapacityResponse> getCapacitites() {
return capacitites;
}
public boolean isLocalStorageEnabled() {
return localStorageEnabled;
}
public Set<ResourceTagResponse> getTags() {
return tags;
}
public Map<String, String> getResourceDetails() {
return resourceDetails;
}
}

View File

@ -101,6 +101,11 @@
<artifactId>cloud-plugin-user-authenticator-sha256salted</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-metrics</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-plugin-network-nvp</artifactId>

View File

@ -16,13 +16,13 @@
// under the License.
package com.cloud.dc.dao;
import java.util.List;
import java.util.Map;
import com.cloud.dc.ClusterVO;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.utils.db.GenericDao;
import java.util.List;
import java.util.Map;
public interface ClusterDao extends GenericDao<ClusterVO, Long> {
List<ClusterVO> listByPodId(long podId);
@ -44,7 +44,7 @@ public interface ClusterDao extends GenericDao<ClusterVO, Long> {
List<ClusterVO> listClustersByDcId(long zoneId);
List<Long> listAllCusters(long zoneId);
List<Long> listAllClusters(Long zoneId);
boolean getSupportsResigning(long clusterId);
}

View File

@ -16,18 +16,6 @@
// under the License.
package com.cloud.dc.dao;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import org.springframework.stereotype.Component;
import com.cloud.dc.ClusterDetailsDao;
import com.cloud.dc.ClusterDetailsVO;
import com.cloud.dc.ClusterVO;
@ -43,6 +31,16 @@ import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.exception.CloudRuntimeException;
import org.springframework.stereotype.Component;
import javax.inject.Inject;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements ClusterDao {
@ -259,9 +257,11 @@ public class ClusterDaoImpl extends GenericDaoBase<ClusterVO, Long> implements C
}
@Override
public List<Long> listAllCusters(long zoneId) {
public List<Long> listAllClusters(Long zoneId) {
SearchCriteria<Long> sc = ClusterIdSearch.create();
sc.setParameters("dataCenterId", zoneId);
if (zoneId != null) {
sc.setParameters("dataCenterId", zoneId);
}
return customSearch(sc, null);
}

View File

@ -31,5 +31,5 @@ public interface HostPodDao extends GenericDao<HostPodVO, Long> {
public List<Long> listDisabledPods(long zoneId);
public List<Long> listAllPods(long zoneId);
public List<Long> listAllPods(Long zoneId);
}

View File

@ -130,9 +130,11 @@ public class HostPodDaoImpl extends GenericDaoBase<HostPodVO, Long> implements H
}
@Override
public List<Long> listAllPods(long zoneId) {
public List<Long> listAllPods(Long zoneId) {
SearchCriteria<Long> sc = PodIdSearch.create();
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
if (zoneId != null) {
sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
}
return customSearch(sc, null);
}
}

55
plugins/metrics/pom.xml Normal file
View File

@ -0,0 +1,55 @@
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-plugin-metrics</artifactId>
<name>Apache CloudStack Plugin - Metrics</name>
<parent>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloudstack-plugins</artifactId>
<version>4.9.3.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-utils</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Xmx1024m</argLine>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,18 @@
# 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.
name=metrics
parent=api

View File

@ -0,0 +1,27 @@
<!--
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.
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<bean id="metricsService" class="org.apache.cloudstack.metrics.MetricsServiceImpl" >
</bean>
</beans>

View File

@ -0,0 +1,51 @@
// 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 org.apache.cloudstack.api;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.metrics.MetricsService;
import org.apache.cloudstack.response.ClusterMetricsResponse;
import javax.inject.Inject;
import java.util.List;
@APICommand(name = ListClustersMetricsCmd.APINAME, description = "Lists clusters metrics", responseObject = ClusterMetricsResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, responseView = ResponseObject.ResponseView.Full,
since = "4.9.3", authorized = {RoleType.Admin})
public class ListClustersMetricsCmd extends ListClustersCmd {
public static final String APINAME = "listClustersMetrics";
@Inject
private MetricsService metricsService;
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
@Override
public void execute() {
final List<ClusterMetricsResponse> metricsResponses = metricsService.listClusterMetrics(getClusterResponses());
ListResponse<ClusterMetricsResponse> response = new ListResponse<>();
response.setResponses(metricsResponses, metricsResponses.size());
response.setResponseName(getCommandName());
setResponseObject(response);
}
}

View File

@ -0,0 +1,54 @@
// 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 org.apache.cloudstack.api;
import com.cloud.host.Host;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.metrics.MetricsService;
import org.apache.cloudstack.response.HostMetricsResponse;
import javax.inject.Inject;
import java.util.List;
@APICommand(name = ListHostsMetricsCmd.APINAME, description = "Lists hosts metrics", responseObject = HostMetricsResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, responseView = ResponseObject.ResponseView.Full,
since = "4.9.3", authorized = {RoleType.Admin})
public class ListHostsMetricsCmd extends ListHostsCmd {
public static final String APINAME = "listHostsMetrics";
@Inject
private MetricsService metricsService;
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
@Override
public void execute() {
setType(Host.Type.Routing.toString());
final List<HostMetricsResponse> metricsResponses = metricsService.listHostMetrics(getHostResponses().getResponses());
ListResponse<HostMetricsResponse> response = new ListResponse<>();
response.setResponses(metricsResponses, metricsResponses.size());
response.setResponseName(getCommandName());
setResponseObject(response);
}
}

View File

@ -0,0 +1,52 @@
// 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 org.apache.cloudstack.api;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.metrics.MetricsService;
import org.apache.cloudstack.response.InfrastructureResponse;
import javax.inject.Inject;
@APICommand(name = ListInfrastructureCmd.APINAME, description = "Lists infrastructure", responseObject = InfrastructureResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, responseView = ResponseObject.ResponseView.Full,
since = "4.9.3", authorized = {RoleType.Admin})
public class ListInfrastructureCmd extends BaseCmd {
public static final String APINAME = "listInfrastructure";
@Inject
private MetricsService metricsService;
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccountId();
}
@Override
public void execute() {
final InfrastructureResponse response = metricsService.listInfrastructure();
response.setResponseName(getCommandName());
setResponseObject(response);
}
}

View File

@ -0,0 +1,52 @@
// 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 org.apache.cloudstack.api;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.metrics.MetricsService;
import org.apache.cloudstack.response.StoragePoolMetricsResponse;
import javax.inject.Inject;
import java.util.List;
@APICommand(name = ListStoragePoolsMetricsCmd.APINAME, description = "Lists storage pool metrics", responseObject = StoragePoolMetricsResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, responseView = ResponseObject.ResponseView.Full,
since = "4.9.3", authorized = {RoleType.Admin})
public class ListStoragePoolsMetricsCmd extends ListStoragePoolsCmd {
public static final String APINAME = "listStoragePoolsMetrics";
@Inject
private MetricsService metricsService;
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
@Override
public void execute() {
final List<StoragePoolMetricsResponse> metricsResponses = metricsService.listStoragePoolMetrics(_queryService.searchForStoragePools(this).getResponses());
ListResponse<StoragePoolMetricsResponse> response = new ListResponse<>();
response.setResponses(metricsResponses, metricsResponses.size());
response.setResponseName(getCommandName());
setResponseObject(response);
}
}

View File

@ -0,0 +1,51 @@
// 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 org.apache.cloudstack.api;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.command.admin.vm.ListVMsCmdByAdmin;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.metrics.MetricsService;
import org.apache.cloudstack.response.VmMetricsResponse;
import javax.inject.Inject;
import java.util.List;
@APICommand(name = ListVMsMetricsCmd.APINAME, description = "Lists VM metrics", responseObject = VmMetricsResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, responseView = ResponseObject.ResponseView.Full,
since = "4.9.3", authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class ListVMsMetricsCmd extends ListVMsCmdByAdmin {
public static final String APINAME = "listVirtualMachinesMetrics";
@Inject
private MetricsService metricsService;
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
@Override
public void execute() {
final List<VmMetricsResponse> metricsResponses = metricsService.listVmMetrics(_queryService.searchForUserVMs(this).getResponses());
ListResponse<VmMetricsResponse> response = new ListResponse<>();
response.setResponses(metricsResponses, metricsResponses.size());
response.setResponseName(getCommandName());
setResponseObject(response);
}
}

View File

@ -0,0 +1,51 @@
// 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 org.apache.cloudstack.api;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.command.admin.volume.ListVolumesCmdByAdmin;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.metrics.MetricsService;
import org.apache.cloudstack.response.VolumeMetricsResponse;
import javax.inject.Inject;
import java.util.List;
@APICommand(name = ListVolumesMetricsCmd.APINAME, description = "Lists volume metrics", responseObject = VolumeMetricsResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, responseView = ResponseObject.ResponseView.Full,
since = "4.9.3", authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class ListVolumesMetricsCmd extends ListVolumesCmdByAdmin {
public static final String APINAME = "listVolumesMetrics";
@Inject
private MetricsService metricsService;
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
@Override
public void execute() {
final List<VolumeMetricsResponse> metricsResponses = metricsService.listVolumeMetrics(_queryService.searchForVolumes(this).getResponses());
ListResponse<VolumeMetricsResponse> response = new ListResponse<>();
response.setResponses(metricsResponses, metricsResponses.size());
response.setResponseName(getCommandName());
setResponseObject(response);
}
}

View File

@ -0,0 +1,52 @@
// 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 org.apache.cloudstack.api;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.command.user.zone.ListZonesCmd;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.metrics.MetricsService;
import org.apache.cloudstack.response.ZoneMetricsResponse;
import javax.inject.Inject;
import java.util.List;
@APICommand(name = ListZonesMetricsCmd.APINAME, description = "Lists zone metrics", responseObject = ZoneMetricsResponse.class,
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, responseView = ResponseObject.ResponseView.Full,
since = "4.9.3", authorized = {RoleType.Admin})
public class ListZonesMetricsCmd extends ListZonesCmd {
public static final String APINAME = "listZonesMetrics";
@Inject
private MetricsService metricsService;
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
@Override
public void execute() {
final List<ZoneMetricsResponse> metricsResponses = metricsService.listZoneMetrics(_queryService.listDataCenters(this).getResponses());
ListResponse<ZoneMetricsResponse> response = new ListResponse<>();
response.setResponses(metricsResponses, metricsResponses.size());
response.setResponseName(getCommandName());
setResponseObject(response);
}
}

View File

@ -0,0 +1,46 @@
// 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 org.apache.cloudstack.metrics;
import com.cloud.utils.component.PluggableService;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.response.ClusterMetricsResponse;
import org.apache.cloudstack.response.HostMetricsResponse;
import org.apache.cloudstack.response.InfrastructureResponse;
import org.apache.cloudstack.response.StoragePoolMetricsResponse;
import org.apache.cloudstack.response.VmMetricsResponse;
import org.apache.cloudstack.response.VolumeMetricsResponse;
import org.apache.cloudstack.response.ZoneMetricsResponse;
import java.util.List;
public interface MetricsService extends PluggableService {
InfrastructureResponse listInfrastructure();
List<VolumeMetricsResponse> listVolumeMetrics(List<VolumeResponse> volumeResponses);
List<VmMetricsResponse> listVmMetrics(List<UserVmResponse> vmResponses);
List<StoragePoolMetricsResponse> listStoragePoolMetrics(List<StoragePoolResponse> poolResponses);
List<HostMetricsResponse> listHostMetrics(List<HostResponse> poolResponses);
List<ClusterMetricsResponse> listClusterMetrics(List<ClusterResponse> poolResponses);
List<ZoneMetricsResponse> listZoneMetrics(List<ZoneResponse> poolResponses);
}

View File

@ -0,0 +1,563 @@
// 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 org.apache.cloudstack.metrics;
import com.cloud.alert.AlertManager;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.query.dao.HostJoinDao;
import com.cloud.api.query.vo.HostJoinVO;
import com.cloud.capacity.Capacity;
import com.cloud.capacity.CapacityManager;
import com.cloud.capacity.dao.CapacityDao;
import com.cloud.capacity.dao.CapacityDaoImpl;
import com.cloud.dc.DataCenter;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.deploy.DeploymentClusterPlanner;
import com.cloud.host.Host;
import com.cloud.host.HostStats;
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.org.Cluster;
import com.cloud.org.Grouping;
import com.cloud.org.Managed;
import com.cloud.utils.component.ComponentLifecycleBase;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.VMInstanceDao;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.ListClustersMetricsCmd;
import org.apache.cloudstack.api.ListHostsMetricsCmd;
import org.apache.cloudstack.api.ListInfrastructureCmd;
import org.apache.cloudstack.api.ListStoragePoolsMetricsCmd;
import org.apache.cloudstack.api.ListVMsMetricsCmd;
import org.apache.cloudstack.api.ListVolumesMetricsCmd;
import org.apache.cloudstack.api.ListZonesMetricsCmd;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.api.response.StoragePoolResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.response.ClusterMetricsResponse;
import org.apache.cloudstack.response.HostMetricsResponse;
import org.apache.cloudstack.response.InfrastructureResponse;
import org.apache.cloudstack.response.StoragePoolMetricsResponse;
import org.apache.cloudstack.response.VmMetricsResponse;
import org.apache.cloudstack.response.VolumeMetricsResponse;
import org.apache.cloudstack.response.ZoneMetricsResponse;
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.commons.beanutils.BeanUtils;
import javax.inject.Inject;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
public class MetricsServiceImpl extends ComponentLifecycleBase implements MetricsService {
@Inject
private DataCenterDao dataCenterDao;
@Inject
private HostPodDao podDao;
@Inject
private ClusterDao clusterDao;
@Inject
private HostDao hostDao;
@Inject
private HostJoinDao hostJoinDao;
@Inject
private PrimaryDataStoreDao storagePoolDao;
@Inject
private ImageStoreDao imageStoreDao;
@Inject
private VMInstanceDao vmInstanceDao;
@Inject
private DomainRouterDao domainRouterDao;
@Inject
private CapacityDao capacityDao;
protected MetricsServiceImpl() {
super();
}
private Double findRatioValue(final String value) {
if (value != null) {
return Double.valueOf(value);
}
return 1.0;
}
private void updateHostMetrics(final Metrics metrics, final HostJoinVO host) {
metrics.incrTotalHosts();
metrics.addCpuAllocated(host.getCpuReservedCapacity() + host.getCpuUsedCapacity());
metrics.addMemoryAllocated(host.getMemReservedCapacity() + host.getMemUsedCapacity());
final HostStats hostStats = ApiDBUtils.getHostStatistics(host.getId());
if (hostStats != null) {
metrics.addCpuUsedPercentage(hostStats.getCpuUtilization());
metrics.addMemoryUsed((long) hostStats.getUsedMemory());
metrics.setMaximumCpuUsage(hostStats.getCpuUtilization());
metrics.setMaximumMemoryUsage((long) hostStats.getUsedMemory());
}
}
@Override
public InfrastructureResponse listInfrastructure() {
final InfrastructureResponse response = new InfrastructureResponse();
response.setZones(dataCenterDao.listAllZones().size());
response.setPods(podDao.listAllPods(null).size());
response.setClusters(clusterDao.listAllClusters(null).size());
response.setHosts(hostDao.listByType(Host.Type.Routing).size());
response.setStoragePools(storagePoolDao.listAll().size());
response.setImageStores(imageStoreDao.listImageStores().size());
response.setSystemvms(vmInstanceDao.listByTypes(VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm).size());
response.setRouters(domainRouterDao.listAll().size());
int cpuSockets = 0;
for (final Host host : hostDao.listByType(Host.Type.Routing)) {
if (host.getCpuSockets() != null) {
cpuSockets += host.getCpuSockets();
}
}
response.setCpuSockets(cpuSockets);
return response;
}
@Override
public List<VolumeMetricsResponse> listVolumeMetrics(List<VolumeResponse> volumeResponses) {
final List<VolumeMetricsResponse> metricsResponses = new ArrayList<>();
for (final VolumeResponse volumeResponse: volumeResponses) {
VolumeMetricsResponse metricsResponse = new VolumeMetricsResponse();
try {
BeanUtils.copyProperties(metricsResponse, volumeResponse);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate volume metrics response");
}
metricsResponse.setDiskSizeGB(volumeResponse.getSize());
metricsResponse.setStorageType(volumeResponse.getStorageType(), volumeResponse.getVolumeType());
metricsResponses.add(metricsResponse);
}
return metricsResponses;
}
@Override
public List<VmMetricsResponse> listVmMetrics(List<UserVmResponse> vmResponses) {
final List<VmMetricsResponse> metricsResponses = new ArrayList<>();
for (final UserVmResponse vmResponse: vmResponses) {
VmMetricsResponse metricsResponse = new VmMetricsResponse();
try {
BeanUtils.copyProperties(metricsResponse, vmResponse);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate vm metrics response");
}
metricsResponse.setIpAddress(vmResponse.getNics());
metricsResponse.setCpuTotal(vmResponse.getCpuNumber(), vmResponse.getCpuSpeed());
metricsResponse.setMemTotal(vmResponse.getMemory());
metricsResponse.setNetworkRead(vmResponse.getNetworkKbsRead());
metricsResponse.setNetworkWrite(vmResponse.getNetworkKbsWrite());
metricsResponse.setDiskRead(vmResponse.getDiskKbsRead());
metricsResponse.setDiskWrite(vmResponse.getDiskKbsWrite());
metricsResponse.setDiskIopsTotal(vmResponse.getDiskIORead(), vmResponse.getDiskIOWrite());
metricsResponses.add(metricsResponse);
}
return metricsResponses;
}
@Override
public List<StoragePoolMetricsResponse> listStoragePoolMetrics(List<StoragePoolResponse> poolResponses) {
final List<StoragePoolMetricsResponse> metricsResponses = new ArrayList<>();
for (final StoragePoolResponse poolResponse: poolResponses) {
StoragePoolMetricsResponse metricsResponse = new StoragePoolMetricsResponse();
try {
BeanUtils.copyProperties(metricsResponse, poolResponse);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate storagepool metrics response");
}
Long poolClusterId = null;
final Cluster cluster = clusterDao.findByUuid(poolResponse.getClusterId());
if (cluster != null) {
poolClusterId = cluster.getId();
}
final Double storageThreshold = AlertManager.StorageCapacityThreshold.valueIn(poolClusterId);
final Double storageDisableThreshold = CapacityManager.StorageCapacityDisableThreshold.valueIn(poolClusterId);
metricsResponse.setDiskSizeUsedGB(poolResponse.getDiskSizeUsed());
metricsResponse.setDiskSizeTotalGB(poolResponse.getDiskSizeTotal(), poolResponse.getOverProvisionFactor());
metricsResponse.setDiskSizeAllocatedGB(poolResponse.getDiskSizeAllocated());
metricsResponse.setDiskSizeUnallocatedGB(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeAllocated(), poolResponse.getOverProvisionFactor());
metricsResponse.setStorageUsedThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeUsed(), poolResponse.getOverProvisionFactor(), storageThreshold);
metricsResponse.setStorageUsedDisableThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeUsed(), poolResponse.getOverProvisionFactor(), storageDisableThreshold);
metricsResponse.setStorageAllocatedThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeAllocated(), poolResponse.getOverProvisionFactor(), storageThreshold);
metricsResponse.setStorageAllocatedDisableThreshold(poolResponse.getDiskSizeTotal(), poolResponse.getDiskSizeUsed(), poolResponse.getOverProvisionFactor(), storageDisableThreshold);
metricsResponses.add(metricsResponse);
}
return metricsResponses;
}
@Override
public List<HostMetricsResponse> listHostMetrics(List<HostResponse> hostResponses) {
final List<HostMetricsResponse> metricsResponses = new ArrayList<>();
for (final HostResponse hostResponse: hostResponses) {
HostMetricsResponse metricsResponse = new HostMetricsResponse();
try {
BeanUtils.copyProperties(metricsResponse, hostResponse);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate host metrics response");
}
final Host host = hostDao.findByUuid(hostResponse.getId());
if (host == null) {
continue;
}
final Long hostId = host.getId();
final Long clusterId = host.getClusterId();
// Thresholds
final Double cpuThreshold = AlertManager.CPUCapacityThreshold.valueIn(clusterId);
final Double memoryThreshold = AlertManager.MemoryCapacityThreshold.valueIn(clusterId);
final Float cpuDisableThreshold = DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.valueIn(clusterId);
final Float memoryDisableThreshold = DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.valueIn(clusterId);
// Over commit ratios
final Double cpuOvercommitRatio = findRatioValue(ApiDBUtils.findClusterDetails(clusterId, "cpuOvercommitRatio"));
final Double memoryOvercommitRatio = findRatioValue(ApiDBUtils.findClusterDetails(clusterId, "memoryOvercommitRatio"));
Long upInstances = 0L;
Long totalInstances = 0L;
for (final VMInstanceVO instance: vmInstanceDao.listByHostId(hostId)) {
if (instance == null) {
continue;
}
if (instance.getType() == VirtualMachine.Type.User) {
totalInstances++;
if (instance.getState() == VirtualMachine.State.Running) {
upInstances++;
}
}
}
metricsResponse.setPowerState(hostResponse.getOutOfBandManagementResponse().getPowerState());
metricsResponse.setInstances(upInstances, totalInstances);
metricsResponse.setCpuTotal(hostResponse.getCpuNumber(), hostResponse.getCpuSpeed(), cpuOvercommitRatio);
metricsResponse.setCpuUsed(hostResponse.getCpuUsed(), hostResponse.getCpuNumber(), hostResponse.getCpuSpeed());
metricsResponse.setCpuAllocated(hostResponse.getCpuAllocated(), hostResponse.getCpuNumber(), hostResponse.getCpuSpeed());
metricsResponse.setMemTotal(hostResponse.getMemoryTotal(), memoryOvercommitRatio);
metricsResponse.setMemAllocated(hostResponse.getMemoryAllocated());
metricsResponse.setMemUsed(hostResponse.getMemoryUsed());
metricsResponse.setNetworkRead(hostResponse.getNetworkKbsRead());
metricsResponse.setNetworkWrite(hostResponse.getNetworkKbsWrite());
// CPU thresholds
metricsResponse.setCpuUsageThreshold(hostResponse.getCpuUsed(), cpuThreshold);
metricsResponse.setCpuUsageDisableThreshold(hostResponse.getCpuUsed(), cpuDisableThreshold);
metricsResponse.setCpuAllocatedThreshold(hostResponse.getCpuAllocated(), cpuOvercommitRatio, cpuThreshold);
metricsResponse.setCpuAllocatedDisableThreshold(hostResponse.getCpuAllocated(), cpuOvercommitRatio, cpuDisableThreshold);
// Memory thresholds
metricsResponse.setMemoryUsageThreshold(hostResponse.getMemoryUsed(), hostResponse.getMemoryTotal(), memoryThreshold);
metricsResponse.setMemoryUsageDisableThreshold(hostResponse.getMemoryUsed(), hostResponse.getMemoryTotal(), memoryDisableThreshold);
metricsResponse.setMemoryAllocatedThreshold(hostResponse.getMemoryAllocated(), hostResponse.getMemoryTotal(), memoryOvercommitRatio, memoryThreshold);
metricsResponse.setMemoryAllocatedDisableThreshold(hostResponse.getMemoryAllocated(), hostResponse.getMemoryTotal(), memoryOvercommitRatio, memoryDisableThreshold);
metricsResponses.add(metricsResponse);
}
return metricsResponses;
}
private CapacityDaoImpl.SummedCapacity getCapacity(final int capacityType, final Long zoneId, final Long clusterId) {
final List<CapacityDaoImpl.SummedCapacity> capacities = capacityDao.findCapacityBy(capacityType, zoneId, null, clusterId);
if (capacities == null || capacities.size() < 1) {
return null;
}
return capacities.get(0);
}
@Override
public List<ClusterMetricsResponse> listClusterMetrics(List<ClusterResponse> clusterResponses) {
final List<ClusterMetricsResponse> metricsResponses = new ArrayList<>();
for (final ClusterResponse clusterResponse: clusterResponses) {
ClusterMetricsResponse metricsResponse = new ClusterMetricsResponse();
try {
BeanUtils.copyProperties(metricsResponse, clusterResponse);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate cluster metrics response");
}
final Cluster cluster = clusterDao.findByUuid(clusterResponse.getId());
if (cluster == null) {
continue;
}
final Long clusterId = cluster.getId();
// Thresholds
final Double cpuThreshold = AlertManager.CPUCapacityThreshold.valueIn(clusterId);
final Double memoryThreshold = AlertManager.MemoryCapacityThreshold.valueIn(clusterId);
final Float cpuDisableThreshold = DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.valueIn(clusterId);
final Float memoryDisableThreshold = DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.valueIn(clusterId);
final Double cpuOvercommitRatio = findRatioValue(ApiDBUtils.findClusterDetails(clusterId, "cpuOvercommitRatio"));
final Double memoryOvercommitRatio = findRatioValue(ApiDBUtils.findClusterDetails(clusterId, "memoryOvercommitRatio"));
// CPU and memory capacities
final CapacityDaoImpl.SummedCapacity cpuCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_CPU, null, clusterId);
final CapacityDaoImpl.SummedCapacity memoryCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_MEMORY, null, clusterId);
final Metrics metrics = new Metrics(cpuCapacity, memoryCapacity);
for (final HostJoinVO host: hostJoinDao.findByClusterId(clusterId, Host.Type.Routing)) {
if (host.getStatus() == Status.Up) {
metrics.incrUpResources();
}
metrics.incrTotalResources();
updateHostMetrics(metrics, host);
}
metricsResponse.setState(clusterResponse.getAllocationState(), clusterResponse.getManagedState());
metricsResponse.setResources(metrics.getUpResources(), metrics.getTotalResources());
// CPU
metricsResponse.setCpuTotal(metrics.getTotalCpu());
metricsResponse.setCpuAllocated(metrics.getCpuAllocated(), metrics.getTotalCpu());
if (metrics.getCpuUsedPercentage() > 0L) {
metricsResponse.setCpuUsed(metrics.getCpuUsedPercentage(), metrics.getTotalHosts());
metricsResponse.setCpuMaxDeviation(metrics.getMaximumCpuUsage(), metrics.getCpuUsedPercentage(), metrics.getTotalHosts());
}
// Memory
metricsResponse.setMemTotal(metrics.getTotalMemory());
metricsResponse.setMemAllocated(metrics.getMemoryAllocated(), metrics.getTotalMemory());
if (metrics.getMemoryUsed() > 0L) {
metricsResponse.setMemUsed(metrics.getMemoryUsed(), metrics.getTotalMemory());
metricsResponse.setMemMaxDeviation(metrics.getMaximumMemoryUsage(), metrics.getMemoryUsed(), metrics.getTotalHosts());
}
// CPU thresholds
metricsResponse.setCpuUsageThreshold(metrics.getCpuUsedPercentage(), metrics.getTotalHosts(), cpuThreshold);
metricsResponse.setCpuUsageDisableThreshold(metrics.getCpuUsedPercentage(), metrics.getTotalHosts(), cpuDisableThreshold);
metricsResponse.setCpuAllocatedThreshold(metrics.getCpuAllocated(), metrics.getTotalCpu(), cpuOvercommitRatio, cpuThreshold);
metricsResponse.setCpuAllocatedDisableThreshold(metrics.getCpuAllocated(), metrics.getTotalCpu(), cpuOvercommitRatio, cpuDisableThreshold);
// Memory thresholds
metricsResponse.setMemoryUsageThreshold(metrics.getMemoryUsed(), metrics.getTotalMemory(), memoryThreshold);
metricsResponse.setMemoryUsageDisableThreshold(metrics.getMemoryUsed(), metrics.getTotalMemory(), memoryDisableThreshold);
metricsResponse.setMemoryAllocatedThreshold(metrics.getMemoryAllocated(), metrics.getTotalMemory(), memoryOvercommitRatio, memoryThreshold);
metricsResponse.setMemoryAllocatedDisableThreshold(metrics.getMemoryAllocated(), metrics.getTotalMemory(), memoryOvercommitRatio, memoryDisableThreshold);
metricsResponses.add(metricsResponse);
}
return metricsResponses;
}
@Override
public List<ZoneMetricsResponse> listZoneMetrics(List<ZoneResponse> zoneResponses) {
final List<ZoneMetricsResponse> metricsResponses = new ArrayList<>();
for (final ZoneResponse zoneResponse: zoneResponses) {
ZoneMetricsResponse metricsResponse = new ZoneMetricsResponse();
try {
BeanUtils.copyProperties(metricsResponse, zoneResponse);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to generate zone metrics response");
}
final DataCenter zone = dataCenterDao.findByUuid(zoneResponse.getId());
if (zone == null) {
continue;
}
final Long zoneId = zone.getId();
// Thresholds
final Double cpuThreshold = AlertManager.CPUCapacityThreshold.value();
final Double memoryThreshold = AlertManager.MemoryCapacityThreshold.value();
final Float cpuDisableThreshold = DeploymentClusterPlanner.ClusterCPUCapacityDisableThreshold.value();
final Float memoryDisableThreshold = DeploymentClusterPlanner.ClusterMemoryCapacityDisableThreshold.value();
// CPU and memory capacities
final CapacityDaoImpl.SummedCapacity cpuCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_CPU, zoneId, null);
final CapacityDaoImpl.SummedCapacity memoryCapacity = getCapacity((int) Capacity.CAPACITY_TYPE_MEMORY, zoneId, null);
final Metrics metrics = new Metrics(cpuCapacity, memoryCapacity);
for (final Cluster cluster : clusterDao.listClustersByDcId(zoneId)) {
metrics.incrTotalResources();
if (cluster.getAllocationState() == Grouping.AllocationState.Enabled
&& cluster.getManagedState() == Managed.ManagedState.Managed) {
metrics.incrUpResources();
}
for (final HostJoinVO host: hostJoinDao.findByClusterId(cluster.getId(), Host.Type.Routing)) {
updateHostMetrics(metrics, host);
}
}
metricsResponse.setState(zoneResponse.getAllocationState());
metricsResponse.setResource(metrics.getUpResources(), metrics.getTotalResources());
// CPU
metricsResponse.setCpuTotal(metrics.getTotalCpu());
metricsResponse.setCpuAllocated(metrics.getCpuAllocated(), metrics.getTotalCpu());
if (metrics.getCpuUsedPercentage() > 0L) {
metricsResponse.setCpuUsed(metrics.getCpuUsedPercentage(), metrics.getTotalHosts());
metricsResponse.setCpuMaxDeviation(metrics.getMaximumCpuUsage(), metrics.getCpuUsedPercentage(), metrics.getTotalHosts());
}
// Memory
metricsResponse.setMemTotal(metrics.getTotalMemory());
metricsResponse.setMemAllocated(metrics.getMemoryAllocated(), metrics.getTotalMemory());
if (metrics.getMemoryUsed() > 0L) {
metricsResponse.setMemUsed(metrics.getMemoryUsed(), metrics.getTotalMemory());
metricsResponse.setMemMaxDeviation(metrics.getMaximumMemoryUsage(), metrics.getMemoryUsed(), metrics.getTotalHosts());
}
// CPU thresholds
metricsResponse.setCpuUsageThreshold(metrics.getCpuUsedPercentage(), metrics.getTotalHosts(), cpuThreshold);
metricsResponse.setCpuUsageDisableThreshold(metrics.getCpuUsedPercentage(), metrics.getTotalHosts(), cpuDisableThreshold);
metricsResponse.setCpuAllocatedThreshold(metrics.getCpuAllocated(), metrics.getTotalCpu(), cpuThreshold);
metricsResponse.setCpuAllocatedDisableThreshold(metrics.getCpuAllocated(), metrics.getTotalCpu(), cpuDisableThreshold);
// Memory thresholds
metricsResponse.setMemoryUsageThreshold(metrics.getMemoryUsed(), metrics.getTotalMemory(), memoryThreshold);
metricsResponse.setMemoryUsageDisableThreshold(metrics.getMemoryUsed(), metrics.getTotalMemory(), memoryDisableThreshold);
metricsResponse.setMemoryAllocatedThreshold(metrics.getMemoryAllocated(), metrics.getTotalMemory(), memoryThreshold);
metricsResponse.setMemoryAllocatedDisableThreshold(metrics.getMemoryAllocated(), metrics.getTotalMemory(), memoryDisableThreshold);
metricsResponses.add(metricsResponse);
}
return metricsResponses;
}
@Override
public List<Class<?>> getCommands() {
List<Class<?>> cmdList = new ArrayList<Class<?>>();
cmdList.add(ListInfrastructureCmd.class);
cmdList.add(ListVolumesMetricsCmd.class);
cmdList.add(ListVMsMetricsCmd.class);
cmdList.add(ListStoragePoolsMetricsCmd.class);
cmdList.add(ListHostsMetricsCmd.class);
cmdList.add(ListClustersMetricsCmd.class);
cmdList.add(ListZonesMetricsCmd.class);
return cmdList;
}
private class Metrics {
// CPU metrics
private Long totalCpu = 0L;
private Long cpuAllocated = 0L;
private Double cpuUsedPercentage = 0.0;
private Double maximumCpuUsage = 0.0;
// Memory metrics
private Long totalMemory = 0L;
private Long memoryUsed = 0L;
private Long memoryAllocated = 0L;
private Long maximumMemoryUsage = 0L;
// Counters
private Long totalHosts = 0L;
private Long totalResources = 0L;
private Long upResources = 0L;
public Metrics(final CapacityDaoImpl.SummedCapacity totalCpu, final CapacityDaoImpl.SummedCapacity totalMemory) {
if (totalCpu != null) {
this.totalCpu = totalCpu.getTotalCapacity();
}
if (totalMemory != null) {
this.totalMemory = totalMemory.getTotalCapacity();
}
}
public void addCpuAllocated(Long cpuAllocated) {
this.cpuAllocated += cpuAllocated;
}
public void addCpuUsedPercentage(Double cpuUsedPercentage) {
this.cpuUsedPercentage += cpuUsedPercentage;
}
public void setMaximumCpuUsage(Double maximumCpuUsage) {
if (this.maximumCpuUsage == null || (maximumCpuUsage != null && maximumCpuUsage > this.maximumCpuUsage)) {
this.maximumCpuUsage = maximumCpuUsage;
}
}
public void addMemoryUsed(Long memoryUsed) {
this.memoryUsed += memoryUsed;
}
public void addMemoryAllocated(Long memoryAllocated) {
this.memoryAllocated += memoryAllocated;
}
public void setMaximumMemoryUsage(Long maximumMemoryUsage) {
if (this.maximumMemoryUsage == null || (maximumMemoryUsage != null && maximumMemoryUsage > this.maximumMemoryUsage)) {
this.maximumMemoryUsage = maximumMemoryUsage;
}
}
public void incrTotalHosts() {
this.totalHosts++;
}
public void incrTotalResources() {
this.totalResources++;
}
public void incrUpResources() {
this.upResources++;
}
public Long getTotalCpu() {
return totalCpu;
}
public Long getCpuAllocated() {
return cpuAllocated;
}
public Double getCpuUsedPercentage() {
return cpuUsedPercentage;
}
public Double getMaximumCpuUsage() {
return maximumCpuUsage;
}
public Long getTotalMemory() {
return totalMemory;
}
public Long getMemoryUsed() {
return memoryUsed;
}
public Long getMemoryAllocated() {
return memoryAllocated;
}
public Long getMaximumMemoryUsage() {
return maximumMemoryUsage;
}
public Long getTotalHosts() {
return totalHosts;
}
public Long getTotalResources() {
return totalResources;
}
public Long getUpResources() {
return upResources;
}
}
}

View File

@ -0,0 +1,211 @@
// 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 org.apache.cloudstack.response;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.response.ClusterResponse;
public class ClusterMetricsResponse extends ClusterResponse {
@SerializedName("state")
@Param(description = "state of the cluster")
private String state;
@SerializedName("hosts")
@Param(description = "running / total hosts in the cluster")
private String resources;
@SerializedName("cputotal")
@Param(description = "the total cpu capacity in Ghz")
private String cpuTotal;
@SerializedName("cpuused")
@Param(description = "the total cpu used in Ghz")
private String cpuUsed;
@SerializedName("cpuallocated")
@Param(description = "the total cpu allocated in Ghz")
private String cpuAllocated;
@SerializedName("cpumaxdeviation")
@Param(description = "the maximum cpu deviation")
private String cpuMaxDeviation;
@SerializedName("memorytotal")
@Param(description = "the total cpu capacity in GiB")
private String memTotal;
@SerializedName("memoryused")
@Param(description = "the total cpu used in GiB")
private String memUsed;
@SerializedName("memoryallocated")
@Param(description = "the total cpu allocated in GiB")
private String memAllocated;
@SerializedName("memorymaxdeviation")
@Param(description = "the maximum memory deviation")
private String memMaxDeviation;
@SerializedName("cputhreshold")
@Param(description = "cpu usage notification threshold exceeded")
private Boolean cpuThresholdExceeded;
@SerializedName("cpudisablethreshold")
@Param(description = "cpu usage disable threshold exceeded")
private Boolean cpuDisableThresholdExceeded;
@SerializedName("cpuallocatedthreshold")
@Param(description = "cpu allocated notification threshold exceeded")
private Boolean cpuAllocatedThresholdExceeded;
@SerializedName("cpuallocateddisablethreshold")
@Param(description = "cpu allocated disable threshold exceeded")
private Boolean cpuAllocatedDisableThresholdExceeded;
@SerializedName("memorythreshold")
@Param(description = "memory usage notification threshold exceeded")
private Boolean memoryThresholdExceeded;
@SerializedName("memorydisablethreshold")
@Param(description = "memory usage disable threshold exceeded")
private Boolean memoryDisableThresholdExceeded;
@SerializedName("memoryallocatedthreshold")
@Param(description = "memory allocated notification threshold exceeded")
private Boolean memoryAllocatedThresholdExceeded;
@SerializedName("memoryallocateddisablethreshold")
@Param(description = "memory allocated disable threshold exceeded")
private Boolean memoryAllocatedDisableThresholdExceeded;
public void setState(final String allocationState, final String managedState) {
this.state = allocationState;
if (managedState.equals("Unmanaged")) {
this.state = managedState;
}
if (managedState.equals("Managed")) {
this.state = allocationState;
}
}
public void setResources(final Long upResources, final Long totalResources) {
if (upResources != null && totalResources != null) {
this.resources = String.format("%d / %d", upResources, totalResources);
}
}
public void setCpuTotal(final Long cpuTotal) {
if (cpuTotal != null) {
this.cpuTotal = String.format("%.2f Ghz", cpuTotal / 1000.0);
}
}
public void setCpuUsed(final Double cpuUsedPercentage, final Long totalHosts) {
if (cpuUsedPercentage != null && totalHosts != null && totalHosts != 0) {
this.cpuUsed = String.format("%.2f%%", 1.0 * cpuUsedPercentage / totalHosts);
}
}
public void setCpuAllocated(final Long cpuAllocated, final Long cpuTotal) {
if (cpuAllocated != null && cpuTotal != null && cpuTotal != 0) {
this.cpuAllocated = String.format("%.2f%%", cpuAllocated * 100.0 / cpuTotal);
}
}
public void setCpuMaxDeviation(final Double maxCpuDeviation, final Double totalCpuUsed, final Long totalHosts) {
if (maxCpuDeviation != null && totalCpuUsed != null && totalHosts != null && totalHosts != 0) {
final Double averageCpuUsage = totalCpuUsed / totalHosts;
this.cpuMaxDeviation = String.format("%.2f%%", (maxCpuDeviation - averageCpuUsage) * 100.0 / averageCpuUsage);
}
}
public void setMemTotal(final Long memTotal) {
if (memTotal != null) {
this.memTotal = String.format("%.2f GB", memTotal / (1024.0 * 1024.0 * 1024.0));
}
}
public void setMemUsed( final Long memUsed, final Long memTotal) {
if (memUsed != null && memTotal != null && memTotal != 0) {
this.memUsed = String.format("%.2f%%", memUsed * 100.0 / memTotal);
}
}
public void setMemAllocated(final Long memAllocated, final Long memTotal) {
if (memAllocated != null && memTotal != null && memTotal != 0) {
this.memAllocated = String.format("%.2f%%", memAllocated * 100.0 / memTotal);
}
}
public void setMemMaxDeviation(final Long maxMemoryUsage, final Long totalMemory, final Long totalHosts) {
if (maxMemoryUsage != null && totalMemory != null && totalHosts != null && totalHosts != 0) {
final Double averageMemoryUsage = 1.0 * totalMemory / totalHosts;
this.memMaxDeviation = String.format("%.2f%%", (maxMemoryUsage - averageMemoryUsage) * 100.0 / averageMemoryUsage);
}
}
public void setCpuUsageThreshold(final Double cpuUsed, final Long totalHosts, final Double threshold) {
if (cpuUsed != null && totalHosts != null && threshold != null && totalHosts != 0) {
this.cpuThresholdExceeded = (cpuUsed / (100.0 * totalHosts)) > threshold;
}
}
public void setCpuUsageDisableThreshold(final Double cpuUsed, final Long totalHosts, final Float threshold) {
if (cpuUsed != null && totalHosts != null && threshold != null && totalHosts != 0) {
this.cpuDisableThresholdExceeded = (cpuUsed / (100.0 * totalHosts)) > threshold;
}
}
public void setCpuAllocatedThreshold(final Long cpuAllocated, final Long cpuUsed, final Double overCommitRatio, final Double threshold) {
if (cpuAllocated != null && cpuUsed != null && overCommitRatio != null && threshold != null && cpuUsed != 0) {
this.cpuAllocatedThresholdExceeded = (1.0 * cpuAllocated * overCommitRatio / cpuUsed) > threshold;
}
}
public void setCpuAllocatedDisableThreshold(final Long cpuAllocated, final Long cpuUsed, final Double overCommitRatio, final Float threshold) {
if (cpuAllocated != null && cpuUsed != null && overCommitRatio != null && threshold != null && cpuUsed != 0) {
this.cpuAllocatedDisableThresholdExceeded = (1.0 * cpuAllocated * overCommitRatio / cpuUsed) > threshold;
}
}
public void setMemoryUsageThreshold(final Long memUsed, final Long memTotal, final Double threshold) {
if (memUsed != null && memTotal != null && threshold != null && memTotal != 0) {
this.memoryThresholdExceeded = (1.0 * memUsed / memTotal) > threshold;
}
}
public void setMemoryUsageDisableThreshold(final Long memUsed, final Long memTotal, final Float threshold) {
if (memUsed != null && memTotal != null && threshold != null && memTotal != 0) {
this.memoryDisableThresholdExceeded = (1.0 * memUsed / memTotal) > threshold;
}
}
public void setMemoryAllocatedThreshold(final Long memAllocated, final Long memTotal, final Double overCommitRatio, final Double threshold) {
if (memAllocated != null && memTotal != null && overCommitRatio != null && threshold != null && memTotal != 0) {
this.memoryAllocatedThresholdExceeded = (1.0 * memAllocated * overCommitRatio / memTotal) > threshold;
}
}
public void setMemoryAllocatedDisableThreshold(final Long memAllocated, final Long memTotal, final Double overCommitRatio, final Float threshold) {
if (memAllocated != null && memTotal != null && overCommitRatio != null && threshold != null && memTotal != 0) {
this.memoryAllocatedDisableThresholdExceeded = (1.0 * memAllocated * overCommitRatio / memTotal) > threshold;
}
}
}

View File

@ -0,0 +1,204 @@
// 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 org.apache.cloudstack.response;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.response.HostResponse;
import org.apache.cloudstack.outofbandmanagement.OutOfBandManagement;
public class HostMetricsResponse extends HostResponse {
@SerializedName("powerstate")
@Param(description = "out-of-band management power state")
private OutOfBandManagement.PowerState powerState;
@SerializedName("instances")
@Param(description = "instances on the host")
private String instances;
@SerializedName("cputotalghz")
@Param(description = "the total cpu capacity in Ghz")
private String cpuTotal;
@SerializedName("cpuusedghz")
@Param(description = "the total cpu used in Ghz")
private String cpuUsed;
@SerializedName("cpuallocatedghz")
@Param(description = "the total cpu allocated in Ghz")
private String cpuAllocated;
@SerializedName("memorytotalgb")
@Param(description = "the total cpu capacity in GiB")
private String memTotal;
@SerializedName("memoryusedgb")
@Param(description = "the total cpu used in GiB")
private String memUsed;
@SerializedName("memoryallocatedgb")
@Param(description = "the total cpu allocated in GiB")
private String memAllocated;
@SerializedName("networkread")
@Param(description = "network read in GiB")
private String networkRead;
@SerializedName("networkwrite")
@Param(description = "network write in GiB")
private String networkWrite;
@SerializedName("cputhreshold")
@Param(description = "cpu usage notification threshold exceeded")
private Boolean cpuThresholdExceeded;
@SerializedName("cpudisablethreshold")
@Param(description = "cpu usage disable threshold exceeded")
private Boolean cpuDisableThresholdExceeded;
@SerializedName("cpuallocatedthreshold")
@Param(description = "cpu allocated notification threshold exceeded")
private Boolean cpuAllocatedThresholdExceeded;
@SerializedName("cpuallocateddisablethreshold")
@Param(description = "cpu allocated disable threshold exceeded")
private Boolean cpuAllocatedDisableThresholdExceeded;
@SerializedName("memorythreshold")
@Param(description = "memory usage notification threshold exceeded")
private Boolean memoryThresholdExceeded;
@SerializedName("memorydisablethreshold")
@Param(description = "memory usage disable threshold exceeded")
private Boolean memoryDisableThresholdExceeded;
@SerializedName("memoryallocatedthreshold")
@Param(description = "memory allocated notification threshold exceeded")
private Boolean memoryAllocatedThresholdExceeded;
@SerializedName("memoryallocateddisablethreshold")
@Param(description = "memory allocated disable threshold exceeded")
private Boolean memoryAllocatedDisableThresholdExceeded;
public void setPowerState(final OutOfBandManagement.PowerState powerState) {
this.powerState = powerState;
}
public void setInstances(final Long running, final Long total) {
if (running != null && total != null) {
this.instances = String.format("%d / %d", running, total);
}
}
public void setCpuTotal(final Integer cpuNumber, final Long cpuSpeed, final Double overcommitRatio) {
if (cpuNumber != null && cpuSpeed != null && overcommitRatio != null) {
this.cpuTotal = String.format("%.2f Ghz (x %.1f)", cpuNumber * cpuSpeed / 1000.0, overcommitRatio);
}
}
public void setCpuUsed(final String cpuUsed, final Integer cpuNumber, final Long cpuSpeed) {
if (cpuUsed != null && cpuNumber != null && cpuSpeed != null) {
this.cpuUsed = String.format("%.2f Ghz", Double.valueOf(cpuUsed.replace("%", "")) * cpuNumber * cpuSpeed / (100.0 * 1000.0));
}
}
public void setCpuAllocated(final String cpuAllocated, final Integer cpuNumber, final Long cpuSpeed) {
if (cpuAllocated != null && cpuNumber != null && cpuSpeed != null) {
this.cpuAllocated = String.format("%.2f Ghz", Double.valueOf(cpuAllocated.replace("%", "")) * cpuNumber * cpuSpeed / (100.0 * 1000.0));
}
}
public void setMemTotal(final Long memTotal, final Double overcommitRatio) {
if (memTotal != null && overcommitRatio != null) {
this.memTotal = String.format("%.2f GB (x %.1f)", memTotal / (1024.0 * 1024.0 * 1024.0), overcommitRatio);
}
}
public void setMemUsed(final Long memUsed) {
if (memUsed != null) {
this.memUsed = String.format("%.2f GB", memUsed / (1024.0 * 1024.0 * 1024.0));
}
}
public void setMemAllocated(final Long memAllocated) {
if (memAllocated != null) {
this.memAllocated = String.format("%.2f GB", memAllocated / (1024.0 * 1024.0 * 1024.0));
}
}
public void setNetworkRead(final Long networkReadKbs) {
if (networkReadKbs != null) {
this.networkRead = String.format("%.2f GB", networkReadKbs / (1024.0 * 1024.0));
}
}
public void setNetworkWrite(final Long networkWriteKbs) {
if (networkWriteKbs != null) {
this.networkWrite = String.format("%.2f GB", networkWriteKbs / (1024.0 * 1024.0));
}
}
public void setCpuUsageThreshold(final String cpuUsed, final Double threshold) {
if (cpuUsed != null && threshold != null) {
this.cpuThresholdExceeded = Double.valueOf(cpuUsed.replace("%", "")) > (100.0 * threshold);
}
}
public void setCpuUsageDisableThreshold(final String cpuUsed, final Float threshold) {
if (cpuUsed != null && threshold != null) {
this.cpuDisableThresholdExceeded = Double.valueOf(cpuUsed.replace("%", "")) > (100.0 * threshold);
}
}
public void setCpuAllocatedThreshold(final String cpuAllocated, final Double overCommitRatio, final Double threshold) {
if (cpuAllocated != null && overCommitRatio != null && threshold != null) {
this.cpuAllocatedThresholdExceeded = (Double.valueOf(cpuAllocated.replace("%", "")) * overCommitRatio) > (100.0 * threshold);
}
}
public void setCpuAllocatedDisableThreshold(final String cpuAllocated, final Double overCommitRatio, final Float threshold) {
if (cpuAllocated != null && overCommitRatio != null && threshold != null) {
this.cpuAllocatedDisableThresholdExceeded = (Double.valueOf(cpuAllocated.replace("%", "")) * overCommitRatio) > (100.0 * threshold);
}
}
public void setMemoryUsageThreshold(final Long memUsed, final Long memTotal, final Double threshold) {
if (memUsed != null && memTotal != null && threshold != null) {
this.memoryThresholdExceeded = memUsed > (memTotal * threshold);
}
}
public void setMemoryUsageDisableThreshold(final Long memUsed, final Long memTotal, final Float threshold) {
if (memUsed != null && memTotal != null && threshold != null) {
this.memoryDisableThresholdExceeded = memUsed > (memTotal * threshold);
}
}
public void setMemoryAllocatedThreshold(final Long memAllocated, final Long memTotal, final Double overCommitRatio, final Double threshold) {
if (memAllocated != null && memTotal != null && overCommitRatio != null && threshold != null) {
this.memoryAllocatedThresholdExceeded = (memAllocated * overCommitRatio) > (memTotal * threshold);
}
}
public void setMemoryAllocatedDisableThreshold(final Long memAllocated, final Long memTotal, final Double overCommitRatio, final Float threshold) {
if (memAllocated != null && memTotal != null && overCommitRatio != null && threshold != null) {
this.memoryAllocatedDisableThresholdExceeded = (memAllocated * overCommitRatio) > (memTotal * threshold);
}
}
}

View File

@ -0,0 +1,101 @@
// 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 org.apache.cloudstack.response;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.BaseResponse;
public class InfrastructureResponse extends BaseResponse {
@SerializedName("zones")
@Param(description = "Number of zones")
private Integer zones;
@SerializedName("pods")
@Param(description = "Number of pods")
private Integer pods;
@SerializedName("clusters")
@Param(description = "Number of clusters")
private Integer clusters;
@SerializedName("hosts")
@Param(description = "Number of hypervisor hosts")
private Integer hosts;
@SerializedName("storagepools")
@Param(description = "Number of storage pools")
private Integer storagePools;
@SerializedName("imagestores")
@Param(description = "Number of images stores")
private Integer imageStores;
@SerializedName("systemvms")
@Param(description = "Number of systemvms")
private Integer systemvms;
@SerializedName("routers")
@Param(description = "Number of routers")
private Integer routers;
@SerializedName("cpusockets")
@Param(description = "Number of cpu sockets")
private Integer cpuSockets;
public InfrastructureResponse() {
setObjectName("infrastructure");
}
public void setZones(final Integer zones) {
this.zones = zones;
}
public void setPods(final Integer pods) {
this.pods = pods;
}
public void setClusters(final Integer clusters) {
this.clusters = clusters;
}
public void setHosts(final Integer hosts) {
this.hosts = hosts;
}
public void setStoragePools(final Integer storagePools) {
this.storagePools = storagePools;
}
public void setImageStores(final Integer imageStores) {
this.imageStores = imageStores;
}
public void setSystemvms(final Integer systemvms) {
this.systemvms = systemvms;
}
public void setRouters(final Integer routers) {
this.routers = routers;
}
public void setCpuSockets(final Integer cpuSockets) {
this.cpuSockets = cpuSockets;
}
}

View File

@ -0,0 +1,105 @@
// 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 org.apache.cloudstack.response;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.response.StoragePoolResponse;
public class StoragePoolMetricsResponse extends StoragePoolResponse {
@SerializedName("disksizeusedgb")
@Param(description = "disk size used in GiB")
private String diskSizeUsedGB;
@SerializedName("disksizetotalgb")
@Param(description = "disk size in GiB")
private String diskSizeTotalGB;
@SerializedName("disksizeallocatedgb")
@Param(description = "disk size allocated in GiB")
private String diskSizeAllocatedGB;
@SerializedName("disksizeunallocatedgb")
@Param(description = "disk size unallocated in GiB")
private String diskSizeUnallocatedGB;
@SerializedName("storageusagethreshold")
@Param(description = "storage usage notification threshold exceeded")
private Boolean storageUsedThreshold;
@SerializedName("storageusagedisablethreshold")
@Param(description = "storage usage disable threshold exceeded")
private Boolean storageUsedDisableThreshold;
@SerializedName("storageallocatedthreshold")
@Param(description = "storage allocated notification threshold exceeded")
private Boolean storageAllocatedThreshold;
@SerializedName("storageallocateddisablethreshold")
@Param(description = "storage allocated disable threshold exceeded")
private Boolean storageAllocatedDisableThreshold;
public void setDiskSizeUsedGB(final Long diskSizeUsed) {
if (diskSizeUsed != null) {
this.diskSizeUsedGB = String.format("%.2f GB", diskSizeUsed / (1024.0 * 1024.0 * 1024.0));
}
}
public void setDiskSizeTotalGB(final Long totalDiskSize, final String overProvisionFactor) {
if (totalDiskSize != null && overProvisionFactor != null) {
this.diskSizeTotalGB = String.format("%.2f GB (x%s)", totalDiskSize / (1024.0 * 1024.0 * 1024.0), overProvisionFactor);
}
}
public void setDiskSizeAllocatedGB(final Long diskSizeAllocated) {
if (diskSizeAllocated != null) {
this.diskSizeAllocatedGB = String.format("%.2f GB", diskSizeAllocated / (1024.0 * 1024.0 * 1024.0));
}
}
public void setDiskSizeUnallocatedGB(final Long totalDiskSize, final Long diskSizeAllocated, final String overProvisionFactor) {
if (totalDiskSize != null && diskSizeAllocated != null && overProvisionFactor != null) {
this.diskSizeUnallocatedGB = String.format("%.2f GB", ((Double.valueOf(overProvisionFactor) * totalDiskSize) - diskSizeAllocated) / (1024.0 * 1024.0 * 1024.0));
}
}
public void setStorageUsedThreshold(final Long totalDiskSize, final Long diskSizeUsed, final String overProvisionFactor, final Double threshold) {
if (totalDiskSize != null && diskSizeUsed != null && overProvisionFactor != null && threshold != null) {
this.storageUsedThreshold = diskSizeUsed > (totalDiskSize * Double.valueOf(overProvisionFactor) * threshold) ;
}
}
public void setStorageUsedDisableThreshold(final Long totalDiskSize, final Long diskSizeUsed, final String overProvisionFactor, final Double threshold) {
if (totalDiskSize != null && diskSizeUsed != null && overProvisionFactor != null && threshold != null) {
this.storageUsedDisableThreshold = diskSizeUsed > (totalDiskSize * Double.valueOf(overProvisionFactor) * threshold);
}
}
public void setStorageAllocatedThreshold(final Long totalDiskSize, final Long diskSizeAllocated, final String overProvisionFactor, final Double threshold) {
if (totalDiskSize != null && diskSizeAllocated != null && overProvisionFactor != null && threshold != null) {
this.storageAllocatedThreshold = diskSizeAllocated > (totalDiskSize * Double.valueOf(overProvisionFactor) * threshold);
}
}
public void setStorageAllocatedDisableThreshold(final Long totalDiskSize, final Long diskSizeAllocated, final String overProvisionFactor, final Double threshold) {
if (totalDiskSize != null && diskSizeAllocated != null && overProvisionFactor != null && threshold != null) {
this.storageAllocatedDisableThreshold = diskSizeAllocated > (totalDiskSize * Double.valueOf(overProvisionFactor) * threshold);
}
}
}

View File

@ -0,0 +1,108 @@
// 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 org.apache.cloudstack.response;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.response.NicResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import java.util.Set;
public class VmMetricsResponse extends UserVmResponse {
@SerializedName(ApiConstants.IP_ADDRESS)
@Param(description = "the VM's primary IP address")
private String ipAddress;
@SerializedName("cputotal")
@Param(description = "the total cpu capacity in Ghz")
private String cpuTotal;
@SerializedName("memorytotal")
@Param(description = "the total memory capacity in GiB")
private String memTotal;
@SerializedName("networkread")
@Param(description = "network read in MiB")
private String networkRead;
@SerializedName("networkwrite")
@Param(description = "network write in MiB")
private String networkWrite;
@SerializedName("diskread")
@Param(description = "disk read in MiB")
private String diskRead;
@SerializedName("diskwrite")
@Param(description = "disk write in MiB")
private String diskWrite;
@SerializedName("diskiopstotal")
@Param(description = "the total disk iops")
private Long diskIopsTotal;
public void setIpAddress(final Set<NicResponse> nics) {
if (nics != null && nics.size() > 0) {
this.ipAddress = nics.iterator().next().getIpaddress();
}
}
public void setCpuTotal(final Integer cpuNumber, final Integer cpuSpeed) {
if (cpuNumber != null && cpuSpeed != null) {
this.cpuTotal = String.format("%.1f Ghz", cpuNumber * cpuSpeed / 1000.0);
}
}
public void setMemTotal(final Integer memory) {
if (memory != null) {
this.memTotal = String.format("%.2f GB", memory / 1024.0);
}
}
public void setNetworkRead(final Long networkReadKbs) {
if (networkReadKbs != null) {
this.networkRead = String.format("%.2f MB", networkReadKbs / 1024.0);
}
}
public void setNetworkWrite(final Long networkWriteKbs) {
if (networkWriteKbs != null) {
this.networkWrite = String.format("%.2f MB", networkWriteKbs / 1024.0);
}
}
public void setDiskRead(final Long diskReadKbs) {
if (diskReadKbs != null) {
this.networkRead = String.format("%.2f MB", diskReadKbs / 1024.0);
}
}
public void setDiskWrite(final Long diskWriteKbs) {
if (diskWriteKbs != null) {
this.networkWrite = String.format("%.2f MB", diskWriteKbs / 1024.0);
}
}
public void setDiskIopsTotal(final Long diskIoRead, final Long diskIoWrite) {
if (diskIoRead != null && diskIoWrite != null) {
this.diskIopsTotal = diskIoRead + diskIoWrite;
}
}
}

View File

@ -0,0 +1,41 @@
// 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 org.apache.cloudstack.response;
import com.cloud.serializer.Param;
import com.google.common.base.Strings;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.response.VolumeResponse;
public class VolumeMetricsResponse extends VolumeResponse {
@SerializedName("sizegb")
@Param(description = "disk size in GiB")
private String diskSizeGB;
public void setStorageType(final String storageType, final String volumeType) {
if (!Strings.isNullOrEmpty(storageType) && !Strings.isNullOrEmpty(volumeType)) {
this.setStorageType(String.format("%s (%s)", storageType.substring(0, 1).toUpperCase() + storageType.substring(1), volumeType));
}
}
public void setDiskSizeGB(final Long size) {
if (size != null) {
this.diskSizeGB = String.format("%.2f GB", size / (1024.0 * 1024.0 * 1024.0));
}
}
}

View File

@ -0,0 +1,206 @@
// 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 org.apache.cloudstack.response;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.response.ZoneResponse;
public class ZoneMetricsResponse extends ZoneResponse {
@SerializedName("state")
@Param(description = "state of the cluster")
private String state;
@SerializedName("clusters")
@Param(description = "healthy / total clusters in the zone")
private String resources;
@SerializedName("cputotal")
@Param(description = "the total cpu capacity in Ghz")
private String cpuTotal;
@SerializedName("cpuused")
@Param(description = "the total cpu used in Ghz")
private String cpuUsed;
@SerializedName("cpuallocated")
@Param(description = "the total cpu allocated in Ghz")
private String cpuAllocated;
@SerializedName("cpumaxdeviation")
@Param(description = "the maximum cpu deviation")
private String cpuMaxDeviation;
@SerializedName("memorytotal")
@Param(description = "the total cpu capacity in GiB")
private String memTotal;
@SerializedName("memoryused")
@Param(description = "the total cpu used in GiB")
private String memUsed;
@SerializedName("memoryallocated")
@Param(description = "the total cpu allocated in GiB")
private String memAllocated;
@SerializedName("memorymaxdeviation")
@Param(description = "the maximum memory deviation")
private String memMaxDeviation;
@SerializedName("cputhreshold")
@Param(description = "cpu usage notification threshold exceeded")
private Boolean cpuThresholdExceeded;
@SerializedName("cpudisablethreshold")
@Param(description = "cpu usage disable threshold exceeded")
private Boolean cpuDisableThresholdExceeded;
@SerializedName("cpuallocatedthreshold")
@Param(description = "cpu allocated notification threshold exceeded")
private Boolean cpuAllocatedThresholdExceeded;
@SerializedName("cpuallocateddisablethreshold")
@Param(description = "cpu allocated disable threshold exceeded")
private Boolean cpuAllocatedDisableThresholdExceeded;
@SerializedName("memorythreshold")
@Param(description = "memory usage notification threshold exceeded")
private Boolean memoryThresholdExceeded;
@SerializedName("memorydisablethreshold")
@Param(description = "memory usage disable threshold exceeded")
private Boolean memoryDisableThresholdExceeded;
@SerializedName("memoryallocatedthreshold")
@Param(description = "memory allocated notification threshold exceeded")
private Boolean memoryAllocatedThresholdExceeded;
@SerializedName("memoryallocateddisablethreshold")
@Param(description = "memory allocated disable threshold exceeded")
private Boolean memoryAllocatedDisableThresholdExceeded;
public void setState(final String allocationState) {
this.state = allocationState;
}
public void setResource(final Long upResources, final Long totalResources) {
if (upResources != null && totalResources != null) {
this.resources = String.format("%d / %d", upResources, totalResources);
}
}
public void setCpuTotal(final Long cpuTotal) {
if (cpuTotal != null) {
this.cpuTotal = String.format("%.2f Ghz", cpuTotal / 1000.0);
}
}
public void setCpuUsed(final Double cpuUsedPercentage, final Long totalHosts) {
if (cpuUsedPercentage != null && totalHosts != null && totalHosts != 0) {
this.cpuUsed = String.format("%.2f%%", 1.0 * cpuUsedPercentage / totalHosts);
}
}
public void setCpuAllocated(final Long cpuAllocated, final Long cpuTotal) {
if (cpuAllocated != null && cpuTotal != null && cpuTotal != 0) {
this.cpuAllocated = String.format("%.2f%%", cpuAllocated * 100.0 / cpuTotal);
}
}
public void setCpuMaxDeviation(final Double maxCpuDeviation, final Double totalCpuUsed, final Long totalHosts) {
if (maxCpuDeviation != null && totalCpuUsed != null && totalHosts != null && totalHosts != 0) {
final Double averageCpuUsage = totalCpuUsed / totalHosts;
this.cpuMaxDeviation = String.format("%.2f%%", (maxCpuDeviation - averageCpuUsage) * 100.0 / averageCpuUsage);
}
}
public void setMemTotal(final Long memTotal) {
if (memTotal != null) {
this.memTotal = String.format("%.2f GB", memTotal / (1024.0 * 1024.0 * 1024.0));
}
}
public void setMemUsed( final Long memUsed, final Long memTotal) {
if (memUsed != null && memTotal != null) {
this.memUsed = String.format("%.2f%%", memUsed * 100.0 / memTotal);
}
}
public void setMemAllocated(final Long memAllocated, final Long memTotal) {
if (memAllocated != null && memTotal != null && memTotal != 0) {
this.memAllocated = String.format("%.2f%%", memAllocated * 100.0 / memTotal);
}
}
public void setMemMaxDeviation(final Long maxMemoryUsage, final Long totalMemory, final Long totalHosts) {
if (maxMemoryUsage != null && totalMemory != null && totalHosts != null && totalHosts != 0) {
final Long averageMemoryUsage = totalMemory / totalHosts;
this.memMaxDeviation = String.format("%.2f%%", (maxMemoryUsage - averageMemoryUsage) * 100.0 / averageMemoryUsage);
}
}
public void setCpuUsageThreshold(final Double cpuUsed, final Long totalHosts, final Double threshold) {
if (cpuUsed != null && totalHosts != null && threshold != null && totalHosts != 0) {
this.cpuThresholdExceeded = (cpuUsed / (100.0 * totalHosts)) > threshold;
}
}
public void setCpuUsageDisableThreshold(final Double cpuUsed, final Long totalHosts, final Float threshold) {
if (cpuUsed != null && totalHosts != null && threshold != null && totalHosts != 0) {
this.cpuDisableThresholdExceeded = (cpuUsed / (100.0 * totalHosts)) > threshold;
}
}
public void setCpuAllocatedThreshold(final Long cpuAllocated, final Long cpuUsed, final Double threshold) {
if (cpuAllocated != null && cpuUsed != null && threshold != null && cpuUsed != 0) {
this.cpuAllocatedThresholdExceeded = (1.0 * cpuAllocated / cpuUsed) > threshold;
}
}
public void setCpuAllocatedDisableThreshold(final Long cpuAllocated, final Long cpuUsed, final Float threshold) {
if (cpuAllocated != null && cpuUsed != null && threshold != null && cpuUsed != 0) {
this.cpuAllocatedDisableThresholdExceeded = (1.0 * cpuAllocated / cpuUsed) > threshold;
}
}
public void setMemoryUsageThreshold(final Long memUsed, final Long memTotal, final Double threshold) {
if (memUsed != null && memTotal != null && threshold != null && memTotal != 0) {
this.memoryThresholdExceeded = (1.0 * memUsed / memTotal) > threshold;
}
}
public void setMemoryUsageDisableThreshold(final Long memUsed, final Long memTotal, final Float threshold) {
if (memUsed != null && memTotal != null && threshold != null && memTotal != 0) {
this.memoryDisableThresholdExceeded = (1.0 * memUsed / memTotal) > threshold;
}
}
public void setMemoryAllocatedThreshold(final Long memAllocated, final Long memTotal, final Double threshold) {
if (memAllocated != null && memTotal != null && threshold != null && memTotal != 0) {
this.memoryAllocatedThresholdExceeded = (1.0 * memAllocated / memTotal) > threshold;
}
}
public void setMemoryAllocatedDisableThreshold(final Long memAllocated, final Long memTotal, final Float threshold) {
if (memAllocated != null && memTotal != null && threshold != null && memTotal != 0) {
this.memoryAllocatedDisableThresholdExceeded = (1.0 * memAllocated / memTotal) > threshold;
}
}
}

View File

@ -69,6 +69,7 @@
<module>hypervisors/ucs</module>
<module>hypervisors/hyperv</module>
<module>hypervisors/ovm3</module>
<module>metrics</module>
<module>network-elements/elastic-loadbalancer</module>
<module>network-elements/ovs</module>
<module>network-elements/juniper-contrail</module>

View File

@ -41,4 +41,6 @@ public interface HostJoinDao extends GenericDao<HostJoinVO, Long> {
List<HostJoinVO> searchByIds(Long... ids);
List<HostJoinVO> findByClusterId(Long clusterId, Host.Type type);
}

View File

@ -65,6 +65,8 @@ public class HostJoinDaoImpl extends GenericDaoBase<HostJoinVO, Long> implements
private final SearchBuilder<HostJoinVO> hostIdSearch;
private final SearchBuilder<HostJoinVO> ClusterSearch;
protected HostJoinDaoImpl() {
hostSearch = createSearchBuilder();
@ -75,6 +77,11 @@ public class HostJoinDaoImpl extends GenericDaoBase<HostJoinVO, Long> implements
hostIdSearch.and("id", hostIdSearch.entity().getId(), SearchCriteria.Op.EQ);
hostIdSearch.done();
ClusterSearch = createSearchBuilder();
ClusterSearch.and("clusterId", ClusterSearch.entity().getClusterId(), SearchCriteria.Op.EQ);
ClusterSearch.and("type", ClusterSearch.entity().getType(), SearchCriteria.Op.EQ);
ClusterSearch.done();
this._count = "select count(distinct id) from host_view WHERE ";
}
@ -432,4 +439,12 @@ public class HostJoinDaoImpl extends GenericDaoBase<HostJoinVO, Long> implements
return uvList;
}
@Override
public List<HostJoinVO> findByClusterId(Long clusterId, Host.Type type) {
SearchCriteria<HostJoinVO> sc = ClusterSearch.create();
sc.setParameters("clusterId", clusterId);
sc.setParameters("type", type);
return listBy(sc);
}
}

View File

@ -588,7 +588,7 @@ StateListener<State, VirtualMachine.Event, VirtualMachine> {
List<Long> allDedicatedPods = _dedicatedDao.listAllPods();
allPodsInDc.retainAll(allDedicatedPods);
List<Long> allClustersInDc = _clusterDao.listAllCusters(dc.getId());
List<Long> allClustersInDc = _clusterDao.listAllClusters(dc.getId());
List<Long> allDedicatedClusters = _dedicatedDao.listAllClusters();
allClustersInDc.retainAll(allDedicatedClusters);

View File

@ -0,0 +1,210 @@
# 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.
import marvin
from marvin.cloudstackTestCase import *
from marvin.cloudstackAPI import *
from marvin.lib.utils import *
from marvin.lib.base import *
from marvin.lib.common import *
from marvin.lib.utils import (random_gen)
from nose.plugins.attrib import attr
import time
_multiprocess_shared_ = True
class TestMetrics(cloudstackTestCase):
def setUp(self):
self.apiclient = self.testClient.getApiClient()
self.hypervisor = self.testClient.getHypervisorInfo()
self.dbclient = self.testClient.getDbConnection()
self.services = self.testClient.getParsedTestDataConfig()
self.zone = get_zone(self.apiclient, self.testClient.getZoneForTests())
self.pod = get_pod(self.apiclient, self.zone.id)
self.host = list_hosts(self.apiclient,
zoneid=self.zone.id,
type='Routing')[0]
self.cluster = self.apiclient.listClusters(listClusters.listClustersCmd())[0]
self.disk_offering = DiskOffering.create(
self.apiclient,
self.services["disk_offering"]
)
self.service_offering = ServiceOffering.create(
self.apiclient,
self.services["service_offering"]
)
self.template = get_template(
self.apiclient,
self.zone.id,
self.services["ostype"]
)
self.cleanup = []
self.cleanup.append(self.disk_offering)
self.cleanup.append(self.service_offering)
def tearDown(self):
try:
#Clean up
cleanup_resources(self.apiclient, self.cleanup)
except Exception as e:
raise Exception("Warning: Exception during cleanup : %s" % e)
@attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
def test_list_hosts_metrics(self):
cmd = listHostsMetrics.listHostsMetricsCmd()
cmd.id = self.host.id
cmd.type = 'Routing'
host_metric = self.apiclient.listHostsMetrics(cmd)[0]
self.assertEqual(host_metric.cpuallocated, self.host.cpuallocated)
self.assertEqual(host_metric.memoryallocated, self.host.memoryallocated)
@attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
def test_list_clusters_metrics(self):
cmd = listClustersMetrics.listClustersMetricsCmd()
cmd.id = self.cluster.id
cluster_metric = self.apiclient.listClustersMetrics(cmd)[0]
self.assertEqual(cluster_metric.id, self.cluster.id)
self.assertTrue(hasattr(cluster_metric, 'cpuallocated'))
self.assertTrue(hasattr(cluster_metric, 'cpumaxdeviation'))
self.assertTrue(hasattr(cluster_metric, 'memoryallocated'))
self.assertTrue(hasattr(cluster_metric, 'memoryused'))
self.assertTrue(hasattr(cluster_metric, 'memorymaxdeviation'))
@attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
def test_list_zones_metrics(self):
cmd = listZonesMetrics.listZonesMetricsCmd()
cmd.id = self.zone.id
zone_metrics = self.apiclient.listZonesMetrics(cmd)[0]
self.assertTrue(hasattr(zone_metrics, 'cpuallocated'))
self.assertTrue(hasattr(zone_metrics, 'cpumaxdeviation'))
self.assertTrue(hasattr(zone_metrics, 'cputotal'))
self.assertTrue(hasattr(zone_metrics, 'cpuused'))
self.assertTrue(hasattr(zone_metrics, 'memoryallocated'))
self.assertTrue(hasattr(zone_metrics, 'memorymaxdeviation'))
self.assertTrue(hasattr(zone_metrics, 'memoryused'))
@attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
def test_list_vms_metrics(self):
#deploy VM
self.small_virtual_machine = VirtualMachine.create(
self.apiclient,
self.services["virtual_machine"],
serviceofferingid=self.service_offering.id,
templateid=self.template.id,
zoneid=self.zone.id
)
self.cleanup.append(self.small_virtual_machine)
cmd = listVirtualMachinesMetrics.listVirtualMachinesMetricsCmd()
cmd.id = self.small_virtual_machine.id
lvmm = self.apiclient.listVirtualMachinesMetrics(cmd)[0]
self.assertEqual(lvmm.id, self.small_virtual_machine.id)
self.assertTrue(hasattr(lvmm, 'cputotal'))
self.assertTrue(hasattr(lvmm, 'cpuused'))
self.assertTrue(hasattr(lvmm, 'diskiowrite'))
self.assertTrue(hasattr(lvmm, 'diskkbswrite'))
self.assertTrue(hasattr(lvmm, 'networkread'))
self.assertTrue(hasattr(lvmm, 'networkwrite'))
return
@attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
def test_list_pstorage_metrics(self):
#list StoragePools
sp = self.apiclient.listStoragePools(listStoragePools.listStoragePoolsCmd())[0]
#list StoragePoolsMetrics
cmd = listStoragePoolsMetrics.listStoragePoolsMetricsCmd()
cmd.id = sp.id
sp_metrics = self.apiclient.listStoragePoolsMetrics(cmd)[0]
self.assertEqual(sp_metrics.disksizeallocated, sp.disksizeallocated)
self.assertEqual(sp_metrics.state, sp.state)
@attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
def test_list_volumes_metrics(self):
volume = Volume.create(
self.apiclient,
self.services['volume'],
zoneid=self.zone.id,
diskofferingid=self.disk_offering.id
)
self.cleanup.append(volume)
cmd = listVolumes.listVolumesCmd()
cmd.id = volume.id
lv = self.apiclient.listVolumes(cmd)[0]
cmd = listVolumesMetrics.listVolumesMetricsCmd()
cmd.id = lv.id
lvm = self.apiclient.listVolumesMetrics(cmd)[0]
self.assertEqual(lv.size, lvm.size)
self.assertTrue(hasattr(lvm, 'diskBytesReadRate'))
self.assertTrue(hasattr(lvm, 'diskBytesWriteRate'))
self.assertTrue(hasattr(lvm, 'diskIopsReadRate'))
self.assertTrue(hasattr(lvm, 'diskIopsWriteRate'))
return
@attr(tags = ["advanced", "advancedns", "smoke", "basic"], required_hardware="false")
def test_list_infrastructure_metrics(self):
cmd = listInfrastructure.listInfrastructureCmd()
li = self.apiclient.listInfrastructure(cmd)
self.assertTrue(hasattr(li, 'clusters'))
self.assertEqual(li.clusters, len(self.apiclient.listClusters(listClusters.listClustersCmd())))
self.assertTrue(hasattr(li, 'hosts'))
self.assertEqual(li.hosts, len(list_hosts(self.apiclient,
zoneid=self.zone.id,
type='Routing')))
self.assertTrue(hasattr(li, 'imagestores'))
self.assertEqual(li.imagestores, len(self.apiclient.listImageStores(listImageStores.listImageStoresCmd())))
self.assertTrue(hasattr(li, 'pods'))
self.assertEqual(li.pods, len(self.apiclient.listPods(listPods.listPodsCmd())))
self.assertTrue(hasattr(li, 'routers'))
self.assertTrue(hasattr(li, 'storagepools'))
self.assertEqual(li.storagepools, len(self.apiclient.listStoragePools(listStoragePools.listStoragePoolsCmd())))
self.assertTrue(hasattr(li, 'zones'))
self.assertEqual(li.zones, len(self.apiclient.listZones(listZones.listZonesCmd())))
self.assertTrue(hasattr(li, 'systemvms'))
self.assertTrue(hasattr(li, 'cpusockets'))

View File

@ -168,7 +168,9 @@ known_categories = {
'CacheStore' : 'Cache Store',
'IAM' : 'IAM',
'OvsElement' : 'Ovs Element',
'StratosphereSsp' : ' Stratosphere SSP'
'StratosphereSsp' : ' Stratosphere SSP',
'Metrics' : 'Metrics',
'Infrastructure' : 'Metrics',
}

View File

@ -56,15 +56,15 @@
label: 'label.metrics.cpu.usage',
collapsible: true,
columns: {
cpuusedavg: {
cpuused: {
label: 'label.metrics.cpu.used.avg',
thresholdcolor: true,
thresholds: {
notification: 'cpunotificationthreshold',
notification: 'cputhreshold',
disable: 'cpudisablethreshold'
}
},
cpumaxdev: {
cpumaxdeviation: {
label: 'label.metrics.cpu.max.dev'
}
}
@ -77,8 +77,8 @@
label: 'label.metrics.allocated',
thresholdcolor: true,
thresholds: {
notification: 'cpunotificationthreshold',
disable: 'cpudisablethreshold'
notification: 'cpuallocatedthreshold',
disable: 'cpuallocateddisablethreshold'
}
},
cputotal: {
@ -90,15 +90,15 @@
label: 'label.metrics.memory.usage',
collapsible: true,
columns: {
memusedavg: {
memoryused: {
label: 'label.metrics.memory.used.avg',
thresholdcolor: true,
thresholds: {
notification: 'memnotificationthreshold',
disable: 'memdisablethreshold'
notification: 'memorythreshold',
disable: 'memorydisablethreshold'
}
},
memmaxdev: {
memorymaxdeviation: {
label: 'label.metrics.memory.max.dev'
}
}
@ -107,15 +107,15 @@
label: 'label.metrics.memory.allocated',
collapsible: true,
columns: {
memallocated: {
memoryallocated: {
label: 'label.metrics.allocated',
thresholdcolor: true,
thresholds: {
notification: 'memnotificationthreshold',
disable: 'memdisablethreshold'
notification: 'memoryallocatedthreshold',
disable: 'memoryallocateddisablethreshold'
}
},
memtotal: {
memorytotal: {
label: 'label.metrics.memory.total'
}
}
@ -125,129 +125,11 @@
var data = {};
listViewDataProvider(args, data);
$.ajax({
url: createURL('listZones'),
url: createURL('listZonesMetrics'),
data: data,
success: function(json) {
var items = json.listzonesresponse.zone;
if (items) {
$.each(items, function(idx, zone) {
items[idx].clusters = 0;
items[idx].clustersUp = 0;
items[idx].hosts = 0;
items[idx].cpuusedavg = 0.0;
items[idx].cpumaxdev = 0.0;
items[idx].cpuallocated = 0.0;
items[idx].cputotal = 0.0;
items[idx].maxCpuUsed = 0.0;
items[idx].memusedavg = 0.0;
items[idx].memmaxdev = 0.0;
items[idx].memallocated = 0.0;
items[idx].memtotal = 0.0;
items[idx].maxMemUsed = 0.0;
// Threshold color coding
items[idx].cpunotificationthreshold = 75.0;
items[idx].cpudisablethreshold = 95.0;
items[idx].memnotificationthreshold = 75.0;
items[idx].memdisablethreshold = 95.0;
$.ajax({
url: createURL('listClusters'),
data: {zoneid: zone.id, pagesize: -1},
success: function(json) {
if (json && json.listclustersresponse && json.listclustersresponse.cluster && json.listclustersresponse.count) {
items[idx].clusters += parseInt(json.listclustersresponse.count);
$.each(json.listclustersresponse.cluster, function(i, cluster) {
if (cluster.allocationstate == 'Enabled' && cluster.managedstate == 'Managed') {
items[idx].clustersUp += 1;
}
$.ajax({
url: createURL('listHosts'),
data: {clusterid: cluster.id, type: 'routing', pagesize: -1},
success: function(json) {
if (json && json.listhostsresponse && json.listhostsresponse.host && json.listhostsresponse.count) {
items[idx].hosts += parseInt(json.listhostsresponse.count);
$.each(json.listhostsresponse.host, function(i, host) {
if (host.hasOwnProperty('cpuused')) {
var hostCpuUsage = parseFloat(host.cpuused);
items[idx].cpuusedavg += hostCpuUsage;
if (hostCpuUsage > items[idx].maxCpuUsed) {
items[idx].maxCpuUsed = hostCpuUsage;
}
}
if (host.hasOwnProperty('cpuallocated')) {
items[idx].cpuallocated += parseFloat(host.cpuallocated.replace('%', ''));
}
if (host.hasOwnProperty('memoryused')) {
var hostMemoryUsage = 100.0 * parseFloat(host.memoryused) / parseFloat(host.memorytotal);
items[idx].memusedavg += hostMemoryUsage;
if (hostMemoryUsage > items[idx].maxMemUsed) {
items[idx].maxMemUsed = hostMemoryUsage;
}
}
if (host.hasOwnProperty('memoryallocated')) {
items[idx].memallocated += parseFloat(100.0 * parseFloat(host.memoryallocated)/parseFloat(host.memorytotal));
}
});
}
},
async: false
});
});
}
},
async: false
});
$.ajax({
url: createURL('listCapacity'),
data: {zoneid: zone.id},
success: function(json) {
if (json && json.listcapacityresponse && json.listcapacityresponse.capacity) {
$.each(json.listcapacityresponse.capacity, function(i, capacity) {
// CPU
if (capacity.type == 1) {
items[idx].cputotal = parseInt(capacity.capacitytotal)/1000.0;
}
// Memory
if (capacity.type == 0) {
items[idx].memtotal = parseInt(capacity.capacitytotal)/(1024.0*1024.0*1024.0);
}
});
}
},
async: false
});
if (items[idx].hosts != 0) {
items[idx].cpuusedavg = (items[idx].cpuusedavg / items[idx].hosts);
items[idx].cpumaxdev = (items[idx].maxCpuUsed - items[idx].cpuusedavg);
items[idx].cpuallocated = (items[idx].cpuallocated / items[idx].hosts);
items[idx].memusedavg = (items[idx].memusedavg / items[idx].hosts);
items[idx].memmaxdev = (items[idx].maxMemUsed - items[idx].memusedavg);
items[idx].memallocated = (items[idx].memallocated / items[idx].hosts);
}
// Format data
items[idx].cpuusedavg = (items[idx].cpuusedavg).toFixed(2) + "%";
items[idx].cpumaxdev = (items[idx].cpumaxdev).toFixed(2) + "%";
items[idx].cpuallocated = (items[idx].cpuallocated).toFixed(2) + "%";
items[idx].cputotal = (items[idx].cputotal).toFixed(2) + " Ghz";
items[idx].memusedavg = (items[idx].memusedavg).toFixed(2) + "%";
items[idx].memmaxdev = (items[idx].memmaxdev).toFixed(2) + "%";
items[idx].memallocated = (items[idx].memallocated).toFixed(2) + "%";
items[idx].memtotal = (items[idx].memtotal).toFixed(2) + " GB";
items[idx].clusters = items[idx].clustersUp + ' / ' + items[idx].clusters;
items[idx].state = items[idx].allocationstate;
});
}
args.response.success({
data: items
data: json.listzonesmetricsresponse.zone
});
}
});
@ -290,15 +172,15 @@
label: 'label.metrics.cpu.usage',
collapsible: true,
columns: {
cpuusedavg: {
cpuused: {
label: 'label.metrics.cpu.used.avg',
thresholdcolor: true,
thresholds: {
notification: 'cpunotificationthreshold',
notification: 'cputhreshold',
disable: 'cpudisablethreshold'
}
},
cpumaxdev: {
cpumaxdeviation: {
label: 'label.metrics.cpu.max.dev'
}
}
@ -311,8 +193,8 @@
label: 'label.metrics.allocated',
thresholdcolor: true,
thresholds: {
notification: 'cpunotificationthreshold',
disable: 'cpudisablethreshold'
notification: 'cpuallocatedthreshold',
disable: 'cpuallocateddisablethreshold'
}
},
cputotal: {
@ -324,15 +206,15 @@
label: 'label.metrics.memory.usage',
collapsible: true,
columns: {
memusedavg: {
memoryused: {
label: 'label.metrics.memory.used.avg',
thresholdcolor: true,
thresholds: {
notification: 'memnotificationthreshold',
disable: 'memdisablethreshold'
notification: 'memorythreshold',
disable: 'memorydisablethreshold'
}
},
memmaxdev: {
memorymaxdeviation: {
label: 'label.metrics.memory.max.dev'
}
}
@ -341,15 +223,15 @@
label: 'label.metrics.memory.allocated',
collapsible: true,
columns: {
memallocated: {
memoryallocated: {
label: 'label.metrics.allocated',
thresholdcolor: true,
thresholds: {
notification: 'memnotificationthreshold',
disable: 'memdisablethreshold'
notification: 'memoryallocatedthreshold',
disable: 'memoryallocateddisablethreshold'
}
},
memtotal: {
memorytotal: {
label: 'label.metrics.memory.total'
}
}
@ -372,154 +254,11 @@
}
$.ajax({
url: createURL('listClusters'),
url: createURL('listClustersMetrics'),
data: data,
success: function(json) {
var items = json.listclustersresponse.cluster;
if (items) {
$.each(items, function(idx, cluster) {
items[idx].hosts = 0;
items[idx].hostsUp = 0;
items[idx].cpuusedavg = 0.0;
items[idx].cpumaxdev = 0.0;
items[idx].cpuallocated = 0.0;
items[idx].cputotal = 0.0;
items[idx].maxCpuUsed = 0;
items[idx].memusedavg = 0.0;
items[idx].memmaxdev = 0.0;
items[idx].memallocated = 0.0;
items[idx].memtotal = 0.0;
items[idx].maxMemUsed = 0.0;
// Threshold color coding
items[idx].cpunotificationthreshold = 75.0;
items[idx].cpudisablethreshold = 95.0;
items[idx].memnotificationthreshold = 75.0;
items[idx].memdisablethreshold = 95.0;
$.ajax({
url: createURL('listConfigurations'),
data: {clusterid: cluster.id, listAll: true},
success: function(json) {
if (json.listconfigurationsresponse && json.listconfigurationsresponse.configuration) {
$.each(json.listconfigurationsresponse.configuration, function(i, config) {
switch (config.name) {
case 'cluster.cpu.allocated.capacity.disablethreshold':
items[idx].cpudisablethreshold = 100 * parseFloat(config.value);
break;
case 'cluster.cpu.allocated.capacity.notificationthreshold':
items[idx].cpunotificationthreshold = 100 * parseFloat(config.value);
break;
case 'cluster.memory.allocated.capacity.disablethreshold':
items[idx].memdisablethreshold = 100 * parseFloat(config.value);
break;
case 'cluster.memory.allocated.capacity.notificationthreshold':
items[idx].memnotificationthreshold = 100 * parseFloat(config.value);
break;
}
});
}
},
async: false
});
$.ajax({
url: createURL('listHosts'),
data: {clusterid: cluster.id, type: 'routing', pagesize: -1},
success: function(json) {
if (json && json.listhostsresponse && json.listhostsresponse.host && json.listhostsresponse.count) {
items[idx].hosts += parseInt(json.listhostsresponse.count);
$.each(json.listhostsresponse.host, function(i, host) {
if (host.state == 'Up') {
items[idx].hostsUp += 1;
}
if (host.hasOwnProperty('cpuused')) {
var hostCpuUsage = parseFloat(host.cpuused);
items[idx].cpuusedavg += hostCpuUsage;
if (hostCpuUsage > items[idx].maxCpuUsed) {
items[idx].maxCpuUsed = hostCpuUsage;
}
}
if (host.hasOwnProperty('cpuallocated')) {
items[idx].cpuallocated += parseFloat(host.cpuallocated.replace('%', ''));
}
if (host.hasOwnProperty('memoryused')) {
var hostMemoryUsage = 100.0 * parseFloat(host.memoryused) / parseFloat(host.memorytotal);
items[idx].memusedavg += hostMemoryUsage;
if (hostMemoryUsage > items[idx].maxMemUsed) {
items[idx].maxMemUsed = hostMemoryUsage;
}
}
if (host.hasOwnProperty('memoryallocated')) {
items[idx].memallocated += parseFloat(100.0 * parseFloat(host.memoryallocated)/parseFloat(host.memorytotal));
}
});
}
},
async: false
});
$.ajax({
url: createURL('listCapacity'),
data: {clusterid: cluster.id},
success: function(json) {
if (json && json.listcapacityresponse && json.listcapacityresponse.capacity) {
$.each(json.listcapacityresponse.capacity, function(i, capacity) {
// CPU
if (capacity.type == 1) {
items[idx].cputotal = parseInt(capacity.capacitytotal)/1000.0;
}
// Memory
if (capacity.type == 0) {
items[idx].memtotal = parseInt(capacity.capacitytotal)/(1024.0*1024.0*1024.0);
}
});
}
},
async: false
});
if (items[idx].hosts != 0) {
items[idx].cpuusedavg = (items[idx].cpuusedavg / items[idx].hosts);
items[idx].cpumaxdev = (items[idx].maxCpuUsed - items[idx].cpuusedavg);
items[idx].cpuallocated = (items[idx].cpuallocated / items[idx].hosts);
items[idx].memusedavg = (items[idx].memusedavg / items[idx].hosts);
items[idx].memmaxdev = (items[idx].maxMemUsed - items[idx].memusedavg);
items[idx].memallocated = (items[idx].memallocated / items[idx].hosts);
}
// Format data
items[idx].cpuusedavg = (items[idx].cpuusedavg).toFixed(2) + "%";
items[idx].cpumaxdev = (items[idx].cpumaxdev).toFixed(2) + "%";
items[idx].cpuallocated = (items[idx].cpuallocated).toFixed(2) + "%";
items[idx].cputotal = (items[idx].cputotal).toFixed(2) + " Ghz";
items[idx].memusedavg = (items[idx].memusedavg).toFixed(2) + "%";
items[idx].memmaxdev = (items[idx].memmaxdev).toFixed(2) + "%";
items[idx].memallocated = (items[idx].memallocated).toFixed(2) + "%";
items[idx].memtotal = (items[idx].memtotal).toFixed(2) + " GB";
items[idx].hosts = items[idx].hostsUp + ' / ' + items[idx].hosts;
items[idx].state = items[idx].allocationstate;
if (items[idx].managedstate == 'Unmanaged') {
items[idx].state = 'Unmanaged';
}
if (items[idx].managedstate == 'Managed' && items[idx].allocationstate == 'Enabled') {
items[idx].state = 'Enabled';
}
if (items[idx].managedstate == 'Managed' && items[idx].allocationstate == 'Disabled') {
items[idx].state = 'Disabled';
}
});
}
args.response.success({
data: items
data: json.listclustersmetricsresponse.cluster
});
}
});
@ -560,7 +299,7 @@
},
compact: true
},
outofbandmanagementpowerstate: {
powerstate: {
label: 'label.metrics.outofbandmanagementpowerstate',
converter: function (str) {
// For localization
@ -580,25 +319,25 @@
label: 'label.metrics.cpu.usage',
collapsible: true,
columns: {
cores: {
label: 'label.metrics.num.cpu.cores'
cpunumber: {
label: 'label.metrics.num.cpu.cores',
},
cputotal: {
cputotalghz: {
label: 'label.metrics.cpu.total'
},
cpuusedavg: {
cpuusedghz: {
label: 'label.metrics.cpu.used.avg',
thresholdcolor: true,
thresholds: {
notification: 'cpunotificationthreshold',
notification: 'cputhreshold',
disable: 'cpudisablethreshold'
}
},
cpuallocated: {
cpuallocatedghz: {
label: 'label.metrics.allocated',
thresholdcolor: true,
thresholds: {
notification: 'cpuallocatednotificationthreshold',
notification: 'cpuallocatedthreshold',
disable: 'cpuallocateddisablethreshold'
}
}
@ -608,23 +347,23 @@
label: 'label.metrics.memory.usage',
collapsible: true,
columns: {
memtotal: {
memorytotalgb: {
label: 'label.metrics.memory.total'
},
memusedavg: {
memoryusedgb: {
label: 'label.metrics.memory.used.avg',
thresholdcolor: true,
thresholds: {
notification: 'memnotificationthreshold',
disable: 'memdisablethreshold'
notification: 'memorythreshold',
disable: 'memorydisablethreshold'
}
},
memallocated: {
memoryallocatedgb: {
label: 'label.metrics.allocated',
thresholdcolor: true,
thresholds: {
notification: 'memallocatednotificationthreshold',
disable: 'memallocateddisablethreshold'
notification: 'memoryallocatedthreshold',
disable: 'memoryallocateddisablethreshold'
}
}
}
@ -670,123 +409,11 @@
}
$.ajax({
url: createURL('listHosts'),
url: createURL('listHostsMetrics'),
data: data,
success: function(json) {
var items = json.listhostsresponse.host;
if (items) {
$.each(items, function(idx, host) {
if (host && host.outofbandmanagement) {
items[idx].outofbandmanagementpowerstate = host.outofbandmanagement.powerstate;
}
items[idx].cores = host.cpunumber;
items[idx].cputotal = (parseFloat(host.cpunumber) * parseFloat(host.cpuspeed) / 1000.0).toFixed(2);
if (host.cpuused) {
items[idx].cpuusedavg = (parseFloat(host.cpuused) * items[idx].cputotal / 100.0).toFixed(2) + ' Ghz';
} else {
items[idx].cpuusedavg = '';
}
items[idx].cpuallocated = (parseFloat(host.cpuallocated) * items[idx].cputotal / 100.0).toFixed(2) + ' Ghz';
items[idx].memtotal = (parseFloat(host.memorytotal)/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB';
items[idx].memallocated = (parseFloat(host.memoryallocated)/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB';
if (host.memoryused) {
items[idx].memusedavg = (parseFloat(host.memoryused)/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB';
} else {
items[idx].memusedavg = '';
}
if (host.networkkbsread && host.networkkbswrite) {
items[idx].networkread = (parseFloat(host.networkkbsread)/(1024.0*1024.0)).toFixed(2) + ' GB';
items[idx].networkwrite = (parseFloat(host.networkkbswrite)/(1024.0*1024.0)).toFixed(2) + ' GB';
} else {
items[idx].networkread = '';
items[idx].networkwrite = '';
}
var cpuOverCommit = 1.0;
var memOverCommit = 1.0;
$.ajax({
url: createURL('listClusters'),
data: {clusterid: host.clusterid, listAll: true},
success: function(json) {
if (json.listclustersresponse && json.listclustersresponse.cluster) {
var cluster = json.listclustersresponse.cluster[0];
cpuOverCommit = parseFloat(cluster.cpuovercommitratio);
memOverCommit = parseFloat(cluster.memoryovercommitratio);
}
},
async: false
});
// Threshold color coding
items[idx].cpunotificationthreshold = 0.75 * parseFloat(items[idx].cputotal);
items[idx].cpudisablethreshold = 0.95 * parseFloat(items[idx].cputotal);
items[idx].cpuallocatednotificationthreshold = 0.75 * cpuOverCommit * parseFloat(items[idx].cputotal);
items[idx].cpuallocateddisablethreshold = 0.95 * cpuOverCommit * parseFloat(items[idx].cputotal);
items[idx].memnotificationthreshold = 0.75 * parseFloat(items[idx].memtotal);
items[idx].memdisablethreshold = 0.95 * parseFloat(items[idx].memtotal);
items[idx].memallocatednotificationthreshold = 0.75 * memOverCommit * parseFloat(items[idx].memtotal);
items[idx].memallocateddisablethreshold = 0.95 * memOverCommit * parseFloat(items[idx].memtotal);
$.ajax({
url: createURL('listConfigurations'),
data: {clusterid: host.clusterid, listAll: true},
success: function(json) {
if (json.listconfigurationsresponse && json.listconfigurationsresponse.configuration) {
$.each(json.listconfigurationsresponse.configuration, function(i, config) {
switch (config.name) {
case 'cluster.cpu.allocated.capacity.disablethreshold':
items[idx].cpudisablethreshold = parseFloat(config.value) * parseFloat(items[idx].cputotal);
items[idx].cpuallocateddisablethreshold = parseFloat(config.value) * cpuOverCommit * parseFloat(items[idx].cputotal);
break;
case 'cluster.cpu.allocated.capacity.notificationthreshold':
items[idx].cpunotificationthreshold = parseFloat(config.value) * parseFloat(items[idx].cputotal);
items[idx].cpuallocatednotificationthreshold = parseFloat(config.value) * cpuOverCommit * parseFloat(items[idx].cputotal);
break;
case 'cluster.memory.allocated.capacity.disablethreshold':
items[idx].memdisablethreshold = parseFloat(config.value) * parseFloat(items[idx].memtotal);
items[idx].memallocateddisablethreshold = parseFloat(config.value) * memOverCommit * parseFloat(items[idx].memtotal);
break;
case 'cluster.memory.allocated.capacity.notificationthreshold':
items[idx].memnotificationthreshold = parseFloat(config.value) * parseFloat(items[idx].memtotal);
items[idx].memallocatednotificationthreshold = parseFloat(config.value) * memOverCommit * parseFloat(items[idx].memtotal);
break;
}
});
}
},
async: false
});
items[idx].cputotal = items[idx].cputotal + ' Ghz (x' + cpuOverCommit + ')';
items[idx].memtotal = items[idx].memtotal + ' (x' + memOverCommit + ')';
items[idx].instances = 0;
items[idx].instancesUp = 0;
$.ajax({
url: createURL('listVirtualMachines'),
data: {hostid: host.id, listAll: true},
success: function(json) {
if (json && json.listvirtualmachinesresponse && json.listvirtualmachinesresponse.virtualmachine) {
var vms = json.listvirtualmachinesresponse.virtualmachine;
if (vms) {
$.each(vms, function(_, vm) {
items[idx].instances += 1;
if (vm.state == 'Running') {
items[idx].instancesUp += 1;
}
});
}
}
},
async: false
});
items[idx].instances = items[idx].instancesUp + ' / ' + items[idx].instances;
});
}
args.response.success({
data: items
data: json.listhostsmetricsresponse.host
});
}
});
@ -838,14 +465,14 @@
label: 'label.metrics.cpu.usage',
collapsible: true,
columns: {
cores: {
label: 'label.metrics.num.cpu.cores'
cpunumber: {
label: 'label.metrics.num.cpu.cores',
},
cputotal: {
label: 'label.metrics.cpu.total'
},
cpuused: {
label: 'label.metrics.cpu.used.avg'
label: 'label.metrics.cpu.used.avg',
}
}
},
@ -853,7 +480,7 @@
label: 'label.metrics.memory.usage',
collapsible: true,
columns: {
memallocated: {
memorytotal: {
label: 'label.metrics.allocated'
}
}
@ -874,10 +501,10 @@
label: 'label.metrics.disk.usage',
collapsible: true,
columns: {
diskread: {
diskioread: {
label: 'label.metrics.disk.read'
},
diskwrite: {
diskiowrite: {
label: 'label.metrics.disk.write'
},
diskiopstotal: {
@ -899,45 +526,11 @@
}
$.ajax({
url: createURL('listVirtualMachines'),
url: createURL('listVirtualMachinesMetrics'),
data: data,
success: function(json) {
var items = [];
if (json && json.listvirtualmachinesresponse && json.listvirtualmachinesresponse.virtualmachine) {
items = json.listvirtualmachinesresponse.virtualmachine;
$.each(items, function(idx, vm) {
items[idx].cores = vm.cpunumber;
items[idx].cputotal = (parseFloat(vm.cpunumber) * parseFloat(vm.cpuspeed) / 1000.0).toFixed(1) + ' Ghz';
items[idx].cpuusedavg = vm.cpuused;
items[idx].cpuallocated = vm.cpuallocated;
items[idx].memallocated = (parseFloat(vm.memory)/1024.0).toFixed(2) + ' GB';
items[idx].networkread = (parseFloat(vm.networkkbsread)/(1024.0)).toFixed(2) + ' MB';
items[idx].networkwrite = (parseFloat(vm.networkkbswrite)/(1024.0)).toFixed(2) + ' MB';
items[idx].diskread = (parseFloat(vm.diskkbsread)/(1024.0)).toFixed(2) + ' MB';
items[idx].diskwrite = (parseFloat(vm.diskkbswrite)/(1024.0)).toFixed(2) + ' MB';
items[idx].diskiopstotal = parseFloat(vm.diskioread) + parseFloat(vm.diskiowrite);
if (vm.nic && vm.nic.length > 0 && vm.nic[0].ipaddress) {
items[idx].ipaddress = vm.nic[0].ipaddress;
}
var keys = [{'cpuused': 'cpuusedavg'},
{'networkkbsread': 'networkread'},
{'networkkbswrite': 'networkwrite'},
{'diskkbsread': 'diskread'},
{'diskkbswrite': 'diskwrite'},
{'diskioread': 'diskiopstotal'}];
for (keyIdx in keys) {
var map = keys[keyIdx];
var key = Object.keys(map)[0];
var uiKey = map[key];
if (!vm.hasOwnProperty(key)) {
items[idx][uiKey] = '';
}
}
});
}
args.response.success({
data: items
data: json.listvirtualmachinesmetricsresponse.virtualmachine
});
}
});
@ -974,22 +567,22 @@
'Expunging': 'off',
'Migrating': 'warning',
'UploadOp': 'transition',
'Snapshotting': 'warning'
'Snapshotting': 'warning',
},
compact: true
},
vmname: {
label: 'label.metrics.vm.name'
},
disksize: {
sizegb: {
label: 'label.metrics.disk.size'
},
storagetype: {
label: 'label.metrics.disk.storagetype'
},
storagepool: {
storage: {
label: 'label.metrics.storagepool'
}
},
},
dataProvider: function(args) {
var data = {listAll: true};
@ -1008,25 +601,11 @@
}
$.ajax({
url: createURL('listVolumes'),
url: createURL('listVolumesMetrics'),
data: data,
success: function(json) {
var items = [];
if (json && json.listvolumesresponse && json.listvolumesresponse.volume) {
items = json.listvolumesresponse.volume;
$.each(items, function(idx, volume) {
items[idx].name = volume.name;
items[idx].state = volume.state;
items[idx].vmname = volume.vmname;
items[idx].disksize = parseFloat(volume.size)/(1024.0*1024.0*1024.0) + ' GB';
items[idx].storagetype = volume.storagetype.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}) + ' (' + volume.type + ')';
if (volume.storage) {
items[idx].storagepool = volume.storage;
}
});
}
args.response.success({
data: items
data: json.listvolumesmetricsresponse.volume
});
}
});
@ -1062,7 +641,7 @@
'ErrorInMaintenance': 'off',
'PrepareForMaintenance': 'transition',
'CancelMaintenance': 'warning',
'Maintenance': 'warning'
'Maintenance': 'warning',
},
compact: true
},
@ -1078,26 +657,26 @@
label: 'label.metrics.disk',
collapsible: true,
columns: {
disksizeused: {
disksizeusedgb: {
label: 'label.metrics.disk.used',
thresholdcolor: true,
thresholds: {
notification: 'storagenotificationthreshold',
disable: 'storagedisablethreshold'
notification: 'storageusagethreshold',
disable: 'storageusagedisablethreshold'
}
},
disksizetotal: {
disksizetotalgb: {
label: 'label.metrics.disk.total'
},
disksizeallocated: {
disksizeallocatedgb: {
label: 'label.metrics.disk.allocated',
thresholdcolor: true,
thresholds: {
notification: 'storageallocatednotificationthreshold',
notification: 'storageallocatedthreshold',
disable: 'storageallocateddisablethreshold'
}
},
disksizeunallocated: {
disksizeunallocatedgb: {
label: 'label.metrics.disk.unallocated'
}
}
@ -1124,74 +703,11 @@
}
$.ajax({
url: createURL('listStoragePools'),
url: createURL('listStoragePoolsMetrics'),
data: data,
success: function(json) {
var items = [];
if (json && json.liststoragepoolsresponse && json.liststoragepoolsresponse.storagepool) {
items = json.liststoragepoolsresponse.storagepool;
$.each(items, function(idx, pool) {
items[idx].name = pool.name;
items[idx].state = pool.state;
items[idx].scope = pool.scope;
items[idx].type = pool.type;
items[idx].overprovisionfactor = parseFloat(pool.overprovisionfactor);
if (pool.disksizeused) {
items[idx].disksizeused = (parseFloat(pool.disksizeused)/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB';
} else {
items[idx].disksizeused = '';
}
items[idx].disksizetotal = parseFloat(pool.disksizetotal);
items[idx].disksizeallocated = parseFloat(pool.disksizeallocated);
items[idx].disksizeunallocated = (items[idx].overprovisionfactor * items[idx].disksizetotal) - items[idx].disksizeallocated;
// Format presentation
items[idx].disksizetotal = (items[idx].disksizetotal/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB (x' + items[idx].overprovisionfactor + ')';
items[idx].disksizeallocated = (items[idx].disksizeallocated/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB';
items[idx].disksizeunallocated = (items[idx].disksizeunallocated/(1024.0*1024.0*1024.0)).toFixed(2) + ' GB';
// Threshold color coding
items[idx].storagenotificationthreshold = 0.75 * parseFloat(items[idx].disksizetotal);
items[idx].storagedisablethreshold = 0.95 * parseFloat(items[idx].disksizetotal);
items[idx].storageallocatednotificationthreshold = 0.75 * parseFloat(items[idx].disksizetotal) * items[idx].overprovisionfactor;
items[idx].storageallocateddisablethreshold = 0.95 * parseFloat(items[idx].disksizetotal) * items[idx].overprovisionfactor;
var getThresholds = function(data, items, idx) {
data.listAll = true;
$.ajax({
url: createURL('listConfigurations'),
data: data,
success: function(json) {
if (json.listconfigurationsresponse && json.listconfigurationsresponse.configuration) {
$.each(json.listconfigurationsresponse.configuration, function(i, config) {
switch (config.name) {
case 'cluster.storage.allocated.capacity.notificationthreshold':
items[idx].storageallocatednotificationthreshold = parseFloat(config.value) * items[idx].overprovisionfactor * parseFloat(items[idx].disksizetotal);
break;
case 'cluster.storage.capacity.notificationthreshold':
items[idx].storagenotificationthreshold = parseFloat(config.value) * parseFloat(items[idx].disksizetotal);
break;
case 'pool.storage.allocated.capacity.disablethreshold':
items[idx].storageallocateddisablethreshold = parseFloat(config.value) * items[idx].overprovisionfactor * parseFloat(items[idx].disksizetotal);
break;
case 'pool.storage.capacity.disablethreshold':
items[idx].storagedisablethreshold = parseFloat(config.value) * parseFloat(items[idx].disksizetotal);
break;
}
});
}
},
async: false
});
};
// Update global and cluster level thresholds
getThresholds({}, items, idx);
getThresholds({clusterid: pool.clusterid}, items, idx);
});
}
args.response.success({
data: items
data: json.liststoragepoolsmetricsresponse.storagepool
});
}
});

View File

@ -225,322 +225,25 @@
// System dashboard
dashboard: {
dataProvider: function (args) {
var dataFns = {
zoneCount: function (data) {
$.ajax({
url: createURL('listZones'),
data: {
listAll: true,
page: 1,
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
},
success: function (json) {
args.response.success({
data: {
zoneCount: json.listzonesresponse.count ? json.listzonesresponse.count: 0,
zones: json.listzonesresponse.zone
}
});
}
$.ajax({
url: createURL('listInfrastructure'),
success: function (json) {
var response = json.listinfrastructureresponse.infrastructure;
var data = {};
data.zoneCount = response.zones;
data.podCount = response.pods;
data.clusterCount = response.clusters;
data.hostCount = response.hosts;
data.primaryStorageCount = response.storagepools;
data.secondaryStorageCount = response.imagestores;
data.systemVmCount = response.systemvms;
data.virtualRouterCount = response.routers;
data.socketCount = response.cpusockets;
args.response.success({
data: data
});
dataFns.podCount();
},
podCount: function (data) {
$.ajax({
url: createURL('listPods'),
data: {
listAll: true,
page: 1,
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
},
success: function (json) {
args.response.success({
data: {
podCount: json.listpodsresponse.count ? json.listpodsresponse.count: 0
}
});
}
});
dataFns.clusterCount();
},
clusterCount: function (data) {
$.ajax({
url: createURL('listClusters'),
data: {
listAll: true,
page: 1,
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
},
success: function (json) {
args.response.success({
data: {
clusterCount: json.listclustersresponse.count ? json.listclustersresponse.count: 0
}
});
}
});
dataFns.hostCount();
},
hostCount: function (data) {
var data2 = {
type: 'routing',
listAll: true,
page: 1,
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
};
$.ajax({
url: createURL('listHosts'),
data: data2,
success: function (json) {
args.response.success({
data: {
hostCount: json.listhostsresponse.count ? json.listhostsresponse.count: 0
}
});
}
});
dataFns.primaryStorageCount();
},
primaryStorageCount: function (data) {
var data2 = {
listAll: true,
page: 1,
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
};
$.ajax({
url: createURL('listStoragePools'),
data: data2,
success: function (json) {
args.response.success({
data: {
primaryStorageCount: json.liststoragepoolsresponse.count ? json.liststoragepoolsresponse.count: 0
}
});
}
});
dataFns.secondaryStorageCount();
},
secondaryStorageCount: function (data) {
var data2 = {
type: 'SecondaryStorage',
listAll: true,
page: 1,
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
};
$.ajax({
url: createURL('listImageStores'),
data: data2,
success: function (json) {
args.response.success({
data: {
secondaryStorageCount: json.listimagestoresresponse.imagestore ? json.listimagestoresresponse.count: 0
}
});
}
});
dataFns.systemVmCount();
},
systemVmCount: function (data) {
$.ajax({
url: createURL('listSystemVms'),
data: {
listAll: true,
page: 1,
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
},
success: function (json) {
args.response.success({
data: {
systemVmCount: json.listsystemvmsresponse.count ? json.listsystemvmsresponse.count: 0
}
});
}
});
dataFns.virtualRouterCount();
},
virtualRouterCount: function (data) {
var data2 = {
listAll: true,
page: 1,
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
};
$.ajax({
url: createURL('listRouters'),
data: data2,
success: function (json) {
var total1 = json.listroutersresponse.count ? json.listroutersresponse.count: 0;
var total2 = 0; //reset
/*
* In project view, the first listRotuers API(without projectid=-1) will return the same objects as the second listRouters API(with projectid=-1),
* because in project view, all API calls are appended with projectid=[projectID].
* Therefore, we only call the second listRouters API(with projectid=-1) in non-project view.
*/
if (cloudStack.context && cloudStack.context.projects == null) { //non-project view
var data3 = {
listAll: true,
projectid: -1,
page: 1,
pagesize: 1 //specifying pagesize as 1 because we don't need any embedded objects to be returned here. The only thing we need from API response is "count" property.
};
$.ajax({
url: createURL('listRouters'),
data: data3,
async: false,
success: function (json) {
total2 = json.listroutersresponse.count ? json.listroutersresponse.count : 0;
}
});
}
args.response.success({
data: {
virtualRouterCount: (total1 + total2)
}
});
}
});
dataFns.capacity();
},
capacity: function (data) {
$.ajax({
url: createURL('listCapacity'),
success: function (json) {
var capacities = json.listcapacityresponse.capacity;
if(capacities) {
var capacityTotal = function (id, converter) {
var capacity = $.grep(capacities, function (capacity) {
return capacity.type == id;
})[0];
var total = capacity ? capacity.capacitytotal: 0;
if (converter) {
return converter(total);
}
return total;
};
args.response.success({
data: {
cpuCapacityTotal: capacityTotal(1, cloudStack.converters.convertHz),
memCapacityTotal: capacityTotal(0, cloudStack.converters.convertBytes),
storageCapacityTotal: capacityTotal(2, cloudStack.converters.convertBytes)
}
});
} else {
args.response.success({
data: {
cpuCapacityTotal: cloudStack.converters.convertHz(0),
memCapacityTotal: cloudStack.converters.convertBytes(0),
storageCapacityTotal: cloudStack.converters.convertBytes(0)
}
});
}
}
});
dataFns.socketInfo();
},
socketInfo: function (data) {
var socketCount = 0;
function listHostFunction(hypervisor, pageSizeValue) {
var deferred = $.Deferred();
var totalHostCount = 0;
var returnedHostCount = 0;
var returnedHostCpusocketsSum = 0;
var callListHostsWithPage = function(page) {
$.ajax({
url: createURL('listHosts'),
data: {
type: 'routing',
hypervisor: hypervisor,
page: page,
details: 'min',
pagesize: pageSizeValue
},
success: function (json) {
if (json.listhostsresponse.count == undefined) {
deferred.resolve();
return;
}
totalHostCount = json.listhostsresponse.count;
returnedHostCount += json.listhostsresponse.host.length;
var items = json.listhostsresponse.host;
for (var i = 0; i < items.length; i++) {
if (items[i].cpusockets != undefined && isNaN(items[i].cpusockets) == false) {
returnedHostCpusocketsSum += items[i].cpusockets;
}
}
if (returnedHostCount < totalHostCount) {
callListHostsWithPage(++page);
} else {
socketCount += returnedHostCpusocketsSum;
deferred.resolve();
}
}
});
}
callListHostsWithPage(1);
return deferred;
}
$.ajax({
url: createURL('listConfigurations'),
data: {
name : 'default.page.size'
},
success: function (json) {
pageSizeValue = json.listconfigurationsresponse.configuration[0].value;
if(!pageSizeValue) {
return;
}
$.ajax({
url: createURL('listHypervisors'),
success: function (json) {
var deferredArray = [];
$(json.listhypervisorsresponse.hypervisor).map(function (index, hypervisor) {
deferredArray.push(listHostFunction(hypervisor.name, pageSizeValue));
});
$.when.apply(null, deferredArray).then(function(){
args.response.success({
data: {
socketCount: socketCount
}
});
});
}
});
}
});
}
};
dataFns.zoneCount();
});
}
},

View File

@ -1245,12 +1245,11 @@
if (field.thresholdcolor && field.thresholds) {
if ((field.thresholds.disable in dataItem) && (field.thresholds.notification in dataItem)) {
var disableThreshold = parseFloat(dataItem[field.thresholds.disable]);
var notificationThreshold = parseFloat(dataItem[field.thresholds.notification]);
var value = parseFloat(content);
if (value >= disableThreshold) {
var disableThreshold = dataItem[field.thresholds.disable];
var notificationThreshold = dataItem[field.thresholds.notification];
if (disableThreshold) {
$td.addClass('alert-disable-threshold');
} else if (value >= notificationThreshold) {
} else if (notificationThreshold) {
$td.addClass('alert-notification-threshold');
}
}