From a00cb07ee01527b23c8e34c21baf227bf84bf667 Mon Sep 17 00:00:00 2001 From: Rohit Yadav Date: Mon, 16 Jan 2017 18:33:38 +0530 Subject: [PATCH] APPLE-328: Metrics View APIs Signed-off-by: Rohit Yadav --- .../admin/cluster/ListClustersCmd.java | 12 +- .../api/command/admin/host/ListHostsCmd.java | 20 +- .../cloudstack/api/response/HostResponse.java | 159 +++++ .../cloudstack/api/response/NicResponse.java | 3 + .../api/response/StoragePoolResponse.java | 8 + .../api/response/UserVmResponse.java | 24 + .../api/response/VolumeResponse.java | 140 ++++ .../cloudstack/api/response/ZoneResponse.java | 88 +++ client/pom.xml | 5 + .../src/com/cloud/dc/dao/ClusterDao.java | 2 +- .../src/com/cloud/dc/dao/ClusterDaoImpl.java | 6 +- .../src/com/cloud/dc/dao/HostPodDao.java | 2 +- .../src/com/cloud/dc/dao/HostPodDaoImpl.java | 6 +- .../src/com/cloud/host/dao/HostDaoImpl.java | 2 - plugins/metrics/pom.xml | 55 ++ .../cloudstack/metrics/module.properties | 18 + .../metrics/spring-metrics-context.xml | 27 + .../api/ListClustersMetricsCmd.java | 51 ++ .../cloudstack/api/ListHostsMetricsCmd.java | 54 ++ .../cloudstack/api/ListInfrastructureCmd.java | 52 ++ .../api/ListStoragePoolsMetricsCmd.java | 52 ++ .../cloudstack/api/ListVMsMetricsCmd.java | 51 ++ .../cloudstack/api/ListVolumesMetricsCmd.java | 51 ++ .../cloudstack/api/ListZonesMetricsCmd.java | 52 ++ .../cloudstack/metrics/MetricsService.java | 46 ++ .../metrics/MetricsServiceImpl.java | 563 ++++++++++++++++ .../response/ClusterMetricsResponse.java | 211 ++++++ .../response/HostMetricsResponse.java | 204 ++++++ .../response/InfrastructureResponse.java | 101 +++ .../response/StoragePoolMetricsResponse.java | 105 +++ .../response/VmMetricsResponse.java | 108 +++ .../response/VolumeMetricsResponse.java | 41 ++ .../response/ZoneMetricsResponse.java | 206 ++++++ plugins/pom.xml | 1 + .../com/cloud/api/query/dao/HostJoinDao.java | 2 + .../cloud/api/query/dao/HostJoinDaoImpl.java | 15 + test/integration/smoke/test_metrics_api.py | 219 +++++++ tools/apidoc/gen_toc.py | 4 +- ui/scripts/metrics.js | 614 ++---------------- ui/scripts/system.js | 280 +------- ui/scripts/ui/widgets/listView.js | 9 +- 41 files changed, 2831 insertions(+), 838 deletions(-) create mode 100644 plugins/metrics/pom.xml create mode 100644 plugins/metrics/resources/META-INF/cloudstack/metrics/module.properties create mode 100644 plugins/metrics/resources/META-INF/cloudstack/metrics/spring-metrics-context.xml create mode 100644 plugins/metrics/src/org/apache/cloudstack/api/ListClustersMetricsCmd.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/api/ListHostsMetricsCmd.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/api/ListInfrastructureCmd.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/api/ListStoragePoolsMetricsCmd.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/api/ListVMsMetricsCmd.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/api/ListVolumesMetricsCmd.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/api/ListZonesMetricsCmd.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/metrics/MetricsService.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/response/ClusterMetricsResponse.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/response/InfrastructureResponse.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/response/StoragePoolMetricsResponse.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/response/VmMetricsResponse.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/response/VolumeMetricsResponse.java create mode 100644 plugins/metrics/src/org/apache/cloudstack/response/ZoneMetricsResponse.java create mode 100644 test/integration/smoke/test_metrics_api.py diff --git a/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java b/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java index 432ca921c4d..74ad764608c 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/cluster/ListClustersCmd.java @@ -125,18 +125,22 @@ public class ListClustersCmd extends BaseListCmd { return s_name; } - @Override - public void execute() { + protected List getClusterResponses() { Pair, Integer> result = _mgr.searchForClusters(this); - ListResponse response = new ListResponse(); List clusterResponses = new ArrayList(); 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 clusterResponses = getClusterResponses(); + ListResponse response = new ListResponse(); + response.setResponses(clusterResponses, clusterResponses.size()); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java index 424fc05aed1..3391fdca1e3 100644 --- a/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java +++ b/api/src/org/apache/cloudstack/api/command/admin/host/ListHostsCmd.java @@ -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 response = null; + protected ListResponse getHostResponses() { + ListResponse response = new ListResponse<>(); if (getVirtualMachineId() == null) { response = _queryService.searchForServers(this); } else { Pair, Integer> result; Ternary, Integer>, List, Map> hostsForMigration = - _mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal()); + _mgr.listHostsForMigrationOfVM(getVirtualMachineId(), this.getStartIndex(), this.getPageSizeVal()); result = hostsForMigration.first(); List hostsWithCapacity = hostsForMigration.second(); - - response = new ListResponse(); List hostResponses = new ArrayList(); 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 response = getHostResponses(); response.setResponseName(getCommandName()); this.setResponseObject(response); } diff --git a/api/src/org/apache/cloudstack/api/response/HostResponse.java b/api/src/org/apache/cloudstack/api/response/HostResponse.java index 5923ca4144f..b5f81e6b8f6 100644 --- a/api/src/org/apache/cloudstack/api/response/HostResponse.java +++ b/api/src/org/apache/cloudstack/api/response/HostResponse.java @@ -471,4 +471,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 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; + } } diff --git a/api/src/org/apache/cloudstack/api/response/NicResponse.java b/api/src/org/apache/cloudstack/api/response/NicResponse.java index 2f79d7ff477..64998ba1d86 100644 --- a/api/src/org/apache/cloudstack/api/response/NicResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NicResponse.java @@ -205,4 +205,7 @@ public class NicResponse extends BaseResponse { this.secondaryIps = ipList; } + public String getIpaddress() { + return ipaddress; + } } diff --git a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java index 3571866fe74..b7f7d0b41ee 100644 --- a/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java +++ b/api/src/org/apache/cloudstack/api/response/StoragePoolResponse.java @@ -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; + } } diff --git a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java index 1f55f5bb31a..4a571da6a91 100644 --- a/api/src/org/apache/cloudstack/api/response/UserVmResponse.java +++ b/api/src/org/apache/cloudstack/api/response/UserVmResponse.java @@ -765,4 +765,28 @@ public class UserVmResponse extends BaseResponse implements ControlledEntityResp public void setOsTypeId(Long osTypeId) { this.osTypeId = osTypeId; } + + public Set getTagIds() { + return tagIds; + } + + public void setTagIds(Set 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; + } } diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java index eeb4af9c9e0..85ad7e332a0 100644 --- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java +++ b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java @@ -522,4 +522,144 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity public void setTemplateDisplayText(String templateDisplayText) { this.templateDisplayText = templateDisplayText; } + + public String getStorageType() { + return storageType; + } + + public String getVolumeType() { + return volumeType; + } + + public String getName() { + return name; + } + + public String getZoneId() { + return zoneId; + } + + public String getZoneName() { + return zoneName; + } + + 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 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 Set getTags() { + return tags; + } + + public Boolean getDisplayVolume() { + return displayVolume; + } } diff --git a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java b/api/src/org/apache/cloudstack/api/response/ZoneResponse.java index 4266077e813..61bab02d321 100644 --- a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java +++ b/api/src/org/apache/cloudstack/api/response/ZoneResponse.java @@ -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 getCapacitites() { + return capacitites; + } + + public boolean isLocalStorageEnabled() { + return localStorageEnabled; + } + + public Set getTags() { + return tags; + } + + public Map getResourceDetails() { + return resourceDetails; + } } diff --git a/client/pom.xml b/client/pom.xml index 44d2c217094..a0cd54d2072 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -100,6 +100,11 @@ cloud-plugin-user-authenticator-sha256salted ${project.version} + + org.apache.cloudstack + cloud-plugin-metrics + ${project.version} + org.apache.cloudstack cloud-plugin-network-nvp diff --git a/engine/schema/src/com/cloud/dc/dao/ClusterDao.java b/engine/schema/src/com/cloud/dc/dao/ClusterDao.java index 50c234c9154..75d216f099b 100644 --- a/engine/schema/src/com/cloud/dc/dao/ClusterDao.java +++ b/engine/schema/src/com/cloud/dc/dao/ClusterDao.java @@ -44,5 +44,5 @@ public interface ClusterDao extends GenericDao { List listClustersByDcId(long zoneId); - List listAllCusters(long zoneId); + List listAllCusters(Long zoneId); } diff --git a/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java index c0f86f33b21..7a48482f9c0 100644 --- a/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/ClusterDaoImpl.java @@ -257,9 +257,11 @@ public class ClusterDaoImpl extends GenericDaoBase implements C } @Override - public List listAllCusters(long zoneId) { + public List listAllCusters(Long zoneId) { SearchCriteria sc = ClusterIdSearch.create(); - sc.setParameters("dataCenterId", zoneId); + if (zoneId != null) { + sc.setParameters("dataCenterId", zoneId); + } return customSearch(sc, null); } } diff --git a/engine/schema/src/com/cloud/dc/dao/HostPodDao.java b/engine/schema/src/com/cloud/dc/dao/HostPodDao.java index 39c8a499192..1a000d8830c 100644 --- a/engine/schema/src/com/cloud/dc/dao/HostPodDao.java +++ b/engine/schema/src/com/cloud/dc/dao/HostPodDao.java @@ -31,5 +31,5 @@ public interface HostPodDao extends GenericDao { public List listDisabledPods(long zoneId); - public List listAllPods(long zoneId); + public List listAllPods(Long zoneId); } diff --git a/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java index 1137eb80ca6..3dfd8512876 100644 --- a/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/HostPodDaoImpl.java @@ -132,9 +132,11 @@ public class HostPodDaoImpl extends GenericDaoBase implements H } @Override - public List listAllPods(long zoneId) { + public List listAllPods(Long zoneId) { SearchCriteria sc = PodIdSearch.create(); - sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); + if (zoneId != null) { + sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId); + } return customSearch(sc, null); } } diff --git a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java index 046981440f0..c04183a7725 100755 --- a/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java +++ b/engine/schema/src/com/cloud/host/dao/HostDaoImpl.java @@ -1111,8 +1111,6 @@ public class HostDaoImpl extends GenericDaoBase implements HostDao public List listAllHostsByType(Host.Type type) { SearchCriteria sc = TypeSearch.create(); sc.setParameters("type", type); - sc.setParameters("resourceState", ResourceState.Enabled); - return listBy(sc); } } diff --git a/plugins/metrics/pom.xml b/plugins/metrics/pom.xml new file mode 100644 index 00000000000..3c57f8ed067 --- /dev/null +++ b/plugins/metrics/pom.xml @@ -0,0 +1,55 @@ + + + 4.0.0 + cloud-plugin-metrics + Apache CloudStack Plugin - Metrics + + org.apache.cloudstack + cloudstack-plugins + 4.5.3-SNAPSHOT + ../pom.xml + + + + org.apache.cloudstack + cloud-api + ${project.version} + + + org.apache.cloudstack + cloud-utils + ${project.version} + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + -Xmx1024m + + + + + diff --git a/plugins/metrics/resources/META-INF/cloudstack/metrics/module.properties b/plugins/metrics/resources/META-INF/cloudstack/metrics/module.properties new file mode 100644 index 00000000000..149b83afde1 --- /dev/null +++ b/plugins/metrics/resources/META-INF/cloudstack/metrics/module.properties @@ -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 diff --git a/plugins/metrics/resources/META-INF/cloudstack/metrics/spring-metrics-context.xml b/plugins/metrics/resources/META-INF/cloudstack/metrics/spring-metrics-context.xml new file mode 100644 index 00000000000..65846417e11 --- /dev/null +++ b/plugins/metrics/resources/META-INF/cloudstack/metrics/spring-metrics-context.xml @@ -0,0 +1,27 @@ + + + + + + diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListClustersMetricsCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListClustersMetricsCmd.java new file mode 100644 index 00000000000..abf57fb2f3f --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/api/ListClustersMetricsCmd.java @@ -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.2", 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 metricsResponses = metricsService.listClusterMetrics(getClusterResponses()); + ListResponse response = new ListResponse<>(); + response.setResponses(metricsResponses, metricsResponses.size()); + response.setResponseName(getCommandName()); + setResponseObject(response); + } +} \ No newline at end of file diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListHostsMetricsCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListHostsMetricsCmd.java new file mode 100644 index 00000000000..e479966b851 --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/api/ListHostsMetricsCmd.java @@ -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.2", 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 metricsResponses = metricsService.listHostMetrics(getHostResponses().getResponses()); + ListResponse response = new ListResponse<>(); + response.setResponses(metricsResponses, metricsResponses.size()); + response.setResponseName(getCommandName()); + setResponseObject(response); + } +} diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListInfrastructureCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListInfrastructureCmd.java new file mode 100644 index 00000000000..c45c239f4f3 --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/api/ListInfrastructureCmd.java @@ -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.2", 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); + } +} diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListStoragePoolsMetricsCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListStoragePoolsMetricsCmd.java new file mode 100644 index 00000000000..767509b268e --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/api/ListStoragePoolsMetricsCmd.java @@ -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.2", 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 metricsResponses = metricsService.listStoragePoolMetrics(_queryService.searchForStoragePools(this).getResponses()); + ListResponse response = new ListResponse<>(); + response.setResponses(metricsResponses, metricsResponses.size()); + response.setResponseName(getCommandName()); + setResponseObject(response); + } + +} diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListVMsMetricsCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListVMsMetricsCmd.java new file mode 100644 index 00000000000..df62e0e84ec --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/api/ListVMsMetricsCmd.java @@ -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.2", 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 metricsResponses = metricsService.listVmMetrics(_queryService.searchForUserVMs(this).getResponses()); + ListResponse response = new ListResponse<>(); + response.setResponses(metricsResponses, metricsResponses.size()); + response.setResponseName(getCommandName()); + setResponseObject(response); + } +} diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListVolumesMetricsCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListVolumesMetricsCmd.java new file mode 100644 index 00000000000..fce078417c5 --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/api/ListVolumesMetricsCmd.java @@ -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.2", 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 metricsResponses = metricsService.listVolumeMetrics(_queryService.searchForVolumes(this).getResponses()); + ListResponse response = new ListResponse<>(); + response.setResponses(metricsResponses, metricsResponses.size()); + response.setResponseName(getCommandName()); + setResponseObject(response); + } +} diff --git a/plugins/metrics/src/org/apache/cloudstack/api/ListZonesMetricsCmd.java b/plugins/metrics/src/org/apache/cloudstack/api/ListZonesMetricsCmd.java new file mode 100644 index 00000000000..296763d8597 --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/api/ListZonesMetricsCmd.java @@ -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.2", 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 metricsResponses = metricsService.listZoneMetrics(_queryService.listDataCenters(this).getResponses()); + ListResponse response = new ListResponse<>(); + response.setResponses(metricsResponses, metricsResponses.size()); + response.setResponseName(getCommandName()); + setResponseObject(response); + } + +} diff --git a/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsService.java b/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsService.java new file mode 100644 index 00000000000..deb1da89c9f --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsService.java @@ -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 listVolumeMetrics(List volumeResponses); + List listVmMetrics(List vmResponses); + List listStoragePoolMetrics(List poolResponses); + List listHostMetrics(List poolResponses); + List listClusterMetrics(List poolResponses); + List listZoneMetrics(List poolResponses); +} diff --git a/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java b/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java new file mode 100644 index 00000000000..3091c7d89c1 --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/metrics/MetricsServiceImpl.java @@ -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.listAllCusters(null).size()); + response.setHosts(hostDao.listAllHostsByType(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.listAllHostsByType(Host.Type.Routing)) { + if (host.getCpuSockets() != null) { + cpuSockets += host.getCpuSockets(); + } + } + response.setCpuSockets(cpuSockets); + return response; + } + + @Override + public List listVolumeMetrics(List volumeResponses) { + final List 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 listVmMetrics(List vmResponses) { + final List 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 listStoragePoolMetrics(List poolResponses) { + final List 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 listHostMetrics(List hostResponses) { + final List 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 capacities = capacityDao.findCapacityBy(capacityType, zoneId, null, clusterId); + if (capacities == null || capacities.size() < 1) { + return null; + } + return capacities.get(0); + } + + @Override + public List listClusterMetrics(List clusterResponses) { + final List 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 listZoneMetrics(List zoneResponses) { + final List 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> getCommands() { + List> cmdList = new ArrayList>(); + 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; + } + } + +} diff --git a/plugins/metrics/src/org/apache/cloudstack/response/ClusterMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/ClusterMetricsResponse.java new file mode 100644 index 00000000000..dde1ab76327 --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/response/ClusterMetricsResponse.java @@ -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; + } + } +} diff --git a/plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java new file mode 100644 index 00000000000..cdc9d16d845 --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/response/HostMetricsResponse.java @@ -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); + } + } + +} diff --git a/plugins/metrics/src/org/apache/cloudstack/response/InfrastructureResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/InfrastructureResponse.java new file mode 100644 index 00000000000..a4db345d21d --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/response/InfrastructureResponse.java @@ -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; + } +} diff --git a/plugins/metrics/src/org/apache/cloudstack/response/StoragePoolMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/StoragePoolMetricsResponse.java new file mode 100644 index 00000000000..f20f797aa3e --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/response/StoragePoolMetricsResponse.java @@ -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); + } + } +} diff --git a/plugins/metrics/src/org/apache/cloudstack/response/VmMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/VmMetricsResponse.java new file mode 100644 index 00000000000..a4057aeb059 --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/response/VmMetricsResponse.java @@ -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 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; + } + } +} diff --git a/plugins/metrics/src/org/apache/cloudstack/response/VolumeMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/VolumeMetricsResponse.java new file mode 100644 index 00000000000..ef8515f1396 --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/response/VolumeMetricsResponse.java @@ -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)); + } + } +} diff --git a/plugins/metrics/src/org/apache/cloudstack/response/ZoneMetricsResponse.java b/plugins/metrics/src/org/apache/cloudstack/response/ZoneMetricsResponse.java new file mode 100644 index 00000000000..71560178564 --- /dev/null +++ b/plugins/metrics/src/org/apache/cloudstack/response/ZoneMetricsResponse.java @@ -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; + } + } +} diff --git a/plugins/pom.xml b/plugins/pom.xml index c60cc14d114..030b4accaef 100755 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -58,6 +58,7 @@ hypervisors/baremetal hypervisors/ucs hypervisors/hyperv + metrics network-elements/elastic-loadbalancer network-elements/ovs network-elements/juniper-contrail diff --git a/server/src/com/cloud/api/query/dao/HostJoinDao.java b/server/src/com/cloud/api/query/dao/HostJoinDao.java index f0ac1831d45..e7dc5d5ff04 100644 --- a/server/src/com/cloud/api/query/dao/HostJoinDao.java +++ b/server/src/com/cloud/api/query/dao/HostJoinDao.java @@ -41,4 +41,6 @@ public interface HostJoinDao extends GenericDao { List searchByIds(Long... ids); + List findByClusterId(Long clusterId, Host.Type type); + } diff --git a/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java index d5542566c63..acecc92a918 100644 --- a/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java +++ b/server/src/com/cloud/api/query/dao/HostJoinDaoImpl.java @@ -71,6 +71,8 @@ public class HostJoinDaoImpl extends GenericDaoBase implements private final SearchBuilder hostIdSearch; + private final SearchBuilder ClusterSearch; + protected HostJoinDaoImpl() { hostSearch = createSearchBuilder(); @@ -81,6 +83,11 @@ public class HostJoinDaoImpl extends GenericDaoBase 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 "; } @@ -439,4 +446,12 @@ public class HostJoinDaoImpl extends GenericDaoBase implements return uvList; } + @Override + public List findByClusterId(Long clusterId, Host.Type type) { + SearchCriteria sc = ClusterSearch.create(); + sc.setParameters("clusterId", clusterId); + sc.setParameters("type", type); + return listBy(sc); + } + } diff --git a/test/integration/smoke/test_metrics_api.py b/test/integration/smoke/test_metrics_api.py new file mode 100644 index 00000000000..48890b97494 --- /dev/null +++ b/test/integration/smoke/test_metrics_api.py @@ -0,0 +1,219 @@ +# 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. +""" BVT tests for Hosts and Clusters +""" +#Import Local Modules +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 System modules +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.assertEqual(li.routers, len(self.apiclient.listRouters(listRouters.listRoutersCmd()))) + + 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')) + + + + + diff --git a/tools/apidoc/gen_toc.py b/tools/apidoc/gen_toc.py index c617e5f729a..433ef96be9e 100644 --- a/tools/apidoc/gen_toc.py +++ b/tools/apidoc/gen_toc.py @@ -165,7 +165,9 @@ known_categories = { 'CacheStore' : 'Cache Store', 'IAM' : 'IAM', 'OvsElement' : 'Ovs Element', - 'StratosphereSsp' : ' Stratosphere SSP' + 'StratosphereSsp' : ' Stratosphere SSP', + 'Metrics' : 'Metrics', + 'Infrastructure' : 'Metrics', } diff --git a/ui/scripts/metrics.js b/ui/scripts/metrics.js index f90f5faa7ce..5b013afff1b 100644 --- a/ui/scripts/metrics.js +++ b/ui/scripts/metrics.js @@ -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}, - 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'}, - 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'}, - 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: { + 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,7 +465,7 @@ label: 'label.metrics.cpu.usage', collapsible: true, columns: { - cores: { + cpunumber: { label: 'label.metrics.num.cpu.cores', }, cputotal: { @@ -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 }); } }); @@ -981,13 +574,13 @@ 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' }, }, @@ -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 }); } }); @@ -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 }); } }); diff --git a/ui/scripts/system.js b/ui/scripts/system.js index 6f1f82f1a24..1d9d7bf8136 100644 --- a/ui/scripts/system.js +++ b/ui/scripts/system.js @@ -216,272 +216,24 @@ // System dashboard dashboard: { dataProvider: function (args) { - var dataFns = { - zoneCount: function (data) { - $.ajax({ - url: createURL('listZones'), - data: { - 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) { - dataFns.podCount($.extend(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 }); - }, - - podCount: function (data) { - $.ajax({ - url: createURL('listPods'), - data: { - 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) { - dataFns.clusterCount($.extend(data, { - podCount: json.listpodsresponse.count ? json.listpodsresponse.count: 0 - })); - } - }); - }, - - clusterCount: function (data) { - $.ajax({ - url: createURL('listClusters'), - data: { - 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) { - dataFns.hostCount($.extend(data, { - clusterCount: json.listclustersresponse.count ? json.listclustersresponse.count: 0 - })); - - //comment the 4 lines above and uncomment the following 4 lines if listHosts API still responds slowly. - - /* - dataFns.primaryStorageCount($.extend(data, { - clusterCount: json.listclustersresponse.count ? - json.listclustersresponse.count : 0 - })); - */ - } - }); - }, - - hostCount: function (data) { - var data2 = { - type: 'routing', - 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) { - dataFns.primaryStorageCount($.extend(data, { - hostCount: json.listhostsresponse.count ? json.listhostsresponse.count: 0 - })); - } - }); - }, - - primaryStorageCount: function (data) { - var data2 = { - 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) { - dataFns.secondaryStorageCount($.extend(data, { - primaryStorageCount: json.liststoragepoolsresponse.count ? json.liststoragepoolsresponse.count: 0 - })); - } - }); - }, - - secondaryStorageCount: function (data) { - var data2 = { - 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) { - dataFns.systemVmCount($.extend(data, { - secondaryStorageCount: json.listimagestoresresponse.imagestore ? json.listimagestoresresponse.count: 0 - })); - } - }); - }, - - systemVmCount: function (data) { - $.ajax({ - url: createURL('listSystemVms'), - data: { - 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) { - dataFns.virtualRouterCount($.extend(data, { - systemVmCount: json.listsystemvmsresponse.count ? json.listsystemvmsresponse.count: 0 - })); - } - }); - }, - - 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; - } - }); - } - - dataFns.capacity($.extend(data, { - virtualRouterCount: (total1 + total2) - })); - } - }); - }, - - capacity: function (data) { - if (data.zoneCount) { - $.ajax({ - url: createURL('listCapacity'), - success: function (json) { - var capacities = json.listcapacityresponse.capacity; - - 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; - }; - - dataFns.socketInfo($.extend(data, { - cpuCapacityTotal: capacityTotal(1, cloudStack.converters.convertHz), - memCapacityTotal: capacityTotal(0, cloudStack.converters.convertBytes), - storageCapacityTotal: capacityTotal(2, cloudStack.converters.convertBytes) - })); - } - }); - } else { - dataFns.socketInfo($.extend(data, { - cpuCapacityTotal: cloudStack.converters.convertHz(0), - memCapacityTotal: cloudStack.converters.convertBytes(0), - storageCapacityTotal: cloudStack.converters.convertBytes(0) - })); - } - }, - - socketInfo: function (data) { - var socketCount = 0; - $.ajax({ - url: createURL('listHypervisors'), - async: false, - success: function (json) { - args.response.success({ - data: $(json.listhypervisorsresponse.hypervisor).map(function (index, hypervisor) { - var totalHostCount = 0; - var currentPage = 1; - var returnedHostCount = 0; - var returnedHostCpusocketsSum = 0; - - var callListHostsWithPage = function() { - $.ajax({ - url: createURL('listHosts'), - async: false, - data: { - type: 'routing', - hypervisor: hypervisor.name, - page: currentPage, - pagesize: pageSize //global variable - }, - success: function (json) { - if (json.listhostsresponse.count == undefined) { - 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) { - currentPage++; - callListHostsWithPage(); - } - } - }); - } - - callListHostsWithPage(); - - socketCount += returnedHostCpusocketsSum; - }) - }); - } - }); - - complete($.extend(data, { - socketCount: socketCount - })); } - }; - - var complete = function (data) { - args.response.success({ - data: data - }); - }; - - dataFns.zoneCount({ }); } }, diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index 9b83940eaf6..5cdc5ee0d05 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -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'); } }