summaryrefslogtreecommitdiffstats
path: root/src/com.gluster.storage.management.server
diff options
context:
space:
mode:
Diffstat (limited to 'src/com.gluster.storage.management.server')
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java61
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/AbstractStatsFactory.java168
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/CpuStatsFactory.java36
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/MemoryStatsFactory.java36
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/NetworkStatsFactory.java105
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java158
-rw-r--r--src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/StatsFactory.java31
7 files changed, 436 insertions, 159 deletions
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java
index 28cf419d..e3332648 100644
--- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/resources/v1_0/GlusterServersResource.java
@@ -24,6 +24,8 @@ import static com.gluster.storage.management.core.constants.RESTConstants.PATH_P
import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_DISK_NAME;
import static com.gluster.storage.management.core.constants.RESTConstants.PATH_PARAM_SERVER_NAME;
import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_DETAILS;
+import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_INTERFACE;
+import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_PERIOD;
import static com.gluster.storage.management.core.constants.RESTConstants.QUERY_PARAM_TYPE;
import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_DISKS;
import static com.gluster.storage.management.core.constants.RESTConstants.RESOURCE_PATH_CLUSTERS;
@@ -56,6 +58,7 @@ import com.gluster.storage.management.core.constants.CoreConstants;
import com.gluster.storage.management.core.constants.RESTConstants;
import com.gluster.storage.management.core.exceptions.ConnectionException;
import com.gluster.storage.management.core.exceptions.GlusterRuntimeException;
+import com.gluster.storage.management.core.exceptions.GlusterValidationException;
import com.gluster.storage.management.core.model.GlusterServer;
import com.gluster.storage.management.core.model.Server.SERVER_STATUS;
import com.gluster.storage.management.core.model.TaskStatus;
@@ -65,7 +68,11 @@ import com.gluster.storage.management.server.data.ClusterInfo;
import com.gluster.storage.management.server.data.ServerInfo;
import com.gluster.storage.management.server.services.ClusterService;
import com.gluster.storage.management.server.tasks.InitializeDiskTask;
+import com.gluster.storage.management.server.utils.CpuStatsFactory;
+import com.gluster.storage.management.server.utils.MemoryStatsFactory;
+import com.gluster.storage.management.server.utils.NetworkStatsFactory;
import com.gluster.storage.management.server.utils.SshUtil;
+import com.gluster.storage.management.server.utils.StatsFactory;
import com.sun.jersey.api.core.InjectParam;
import com.sun.jersey.spi.resource.Singleton;
@@ -87,7 +94,16 @@ public class GlusterServersResource extends AbstractServersResource {
@Autowired
private SshUtil sshUtil;
+
+ @Autowired
+ private CpuStatsFactory cpuStatsFactory;
+ @Autowired
+ private MemoryStatsFactory memoryStatsFactory;
+
+ @Autowired
+ private NetworkStatsFactory networkStatsFactory;
+
protected void fetchServerDetails(GlusterServer server) {
try {
server.setStatus(SERVER_STATUS.ONLINE);
@@ -471,51 +487,54 @@ public class GlusterServersResource extends AbstractServersResource {
@Produces(MediaType.APPLICATION_XML)
@Path(RESOURCE_STATISTICS)
public Response getAggregatedPerformanceDataXML(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
- @QueryParam(QUERY_PARAM_TYPE) String type) {
- return getAggregaredPerformanceData(clusterName, type, MediaType.APPLICATION_XML);
+ @QueryParam(QUERY_PARAM_TYPE) String type, @QueryParam(QUERY_PARAM_PERIOD) String period) {
+ return getAggregaredPerformanceData(clusterName, type, period, MediaType.APPLICATION_XML);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path(RESOURCE_STATISTICS)
public Response getAggregaredPerformanceDataJSON(@PathParam(PATH_PARAM_CLUSTER_NAME) String clusterName,
- @QueryParam(QUERY_PARAM_TYPE) String type) {
- return getAggregaredPerformanceData(clusterName, type, MediaType.APPLICATION_JSON);
+ @QueryParam(QUERY_PARAM_TYPE) String type, @QueryParam(QUERY_PARAM_PERIOD) String period) {
+ return getAggregaredPerformanceData(clusterName, type, period, MediaType.APPLICATION_JSON);
}
@GET
@Produces(MediaType.APPLICATION_XML)
@Path("{" + PATH_PARAM_SERVER_NAME + "}/" + RESOURCE_STATISTICS)
- public Response getPerformanceDataXML(@PathParam(PATH_PARAM_SERVER_NAME) String serverName, @QueryParam(QUERY_PARAM_TYPE) String type) {
- return getPerformanceData(serverName, type, MediaType.APPLICATION_XML);
+ public Response getPerformanceDataXML(@PathParam(PATH_PARAM_SERVER_NAME) String serverName,
+ @QueryParam(QUERY_PARAM_TYPE) String type, @QueryParam(QUERY_PARAM_PERIOD) String period,
+ @QueryParam(QUERY_PARAM_INTERFACE) String networkInterface) {
+ return getPerformanceData(serverName, type, period, networkInterface, MediaType.APPLICATION_XML);
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("{" + PATH_PARAM_SERVER_NAME + "}/" + RESOURCE_STATISTICS)
- public Response getPerformanceDataJSON(@PathParam(PATH_PARAM_SERVER_NAME) String serverName, @QueryParam(QUERY_PARAM_TYPE) String type) {
- return getPerformanceData(serverName, type, MediaType.APPLICATION_JSON);
+ public Response getPerformanceDataJSON(@PathParam(PATH_PARAM_SERVER_NAME) String serverName,
+ @QueryParam(QUERY_PARAM_TYPE) String type, @QueryParam(QUERY_PARAM_PERIOD) String period,
+ @QueryParam(QUERY_PARAM_INTERFACE) String networkInterface) {
+ return getPerformanceData(serverName, type, period, networkInterface, MediaType.APPLICATION_JSON);
}
- private Response getAggregaredPerformanceData(String clusterName, String type, String mediaType) {
+ private Response getAggregaredPerformanceData(String clusterName, String type, String period, String mediaType) {
List<String> serverNames = getServerNames(getGlusterServers(clusterName, false));
- if(type.equals(STATISTICS_TYPE_CPU)) {
- return okResponse(serverUtil.fetchAggregatedCPUStats(serverNames), mediaType);
- } else {
- return badRequestResponse("Server Statistics for [" + type + "] not supported! Valid values are ["
- + STATISTICS_TYPE_CPU + ", " + STATISTICS_TYPE_NETWORK + ", " + STATISTICS_TYPE_MEMORY + "]");
- }
+ return okResponse(getStatsFactory(type).fetchAggregatedStats(serverNames, period), mediaType);
}
- private Response getPerformanceData(String serverName, String type, String mediaType) {
+ private Response getPerformanceData(String serverName, String type, String period, String networkInterface, String mediaType) {
+ return okResponse(getStatsFactory(type).fetchStats(serverName, period, networkInterface), mediaType);
+ }
+
+ private StatsFactory getStatsFactory(String type) {
if(type.equals(STATISTICS_TYPE_CPU)) {
- return okResponse(serverUtil.fetchCPUUsageData(serverName), mediaType);
- } else if(type.equals(STATISTICS_TYPE_NETWORK)) {
- return okResponse(serverUtil.fetchCPUUsageData(serverName), mediaType);
+ return cpuStatsFactory;
} else if(type.equals(STATISTICS_TYPE_MEMORY)) {
- return okResponse(serverUtil.fetchCPUUsageData(serverName), mediaType);
+ return memoryStatsFactory;
+ } else if(type.equals(STATISTICS_TYPE_NETWORK)) {
+ return networkStatsFactory;
} else {
- return badRequestResponse("Server Statistics for [" + type + "] not supported! Valid values are ["
+ throw new GlusterValidationException("Invalid server statistics type [" + type + "]. Valid values are ["
+ STATISTICS_TYPE_CPU + ", " + STATISTICS_TYPE_NETWORK + ", " + STATISTICS_TYPE_MEMORY + "]");
}
}
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/AbstractStatsFactory.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/AbstractStatsFactory.java
new file mode 100644
index 00000000..820cc542
--- /dev/null
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/AbstractStatsFactory.java
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *******************************************************************************/
+package com.gluster.storage.management.server.utils;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.gluster.storage.management.core.exceptions.GlusterRuntimeException;
+import com.gluster.storage.management.core.model.ServerStats;
+import com.gluster.storage.management.core.model.ServerStatsRow;
+import com.gluster.storage.management.core.model.Status;
+
+/**
+ *
+ */
+@Component
+public abstract class AbstractStatsFactory implements StatsFactory {
+ @Autowired
+ protected ServerUtil serverUtil;
+
+ private Logger logger = Logger.getLogger(AbstractStatsFactory.class);
+
+ protected ServerStats getFirstOnlineServerStats(List<String> serverNames, String period,
+ boolean removeServerOnError, boolean removeOnlineServer) {
+ for(int i = serverNames.size() - 1; i >= 0; i--) {
+ String serverName = serverNames.get(i);
+ try {
+ ServerStats stats = fetchStats(serverName, period);
+ if(removeOnlineServer) {
+ serverNames.remove(serverName);
+ }
+ return stats;
+ } catch(Exception e) {
+ // server might be offline - continue with next one
+ logger.warn("Couldn't fetch CPU stats from server [" + serverName + "]!", e);
+ if(removeServerOnError) {
+ serverNames.remove(serverName);
+ }
+ continue;
+ }
+ }
+ throw new GlusterRuntimeException("All servers offline!");
+ }
+
+ protected void aggregateStats(List<String> serverNames, ServerStats aggregatedStats, String period) {
+ if(serverNames.isEmpty()) {
+ return;
+ }
+
+ int rowCount = aggregatedStats.getMetadata().getRowCount();
+ int columnCount = aggregatedStats.getMetadata().getLegend().size();
+ int[][] dataCount = initDataCountArray(rowCount, columnCount);
+
+ for (String serverName : serverNames) {
+ try {
+ // fetch the stats and add to aggregated stats
+ addServerStats(fetchStats(serverName, period), aggregatedStats, dataCount);
+ } catch(Exception e) {
+ // server might be offline - continue with next one
+ logger.warn("Couldn't fetch CPU stats from server [" + serverName + "]!", e);
+ continue;
+ }
+ }
+
+ averageAggregatedStats(aggregatedStats, dataCount);
+ }
+
+ /**
+ *
+ * @param statsToBeAdded
+ * @param targetStats
+ * @param dataCount Each element of this matrix will be incremented for every valid element added
+ * @return
+ */
+ protected List<ServerStatsRow> addServerStats(ServerStats statsToBeAdded, ServerStats targetStats, int[][] dataCount) {
+ List<ServerStatsRow> serverStatsRows = statsToBeAdded.getRows();
+ for (int rowNum = 0; rowNum < serverStatsRows.size()
+ && rowNum < targetStats.getMetadata().getRowCount(); rowNum++) {
+ ServerStatsRow row = serverStatsRows.get(rowNum);
+ List<Double> rowData = row.getUsageData();
+
+ List<Double> aggregatedStatsRowData = targetStats.getRows().get(rowNum).getUsageData();
+ for(int i = 1; i < targetStats.getMetadata().getLegend().size(); i++) {
+ // Add the data
+ Double data = rowData.get(i);
+ if(!data.isNaN()) {
+ // data is available. add it.
+ aggregatedStatsRowData.set(i, aggregatedStatsRowData.get(i) + data);
+ // increment record count. this will be used for calculating average of aggregated data.
+ dataCount[rowNum][i]++;
+ }
+ }
+ }
+ return serverStatsRows;
+ }
+
+ protected void averageAggregatedStats(ServerStats aggregatedStats, int[][] dataCount) {
+ List<ServerStatsRow> rows = aggregatedStats.getRows();
+ for(int rowNum = 0; rowNum < rows.size(); rowNum++) {
+ List<Double> data = rows.get(rowNum).getUsageData();
+ for(int columnNum = 0; columnNum < data.size(); columnNum++) {
+ data.set(columnNum, data.get(columnNum) / dataCount[rowNum][columnNum]);
+ }
+ }
+ }
+
+ protected int[][] initDataCountArray(int rowCount, int columnCount) {
+ int[][] dataCount = new int[rowCount][columnCount];
+ // initialize all data counts to 1
+ for(int rowNum = 0; rowNum < rowCount; rowNum++) {
+ for(int columnNum = 0; columnNum < columnCount; columnNum++) {
+ dataCount[rowNum][columnNum] = 1;
+ }
+ }
+ return dataCount;
+ }
+
+ @Override
+ public ServerStats fetchAggregatedStats(List<String> serverNames, String period) {
+ if(serverNames == null || serverNames.size() == 0) {
+ throw new GlusterRuntimeException("No server names passed to fetchAggregaredCPUStats!");
+ }
+
+ ServerStats firstServerStats = getFirstOnlineServerStats(serverNames, period, true, true);
+
+ ServerStats aggregatedStats = new ServerStats(firstServerStats);
+ aggregateStats(serverNames, aggregatedStats, period);
+ return aggregatedStats;
+ }
+
+ @Override
+ public ServerStats fetchStats(String serverName, String period, String...args) {
+ String argsStr = "";
+ for (String arg : args) {
+ if(arg != null) {
+ argsStr += " " + arg;
+ }
+ }
+ Object output = serverUtil.executeOnServer(true, serverName, getStatsScriptName() + argsStr + " " + period, ServerStats.class);
+ //String cpuUsageData = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> <xport> <meta> <start>1310468100</start> <step>300</step> <end>1310471700</end> <rows>13</rows> <columns>3</columns> <legend> <entry>user</entry> <entry>system</entry> <entry>total</entry> </legend> </meta> <data> <row><t>1310468100</t><v>2.23802952e-1</v><v>4.3747778209e-01</v><v>6.6128073384e-01</v></row> <row><t>1310468400</t><v>2.3387347338e-01</v><v>4.4642717442e-01</v><v>6.8030064780e-01</v></row> <row><t>1310468700</t><v>5.5043873220e+00</v><v>6.2462376636e+00</v><v>1.1750624986e+01</v></row> <row><t>1310469000</t><v>2.4350593653e+01</v><v>2.6214585217e+01</v><v>5.0565178869e+01</v></row> <row><t>1310469300</t><v>4.0786489953e+01</v><v>4.6784713828e+01</v><v>8.7571203781e+01</v></row> <row><t>1310469600</t><v>4.1459955508e+01</v><v>5.2546309044e+01</v><v>9.4006264551e+01</v></row> <row><t>1310469900</t><v>4.2312286165e+01</v><v>5.2390588332e+01</v><v>9.4702874497e+01</v></row> <row><t>1310470200</t><v>4.2603794982e+01</v><v>5.1598861493e+01</v><v>9.4202656475e+01</v></row> <row><t>1310470500</t><v>3.8238751290e+01</v><v>4.5312089966e+01</v><v>8.3550841256e+01</v></row> <row><t>1310470800</t><v>1.7949961224e+01</v><v>2.1282058418e+01</v><v>3.9232019642e+01</v></row> <row><t>1310471100</t><v>1.2330371421e-01</v><v>4.6347832868e-01</v><v>5.8678204289e-01</v></row> <row><t>1310471400</t><v>1.6313260492e-01</v><v>5.4088119561e-01</v><v>7.0401380052e-01</v></row> <row><t>1310471700</t><v>NaN</v><v>NaN</v><v>NaN</v></row> </data> </xport>";
+ //Object output = unmarshal(ServerStats.class, cpuUsageData, false);
+ if(output instanceof Status) {
+ throw new GlusterRuntimeException(((Status)output).toString());
+ }
+ return (ServerStats) output;
+ }
+
+ public abstract String getStatsScriptName();
+}
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/CpuStatsFactory.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/CpuStatsFactory.java
new file mode 100644
index 00000000..27e271e5
--- /dev/null
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/CpuStatsFactory.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *******************************************************************************/
+package com.gluster.storage.management.server.utils;
+
+import org.springframework.stereotype.Component;
+
+/**
+ *
+ */
+@Component
+public class CpuStatsFactory extends AbstractStatsFactory {
+
+ private static final String CPU_STATS_SCRIPT = "get_rrd_cpu_details.py";
+
+ @Override
+ public String getStatsScriptName() {
+ return CPU_STATS_SCRIPT;
+ }
+
+}
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/MemoryStatsFactory.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/MemoryStatsFactory.java
new file mode 100644
index 00000000..65f4e44e
--- /dev/null
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/MemoryStatsFactory.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *******************************************************************************/
+package com.gluster.storage.management.server.utils;
+
+import org.springframework.stereotype.Component;
+
+/**
+ *
+ */
+@Component
+public class MemoryStatsFactory extends AbstractStatsFactory {
+
+ private static final String MEM_STATS_SCRIPT = "get_rrd_mem_details.py";
+
+ @Override
+ public String getStatsScriptName() {
+ return MEM_STATS_SCRIPT;
+ }
+
+}
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/NetworkStatsFactory.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/NetworkStatsFactory.java
new file mode 100644
index 00000000..96bb0c65
--- /dev/null
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/NetworkStatsFactory.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *******************************************************************************/
+package com.gluster.storage.management.server.utils;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.gluster.storage.management.core.exceptions.GlusterRuntimeException;
+import com.gluster.storage.management.core.model.NetworkInterface;
+import com.gluster.storage.management.core.model.Server;
+import com.gluster.storage.management.core.model.ServerStats;
+
+/**
+ *
+ */
+@Component
+public class NetworkStatsFactory extends AbstractStatsFactory {
+ private static final Logger logger = Logger.getLogger(NetworkStatsFactory.class);
+ private static final String NETWORK_STATS_SCRIPT = "get_rrd_net_details.py";
+ private int[][] dataCount;
+
+ @Override
+ public String getStatsScriptName() {
+ return NETWORK_STATS_SCRIPT;
+ }
+
+ @Override
+ protected ServerStats getFirstOnlineServerStats(List<String> serverNames, String period,
+ boolean removeServerOnError, boolean removeOnlineServer) {
+ ServerStats firstOnlineServerStats = null;
+ for(int i = serverNames.size() - 1; i >= 0; i--) {
+ String serverName = serverNames.get(i);
+ Server server = new Server(serverName);
+ serverUtil.fetchServerDetails(server);
+ try {
+ for(NetworkInterface networkInterface : server.getNetworkInterfaces()) {
+ ServerStats stats = fetchStats(serverName, period, networkInterface.getName());
+ if(firstOnlineServerStats == null) {
+ firstOnlineServerStats = stats;
+ int rowCount = firstOnlineServerStats.getMetadata().getRowCount();
+ int columnCount = firstOnlineServerStats.getMetadata().getLegend().size();
+ dataCount = initDataCountArray(rowCount, columnCount);
+ } else {
+ addServerStats(stats, firstOnlineServerStats, dataCount);
+ }
+ }
+
+ if(removeOnlineServer) {
+ serverNames.remove(serverName);
+ }
+ return firstOnlineServerStats;
+ } catch(Exception e) {
+ // server might be offline - continue with next one
+ logger.warn("Couldn't fetch stats from server [" + serverName + "]!", e);
+ if(removeServerOnError) {
+ serverNames.remove(serverName);
+ }
+ continue;
+ }
+ }
+ throw new GlusterRuntimeException("All servers offline!");
+ }
+
+ protected void aggregateStats(List<String> serverNames, ServerStats aggregatedStats, String period) {
+ if(serverNames.isEmpty()) {
+ return;
+ }
+
+ for (String serverName : serverNames) {
+ try {
+ Server server = new Server(serverName);
+ serverUtil.fetchServerDetails(server);
+
+ for (NetworkInterface networkInterface : server.getNetworkInterfaces()) {
+ // fetch the stats and add to aggregated stats
+ addServerStats(fetchStats(serverName, period, networkInterface.getName()), aggregatedStats, dataCount);
+ }
+ } catch(Exception e) {
+ // server might be offline - continue with next one
+ logger.warn("Couldn't fetch Network stats from server [" + serverName + "]!", e);
+ continue;
+ }
+ }
+
+ averageAggregatedStats(aggregatedStats, dataCount);
+ }
+}
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java
index 871a2e9d..e4d37ad8 100644
--- a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/ServerUtil.java
@@ -23,8 +23,6 @@ package com.gluster.storage.management.server.utils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
import java.util.List;
import javax.servlet.ServletContext;
@@ -40,9 +38,9 @@ import org.springframework.stereotype.Component;
import com.gluster.storage.management.core.constants.CoreConstants;
import com.gluster.storage.management.core.exceptions.ConnectionException;
import com.gluster.storage.management.core.exceptions.GlusterRuntimeException;
-import com.gluster.storage.management.core.model.ServerStatsRow;
-import com.gluster.storage.management.core.model.ServerStats;
import com.gluster.storage.management.core.model.Server;
+import com.gluster.storage.management.core.model.ServerStats;
+import com.gluster.storage.management.core.model.ServerStatsRow;
import com.gluster.storage.management.core.model.Status;
import com.gluster.storage.management.core.response.GenericResponse;
import com.gluster.storage.management.core.utils.ProcessResult;
@@ -226,140 +224,24 @@ public class ServerUtil {
return (Status) executeOnServer(true, serverName, REMOTE_SCRIPT_GET_DISK_FOR_DIR + " " + brickDir, Status.class);
}
- public ServerStats fetchCPUUsageData(String serverName) {
- Object output = executeOnServer(true, serverName, "get_rrd_cpu_details.py 1d", ServerStats.class);
- //String cpuUsageData = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?> <xport> <meta> <start>1310468100</start> <step>300</step> <end>1310471700</end> <rows>13</rows> <columns>3</columns> <legend> <entry>user</entry> <entry>system</entry> <entry>total</entry> </legend> </meta> <data> <row><t>1310468100</t><v>2.23802952e-1</v><v>4.3747778209e-01</v><v>6.6128073384e-01</v></row> <row><t>1310468400</t><v>2.3387347338e-01</v><v>4.4642717442e-01</v><v>6.8030064780e-01</v></row> <row><t>1310468700</t><v>5.5043873220e+00</v><v>6.2462376636e+00</v><v>1.1750624986e+01</v></row> <row><t>1310469000</t><v>2.4350593653e+01</v><v>2.6214585217e+01</v><v>5.0565178869e+01</v></row> <row><t>1310469300</t><v>4.0786489953e+01</v><v>4.6784713828e+01</v><v>8.7571203781e+01</v></row> <row><t>1310469600</t><v>4.1459955508e+01</v><v>5.2546309044e+01</v><v>9.4006264551e+01</v></row> <row><t>1310469900</t><v>4.2312286165e+01</v><v>5.2390588332e+01</v><v>9.4702874497e+01</v></row> <row><t>1310470200</t><v>4.2603794982e+01</v><v>5.1598861493e+01</v><v>9.4202656475e+01</v></row> <row><t>1310470500</t><v>3.8238751290e+01</v><v>4.5312089966e+01</v><v>8.3550841256e+01</v></row> <row><t>1310470800</t><v>1.7949961224e+01</v><v>2.1282058418e+01</v><v>3.9232019642e+01</v></row> <row><t>1310471100</t><v>1.2330371421e-01</v><v>4.6347832868e-01</v><v>5.8678204289e-01</v></row> <row><t>1310471400</t><v>1.6313260492e-01</v><v>5.4088119561e-01</v><v>7.0401380052e-01</v></row> <row><t>1310471700</t><v>NaN</v><v>NaN</v><v>NaN</v></row> </data> </xport>";
- //Object output = unmarshal(ServerStats.class, cpuUsageData, false);
- if(output instanceof Status) {
- throw new GlusterRuntimeException(((Status)output).toString());
- }
- return (ServerStats) output;
- }
-
- private ServerStats getFirstOnlineServerCPUStats(List<String> serverNames, boolean removeServerOnError, boolean removeOnlineServer) {
- for(int i = serverNames.size() - 1; i >= 0; i--) {
- String serverName = serverNames.get(i);
- try {
- ServerStats stats = fetchCPUUsageData(serverName);
- if(removeOnlineServer) {
- serverNames.remove(serverName);
- }
- return stats;
- } catch(Exception e) {
- // server might be offline - continue with next one
- logger.warn("Couldn't fetch CPU stats from server [" + serverName + "]!", e);
- if(removeServerOnError) {
- serverNames.remove(serverName);
- }
- continue;
- }
- }
- throw new GlusterRuntimeException("All servers offline!");
- }
-
- public ServerStats fetchAggregatedCPUStats(List<String> serverNames) {
- if(serverNames == null || serverNames.size() == 0) {
- throw new GlusterRuntimeException("No server names passed to fetchAggregaredCPUUsageData!");
- }
-
- ServerStats firstServerStats = getFirstOnlineServerCPUStats(serverNames, true, true);
-
- ServerStats aggregatedStats = new ServerStats(firstServerStats);
- aggregateCPUStats(serverNames, aggregatedStats);
- return aggregatedStats;
- }
-
- private void aggregateCPUStats(List<String> serverNames, ServerStats aggregatedStats) {
- if(serverNames.isEmpty()) {
- return;
- }
-
- int rowCount = aggregatedStats.getMetadata().getRowCount();
- int columnCount = aggregatedStats.getMetadata().getLegend().size();
- int[][] dataCount = initDataCountArray(rowCount, columnCount);
-
- for (String serverName : serverNames) {
- try {
- // fetch the stats and add to aggregated stats
- addServerStats(fetchCPUUsageData(serverName), aggregatedStats, dataCount);
- } catch(Exception e) {
- // server might be offline - continue with next one
- logger.warn("Couldn't fetch CPU stats from server [" + serverName + "]!", e);
- continue;
- }
- }
-
- averageAggregatedStats(aggregatedStats, dataCount);
- }
-
- private void averageAggregatedStats(ServerStats aggregatedStats, int[][] dataCount) {
- List<ServerStatsRow> rows = aggregatedStats.getRows();
- for(int rowNum = 0; rowNum < rows.size(); rowNum++) {
- List<Double> data = rows.get(rowNum).getUsageData();
- for(int columnNum = 0; columnNum < data.size(); columnNum++) {
- data.set(columnNum, data.get(columnNum) / dataCount[rowNum][columnNum]);
- }
- }
- }
-
- private int[][] initDataCountArray(int rowCount, int columnCount) {
- int[][] dataCount = new int[rowCount][columnCount];
- // initialize all data counts to 1
- for(int rowNum = 0; rowNum < rowCount; rowNum++) {
- for(int columnNum = 0; columnNum < columnCount; columnNum++) {
- dataCount[rowNum][columnNum] = 1;
- }
- }
- return dataCount;
- }
-
- /**
- *
- * @param statsToBeAdded
- * @param targetStats
- * @param dataCount Each element of this matrix will be incremented for every valid element added
- * @return
- */
- private List<ServerStatsRow> addServerStats(ServerStats statsToBeAdded, ServerStats targetStats, int[][] dataCount) {
- List<ServerStatsRow> serverStatsRows = statsToBeAdded.getRows();
- for (int rowNum = 0; rowNum < serverStatsRows.size()
- && rowNum < targetStats.getMetadata().getRowCount(); rowNum++) {
- ServerStatsRow row = serverStatsRows.get(rowNum);
- List<Double> rowData = row.getUsageData();
-
- List<Double> aggregatedStatsRowData = targetStats.getRows().get(rowNum).getUsageData();
- for(int i = 1; i < targetStats.getMetadata().getLegend().size(); i++) {
- // Add the data
- Double data = rowData.get(i);
- if(!data.isNaN()) {
- // data is available. add it.
- aggregatedStatsRowData.set(i, aggregatedStatsRowData.get(i) + data);
- // increment record count. this will be used for calculating average of aggregated data.
- dataCount[rowNum][i]++;
- }
- }
- }
- return serverStatsRows;
- }
-
public static void main(String[] args) {
- ServerStats stats = new ServerUtil().fetchCPUUsageData("s1");
- for(ServerStatsRow row : stats.getRows()) {
- System.out.println(row.getUsageData().get(2));
- }
- JAXBContext context;
- try {
- context = JAXBContext.newInstance(ServerStats.class);
- Marshaller m = context.createMarshaller();
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- m.marshal(stats, out);
- ServerStats stats1 = (ServerStats)new ServerUtil().unmarshal(ServerStats.class, out.toString(), false);
- for(ServerStatsRow row : stats1.getRows()) {
- System.out.println(row.getUsageData().get(2));
- }
- } catch (JAXBException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
+// ServerStats stats = new ServerUtil().fetchCPUUsageData("s1", "1d");
+// for(ServerStatsRow row : stats.getRows()) {
+// System.out.println(row.getUsageData().get(2));
+// }
+// JAXBContext context;
+// try {
+// context = JAXBContext.newInstance(ServerStats.class);
+// Marshaller m = context.createMarshaller();
+// ByteArrayOutputStream out = new ByteArrayOutputStream();
+// m.marshal(stats, out);
+// ServerStats stats1 = (ServerStats)new ServerUtil().unmarshal(ServerStats.class, out.toString(), false);
+// for(ServerStatsRow row : stats1.getRows()) {
+// System.out.println(row.getUsageData().get(2));
+// }
+// } catch (JAXBException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+// }
}
}
diff --git a/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/StatsFactory.java b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/StatsFactory.java
new file mode 100644
index 00000000..85487602
--- /dev/null
+++ b/src/com.gluster.storage.management.server/src/com/gluster/storage/management/server/utils/StatsFactory.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com>
+ * This file is part of Gluster Management Console.
+ *
+ * Gluster Management Console is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Gluster Management Console is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *******************************************************************************/
+package com.gluster.storage.management.server.utils;
+
+import java.util.List;
+
+import com.gluster.storage.management.core.model.ServerStats;
+
+/**
+ *
+ */
+public interface StatsFactory {
+ public ServerStats fetchStats(String serverName, String period, String...args);
+ public ServerStats fetchAggregatedStats(List<String> serverName, String period);
+}