diff options
| author | Selvasundaram <selvam@gluster.com> | 2011-07-25 14:54:50 +0530 |
|---|---|---|
| committer | Selvasundaram <selvam@gluster.com> | 2011-07-25 14:54:50 +0530 |
| commit | 0662fff71691bfcb0e667d7ffb4f9e057c2860be (patch) | |
| tree | a21ffe346d8f76bf7919299bfc72241fd80c7eda /src/com.gluster.storage.management.server | |
| parent | f887ca2e1b69874117ce930771f837a6776bd94d (diff) | |
| parent | a2a52d53ee2e0dd32b993c112200cfd1c927aafa (diff) | |
Merge branch 'master' of github.com:gluster/console
Diffstat (limited to 'src/com.gluster.storage.management.server')
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); +} |
