diff options
| author | Shireesh Anjal <shireesh@gluster.com> | 2011-07-23 19:12:02 +0530 |
|---|---|---|
| committer | Shireesh Anjal <shireesh@gluster.com> | 2011-07-24 22:14:36 +0530 |
| commit | c3f598a9a5dc66428c98e026f621caf647ae09fd (patch) | |
| tree | d40471204ee2c2410df30daa4a9eb40f73201df7 /src | |
| parent | a2a73df297f918dfb07f19d44fbed3c3654b9fb5 (diff) | |
Story #38 - CPU Usage graph
Diffstat (limited to 'src')
23 files changed, 694 insertions, 402 deletions
diff --git a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java index 8be5beac..ee29c353 100644 --- a/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java +++ b/src/com.gluster.storage.management.client/src/com/gluster/storage/management/client/GlusterServersClient.java @@ -85,15 +85,24 @@ public class GlusterServersClient extends AbstractClient { deleteSubResource(serverName); } - public ServerStats getCPUStats(String serverName) { + public ServerStats getCpuStats(String serverName, String period) { MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); queryParams.add(RESTConstants.QUERY_PARAM_TYPE, RESTConstants.STATISTICS_TYPE_CPU); + queryParams.add(RESTConstants.QUERY_PARAM_PERIOD, period); return fetchSubResource(serverName + "/" + RESTConstants.RESOURCE_STATISTICS, queryParams, ServerStats.class); } - public ServerStats getAggregatedCPUStats() { + public ServerStats getAggregatedCpuStats(String period) { MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); queryParams.add(RESTConstants.QUERY_PARAM_TYPE, RESTConstants.STATISTICS_TYPE_CPU); + queryParams.add(RESTConstants.QUERY_PARAM_PERIOD, period); + return fetchSubResource(RESTConstants.RESOURCE_STATISTICS, queryParams, ServerStats.class); + } + + public ServerStats getAggregatedNetworkStats(String period) { + MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); + queryParams.add(RESTConstants.QUERY_PARAM_TYPE, RESTConstants.STATISTICS_TYPE_NETWORK); + queryParams.add(RESTConstants.QUERY_PARAM_PERIOD, period); return fetchSubResource(RESTConstants.RESOURCE_STATISTICS, queryParams, ServerStats.class); } } diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java index d4b0e43a..edf3bbe4 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/constants/RESTConstants.java @@ -100,6 +100,8 @@ public class RESTConstants { public static final String QUERY_PARAM_SERVER_NAME = "serverName"; public static final String QUERY_PARAM_DETAILS = "details"; public static final String QUERY_PARAM_TYPE = "type"; + public static final String QUERY_PARAM_PERIOD = "period"; + public static final String QUERY_PARAM_INTERFACE = "interface"; public static final String STATISTICS_TYPE_CPU = "cpu"; public static final String STATISTICS_TYPE_NETWORK = "network"; diff --git a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java index 58faef02..67aeeeda 100644 --- a/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java +++ b/src/com.gluster.storage.management.core/src/com/gluster/storage/management/core/model/Cluster.java @@ -30,6 +30,8 @@ public class Cluster extends Entity { List<Volume> volumes = new ArrayList<Volume>(); List<TaskInfo> taskInfoList = new ArrayList<TaskInfo>(); List<Alert> alerts = new ArrayList<Alert>(); + ServerStats aggregatedCpuStats; + ServerStats aggregatedNetworkStats; public Cluster() { } @@ -175,4 +177,20 @@ public class Cluster extends Entity { } return null; } + + public ServerStats getAggregatedCpuStats() { + return aggregatedCpuStats; + } + + public void setAggregatedCpuStats(ServerStats aggregatedCpuStats) { + this.aggregatedCpuStats = aggregatedCpuStats; + } + + public ServerStats getAggregatedNetworkStats() { + return aggregatedNetworkStats; + } + + public void setAggregatedNetworkStats(ServerStats aggregatedNetworkStats) { + this.aggregatedNetworkStats = aggregatedNetworkStats; + } } diff --git a/src/com.gluster.storage.management.gui/plugin.xml b/src/com.gluster.storage.management.gui/plugin.xml index 250fa2e2..3955ed91 100644 --- a/src/com.gluster.storage.management.gui/plugin.xml +++ b/src/com.gluster.storage.management.gui/plugin.xml @@ -1389,10 +1389,17 @@ name="Gluster"> </page> <page + category="com.gluster.storage.management.gui.preferences.GlusterPreferencePage" class="com.gluster.storage.management.gui.preferences.AlertsPreferencePage" id="com.gluster.storage.management.gui.preferences.AlertsPreferencePage" name="Alerts"> </page> + <page + category="com.gluster.storage.management.gui.preferences.GlusterPreferencePage" + class="com.gluster.storage.management.gui.preferences.ChartsPreferencePage" + id="com.gluster.storage.management.gui.preferences.ChartsPreferencePage" + name="Charts"> + </page> </extension> <extension point="org.eclipse.core.runtime.preferences"> diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/GlusterDataModelManager.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/GlusterDataModelManager.java index aba7dde2..d63886c6 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/GlusterDataModelManager.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/GlusterDataModelManager.java @@ -26,6 +26,7 @@ import java.util.Set; import org.apache.log4j.Logger; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.preference.IPreferenceStore; import com.gluster.storage.management.client.DiscoveredServersClient; import com.gluster.storage.management.client.GlusterServersClient; @@ -33,11 +34,11 @@ import com.gluster.storage.management.client.TasksClient; import com.gluster.storage.management.client.VolumesClient; import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; import com.gluster.storage.management.core.model.Alert; +import com.gluster.storage.management.core.model.Alert.ALERT_TYPES; import com.gluster.storage.management.core.model.Brick; import com.gluster.storage.management.core.model.Cluster; import com.gluster.storage.management.core.model.ClusterListener; import com.gluster.storage.management.core.model.Device; -import com.gluster.storage.management.core.model.Alert.ALERT_TYPES; import com.gluster.storage.management.core.model.Device.DEVICE_STATUS; import com.gluster.storage.management.core.model.Disk; import com.gluster.storage.management.core.model.Event; @@ -56,6 +57,7 @@ import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE; import com.gluster.storage.management.core.model.VolumeOptionInfo; import com.gluster.storage.management.core.utils.GlusterCoreUtil; +import com.gluster.storage.management.gui.preferences.PreferenceConstants; public class GlusterDataModelManager { private static GlusterDataModelManager instance = new GlusterDataModelManager(); @@ -116,6 +118,16 @@ public class GlusterDataModelManager { volumeChanged(oldVolume, newVolume); } } + + private boolean isCancelled(IProgressMonitor monitor) { + if(monitor.isCanceled()) { + monitor.setTaskName("Data sync cancelled!"); + monitor.done(); + return true; + } else { + return false; + } + } public GlusterDataModel fetchModel(IProgressMonitor monitor) { synchronized (syncInProgress) { @@ -132,23 +144,46 @@ public class GlusterDataModelManager { Cluster cluster = new Cluster(clusterName, model); model.addCluster(cluster); - monitor.beginTask("Data Sync", 4); + monitor.beginTask("Data Sync", 6); monitor.setTaskName("Syncing servers..."); initializeGlusterServers(cluster); monitor.worked(1); + if(isCancelled(monitor)) { + return model; + } monitor.setTaskName("Syncing volumes..."); initializeVolumes(cluster); monitor.worked(1); + if(isCancelled(monitor)) { + return model; + } monitor.setTaskName("Syncing discovered servers..."); initializeAutoDiscoveredServers(cluster); monitor.worked(1); + if(isCancelled(monitor)) { + return model; + } monitor.setTaskName("Syncing tasks..."); initializeTasks(cluster); monitor.worked(1); + if(isCancelled(monitor)) { + return model; + } + + monitor.setTaskName("Syncing aggregated CPU stats..."); + initializeAggregatedCpuStats(cluster); + monitor.worked(1); + if(isCancelled(monitor)) { + return model; + } + + monitor.setTaskName("Syncing aggregated Network stats..."); + initializeAggregatedNetworkStats(cluster); + monitor.worked(1); monitor.done(); return model; @@ -391,12 +426,26 @@ public class GlusterDataModelManager { this.volumeOptionsDefaults = new VolumesClient(clusterName).getVolumeOptionsDefaults(); } - public void initializeTasks(Cluster cluster) { + private void initializeTasks(Cluster cluster) { List<TaskInfo> taskInfoList = new TasksClient(cluster.getName()).getAllTasks(); //List<TaskInfo> taskInfoList = getDummyTasks(); cluster.setTaskInfoList(taskInfoList); } + private void initializeAggregatedCpuStats(Cluster cluster) { + IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore(); + String cpuStatsPeriod = preferenceStore.getString(PreferenceConstants.P_CPU_CHART_PERIOD); + + cluster.setAggregatedCpuStats(new GlusterServersClient().getAggregatedCpuStats(cpuStatsPeriod)); + } + + private void initializeAggregatedNetworkStats(Cluster cluster) { + IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore(); + String networkStatsPeriod = preferenceStore.getString(PreferenceConstants.P_NETWORK_CHART_PERIOD); + + cluster.setAggregatedNetworkStats(new GlusterServersClient().getAggregatedNetworkStats(networkStatsPeriod)); + } + private List<TaskInfo> getDummyTasks() { List<TaskInfo> taskInfoList = new ArrayList<TaskInfo>(); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ChangePasswordDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ChangePasswordDialog.java index d62c5dcb..00f2aab0 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ChangePasswordDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ChangePasswordDialog.java @@ -193,6 +193,7 @@ public class ChangePasswordDialog extends Dialog { @Override protected void createButtonsForButtonBar(Composite parent) { okButton = createButton(parent, IDialogConstants.OK_ID, "&Change", true); + okButton.setEnabled(false); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); setupDataBinding(); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java index 37381172..f5d2f6dd 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/ClusterSelectionDialog.java @@ -200,6 +200,7 @@ public class ClusterSelectionDialog extends Dialog { private void createClusterRegisterComposite(Composite composite) { clusterRegisterComposite = new Composite(composite, SWT.NONE); GridLayout layout = new GridLayout(2, false); + layout.horizontalSpacing = 15; clusterRegisterComposite.setLayout(layout); createClusterNameLabel(clusterRegisterComposite); @@ -224,6 +225,7 @@ public class ClusterSelectionDialog extends Dialog { private void createClusterCreationComposite(Composite subComposite) { clusterCreationComposite = new Composite(subComposite, SWT.NONE); GridLayout layout = new GridLayout(2, false); + layout.horizontalSpacing = 15; clusterCreationComposite.setLayout(layout); createClusterNameLabel(clusterCreationComposite); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java index 9c7988e3..401bdce0 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/LoginDialog.java @@ -222,11 +222,10 @@ public class LoginDialog extends Dialog { if (password.equalsIgnoreCase(CoreConstants.DEFAULT_PASSWORD)) { String oldSecurityTokeString = GlusterDataModelManager.getInstance().getSecurityToken(); ChangePasswordDialog dialog = new ChangePasswordDialog(getShell()); - dialog.open(); - if (GlusterDataModelManager.getInstance().getSecurityToken().equals(oldSecurityTokeString)) { - MessageDialog.openInformation(getShell(), "Change password Cancelled", - "Gateway could not be accessed with default password !" + "\n\n" + "Application will close."); + if (dialog.open() == Dialog.CANCEL) { + MessageDialog.openError(getShell(), "Change password Cancelled", + "Password must be changed on first login!" + "\n" + "Application will close."); cancelPressed(); return; } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ChartsPreferencePage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ChartsPreferencePage.java new file mode 100644 index 00000000..112a2a91 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ChartsPreferencePage.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * 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.gui.preferences; + +import org.eclipse.jface.preference.ComboFieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +import com.gluster.storage.management.gui.Activator; + +/** + * + */ +public class ChartsPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { + + public ChartsPreferencePage() { + super(GRID); + setPreferenceStore(Activator.getDefault().getPreferenceStore()); + setDescription("Gluster Management Console - Charts Preferences"); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + @Override + public void init(IWorkbench workbench) { + } + + /* (non-Javadoc) + * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors() + */ + @Override + protected void createFieldEditors() { + String[][] entryNamesAndValues = new String[][] { { "1 day", "1d" }, { "1 week", "1w" }, { "1 month", "1m" }, + { "1 year", "1y" } }; + addField(new ComboFieldEditor(PreferenceConstants.P_CPU_CHART_PERIOD, "CPU Usage chart period", + entryNamesAndValues, getFieldEditorParent())); + addField(new ComboFieldEditor(PreferenceConstants.P_MEM_CHART_PERIOD, "Memory Usage chart period", entryNamesAndValues, + getFieldEditorParent())); + addField(new ComboFieldEditor(PreferenceConstants.P_NETWORK_CHART_PERIOD, "Network Usage chart period", entryNamesAndValues, + getFieldEditorParent())); + } + +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ClusterPreferencePage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ClusterPreferencePage.java deleted file mode 100644 index 14dbeba9..00000000 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ClusterPreferencePage.java +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * 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.gui.preferences; - -import org.eclipse.jface.preference.*; -import org.eclipse.ui.IWorkbenchPreferencePage; -import org.eclipse.ui.IWorkbench; - -import com.gluster.storage.management.gui.Activator; - -/** - * This class represents a preference page that - * is contributed to the Preferences dialog. By - * subclassing <samp>FieldEditorPreferencePage</samp>, we - * can use the field support built into JFace that allows - * us to create a page that is small and knows how to - * save, restore and apply itself. - * <p> - * This page is used to modify preferences only. They - * are stored in the preference store that belongs to - * the main plug-in class. That way, preferences can - * be accessed directly via the preference store. - */ - -public class ClusterPreferencePage - extends FieldEditorPreferencePage - implements IWorkbenchPreferencePage { - - public ClusterPreferencePage() { - super(GRID); - setPreferenceStore(Activator.getDefault().getPreferenceStore()); - setDescription("A demonstration of a preference page implementation"); - } - - /** - * Creates the field editors. Field editors are abstractions of - * the common GUI blocks needed to manipulate various types - * of preferences. Each field editor knows how to save and - * restore itself. - */ - public void createFieldEditors() { - addField(new DirectoryFieldEditor(PreferenceConstants.P_PATH, - "&Directory preference:", getFieldEditorParent())); - addField( - new BooleanFieldEditor( - PreferenceConstants.P_BOOLEAN, - "&An example of a boolean preference", - getFieldEditorParent())); - - addField(new RadioGroupFieldEditor( - PreferenceConstants.P_CHOICE, - "An example of a multiple-choice preference", - 1, - new String[][] { { "&Choice 1", "choice1" }, { - "C&hoice 2", "choice2" } - }, getFieldEditorParent())); - addField( - new StringFieldEditor(PreferenceConstants.P_STRING, "A &text preference:", getFieldEditorParent())); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) - */ - public void init(IWorkbench workbench) { - } - -}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ConsolePreferencePage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ConsolePreferencePage.java deleted file mode 100644 index 2d49af9b..00000000 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ConsolePreferencePage.java +++ /dev/null @@ -1,83 +0,0 @@ -/******************************************************************************* - * 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.gui.preferences; - -import org.eclipse.jface.preference.*; -import org.eclipse.ui.IWorkbenchPreferencePage; -import org.eclipse.ui.IWorkbench; - -import com.gluster.storage.management.gui.Activator; - -/** - * This class represents a preference page that - * is contributed to the Preferences dialog. By - * subclassing <samp>FieldEditorPreferencePage</samp>, we - * can use the field support built into JFace that allows - * us to create a page that is small and knows how to - * save, restore and apply itself. - * <p> - * This page is used to modify preferences only. They - * are stored in the preference store that belongs to - * the main plug-in class. That way, preferences can - * be accessed directly via the preference store. - */ - -public class ConsolePreferencePage - extends FieldEditorPreferencePage - implements IWorkbenchPreferencePage { - - public ConsolePreferencePage() { - super(GRID); - setPreferenceStore(Activator.getDefault().getPreferenceStore()); - setDescription("A demonstration of a preference page implementation"); - } - - /** - * Creates the field editors. Field editors are abstractions of - * the common GUI blocks needed to manipulate various types - * of preferences. Each field editor knows how to save and - * restore itself. - */ - public void createFieldEditors() { - addField(new DirectoryFieldEditor(PreferenceConstants.P_PATH, - "&Directory preference:", getFieldEditorParent())); - addField( - new BooleanFieldEditor( - PreferenceConstants.P_BOOLEAN, - "&An example of a boolean preference", - getFieldEditorParent())); - - addField(new RadioGroupFieldEditor( - PreferenceConstants.P_CHOICE, - "An example of a multiple-choice preference", - 1, - new String[][] { { "&Choice 1", "choice1" }, { - "C&hoice 2", "choice2" } - }, getFieldEditorParent())); - addField( - new StringFieldEditor(PreferenceConstants.P_STRING, "A &text preference:", getFieldEditorParent())); - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) - */ - public void init(IWorkbench workbench) { - } - -}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java index b44ca37b..46af10d3 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java @@ -31,10 +31,7 @@ public class PreferenceConstants { public static final String P_SERVER_MEMORY_USAGE_THRESHOLD = "server.memory.threshold"; public static final String P_DISK_SPACE_USAGE_THRESHOLD = "disk.space.threshold"; // in percentage - // TODO: Remove after proper preferences are added - public static final String P_PATH = "pathPreference"; - public static final String P_BOOLEAN = "booleanPreference"; - public static final String P_CHOICE = "choicePreference"; - public static final String P_STRING = "stringPreference"; - // public static final String P_CPU_THRESHOLD = "stringPreference"; + public static final String P_CPU_CHART_PERIOD = "cpu.chart.period"; + public static final String P_MEM_CHART_PERIOD = "memory.chart.period"; + public static final String P_NETWORK_CHART_PERIOD = "network.chart.period"; } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java index ae04034b..f889a259 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java @@ -46,5 +46,10 @@ public class PreferenceInitializer extends AbstractPreferenceInitializer { // Default disk free space threshold store.setDefault(PreferenceConstants.P_DISK_SPACE_USAGE_THRESHOLD, 90); + + // Default period for server statistics charts + store.setDefault(PreferenceConstants.P_CPU_CHART_PERIOD, "1d"); + store.setDefault(PreferenceConstants.P_MEM_CHART_PERIOD, "1d"); + store.setDefault(PreferenceConstants.P_NETWORK_CHART_PERIOD, "1d"); } } diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/ChartViewerComposite.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/ChartViewerComposite.java index f7ebd0ec..f2735380 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/ChartViewerComposite.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/ChartViewerComposite.java @@ -213,7 +213,7 @@ public final class ChartViewerComposite extends Composite implements PaintListen DateTimeDataElement dtde1 = DateTimeDataElementImpl.create(timestamps[0]); xAxisPrimary.getScale().setMax(dtde); xAxisPrimary.getScale().setStep((dtde.getValue() - dtde1.getValue())/ 10); - xAxisPrimary.getScale().setMajorGridsStepNumber(timestamps.length / 10); + xAxisPrimary.getScale().setMajorGridsStepNumber(timestamps.length > 10 ? timestamps.length / 10 : 1); //xAxisPrimary.getMajorGrid().setTickStyle(TickStyle.ABOVE_LITERAL); xAxisPrimary.getMajorGrid().getTickAttributes().setVisible(false); xAxisPrimary.getMajorGrid().setLineAttributes(LineAttributesImpl.create(ColorDefinitionImpl.GREY(), LineStyle.SOLID_LITERAL, 1)); diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java index b9a9e5ae..90307c8b 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java @@ -20,6 +20,7 @@ */ package com.gluster.storage.management.gui.views; +import java.util.ArrayList; import java.util.List; import org.eclipse.birt.chart.util.CDateTime; @@ -40,6 +41,7 @@ import org.eclipse.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.part.ViewPart; +import com.gluster.storage.management.client.GlusterServersClient; import com.gluster.storage.management.core.model.Alert; import com.gluster.storage.management.core.model.Cluster; import com.gluster.storage.management.core.model.EntityGroup; @@ -47,6 +49,8 @@ import com.gluster.storage.management.core.model.GlusterDataModel; import com.gluster.storage.management.core.model.GlusterServer; import com.gluster.storage.management.core.model.Server; import com.gluster.storage.management.core.model.Server.SERVER_STATUS; +import com.gluster.storage.management.core.model.ServerStats; +import com.gluster.storage.management.core.model.ServerStatsRow; import com.gluster.storage.management.core.model.TaskInfo; import com.gluster.storage.management.core.utils.NumberUtil; import com.gluster.storage.management.gui.GlusterDataModelManager; @@ -235,7 +239,6 @@ public class ClusterSummaryView extends ViewPart { createDiskSpaceSection(); createCPUUsageSection(); createNetworkUsageSection(); - //createMemoryUsageSection(); createActionsSection(); createAlertsSection(); createRunningTasksSection(); @@ -244,56 +247,53 @@ public class ClusterSummaryView extends ViewPart { } private void createCPUUsageSection() { - Composite section = guiHelper.createSection(form, toolkit, "CPU Usage (aggregated)", null, 1, false); + // in case of CPU usage, there are three elements in usage data: user, system and total. we use total. + createAreaChartSection(cluster.getAggregatedCpuStats(), "CPU Usage (Aggregated)", 2, "%"); + } + + private void createAreaChartSection(ServerStats stats, String sectionTitle, int dataColumnIndex, String unit) { + List<Calendar> timestamps = new ArrayList<Calendar>(); + List<Double> data = new ArrayList<Double>(); + extractChartData(stats, timestamps, data, dataColumnIndex); + + if(timestamps.size() == 0) { + // Log a message saying no CPU stats available + return; + } + + Composite section = guiHelper.createSection(form, toolkit, sectionTitle, null, 1, false); if (cluster.getServers().size() == 0) { toolkit.createLabel(section, "This section will be populated after at least\none server is added to the storage cloud."); return; } -// ServerStats stats = new GlusterServersClient().getAggregatedCPUStats(); -// List<Calendar> timestamps = new ArrayList<Calendar>(); -// List<Double> data = new ArrayList<Double>(); -// for(ServerStatsRow row : stats.getRows()) { -// // in case of CPU usage, there are three elements in usage data: user, system and total. we use total. -// Double cpuUsage = row.getUsageData().get(2); -// if(!cpuUsage.isNaN()) { -// timestamps.add(new CDateTime(row.getTimestamp() * 1000)); -// data.add(cpuUsage); -// } -// } -// createLineChart(section, timestamps.toArray(new Calendar[0]), data.toArray(new Double[0])); + createLineChart(section, timestamps.toArray(new Calendar[0]), data.toArray(new Double[0]), unit); - Calendar[] timestamps = new Calendar[] { new CDateTime(1000l*1310468100), new CDateTime(1000l*1310468400), new CDateTime(1000l*1310468700), - new CDateTime(1000l*1310469000), new CDateTime(1000l*1310469300), new CDateTime(1000l*1310469600), new CDateTime(1000l*1310469900), - new CDateTime(1000l*1310470200), new CDateTime(1000l*1310470500), new CDateTime(1000l*1310470800), new CDateTime(1000l*1310471100), - new CDateTime(1000l*1310471400), new CDateTime(1000l*1310471700), new CDateTime(1000l*1310472000), new CDateTime(1000l*1310472300), - new CDateTime(1000l*1310472600), new CDateTime(1000l*1310472900), new CDateTime(1000l*1310473200), new CDateTime(1000l*1310473500), - new CDateTime(1000l*1310473800) }; - - Double[] values = new Double[] { 10d, 11.23d, 17.92d, 18.69d, 78.62d, 89.11d, 92.43d, 89.31d, 57.39d, 18.46d, 10.44d, 16.28d, 13.51d, 17.53d, 12.21, 20d, 21.43d, 16.45d, 14.86d, 15.27d }; - createLineChart(section, timestamps, values, "%"); +// Calendar[] timestamps = new Calendar[] { new CDateTime(1000l*1310468100), new CDateTime(1000l*1310468400), new CDateTime(1000l*1310468700), +// new CDateTime(1000l*1310469000), new CDateTime(1000l*1310469300), new CDateTime(1000l*1310469600), new CDateTime(1000l*1310469900), +// new CDateTime(1000l*1310470200), new CDateTime(1000l*1310470500), new CDateTime(1000l*1310470800), new CDateTime(1000l*1310471100), +// new CDateTime(1000l*1310471400), new CDateTime(1000l*1310471700), new CDateTime(1000l*1310472000), new CDateTime(1000l*1310472300), +// new CDateTime(1000l*1310472600), new CDateTime(1000l*1310472900), new CDateTime(1000l*1310473200), new CDateTime(1000l*1310473500), +// new CDateTime(1000l*1310473800) }; +// +// Double[] values = new Double[] { 10d, 11.23d, 17.92d, 18.69d, 78.62d, 89.11d, 92.43d, 89.31d, 57.39d, 18.46d, 10.44d, 16.28d, 13.51d, 17.53d, 12.21, 20d, 21.43d, 16.45d, 14.86d, 15.27d }; +// createLineChart(section, timestamps, values, "%"); createChartLinks(section, 4); } + private void extractChartData(ServerStats stats, List<Calendar> timestamps, List<Double> data, int dataColumnIndex) { + for(ServerStatsRow row : stats.getRows()) { + Double cpuUsage = row.getUsageData().get(dataColumnIndex); + if(!cpuUsage.isNaN()) { + timestamps.add(new CDateTime(row.getTimestamp() * 1000)); + data.add(cpuUsage); + } + } + } + private void createNetworkUsageSection() { - Composite section = guiHelper.createSection(form, toolkit, "Network Usage (Aggregated)", null, 1, false); - //toolkit.createLabel(section, "Historical Network Usage graph will be displayed here."); - - Calendar[] timestamps = new Calendar[] { new CDateTime(1000l*1310468100), new CDateTime(1000l*1310468400), new CDateTime(1000l*1310468700), - new CDateTime(1000l*1310469000), new CDateTime(1000l*1310469300), new CDateTime(1000l*1310469600), new CDateTime(1000l*1310469900), - new CDateTime(1000l*1310470200), new CDateTime(1000l*1310470500), new CDateTime(1000l*1310470800), new CDateTime(1000l*1310471100), - new CDateTime(1000l*1310471400), new CDateTime(1000l*1310471700), new CDateTime(1000l*1310472000), new CDateTime(1000l*1310472300), - new CDateTime(1000l*1310472600), new CDateTime(1000l*1310472900), new CDateTime(1000l*1310473200), new CDateTime(1000l*1310473500), - new CDateTime(1000l*1310473800) }; -// Date[] timestamps = new Date[] { new Date(1310468100), new Date(1310468400), new Date(1310468700), -// new Date(1310469000), new Date(1310469300), new Date(1310469600), new Date(1310469900), -// new Date(1310470200), new Date(1310470500), new Date(1310470800), new Date(1310471100), -// new Date(1310471400), new Date(1310471700), new Date(1310472000), new Date(1310472300), -// new Date(1310472600), new Date(1310472900), new Date(1310473200), new Date(1310473500), -// new Date(1310473800) }; - Double[] values = new Double[] { 32d, 31.23d, 27.92d, 48.69d, 58.62d, 49.11d, 72.43d, 69.31d, 87.39d, 78.46d, 60.44d, 56.28d, 33.51d, 27.53d, 12.21, 10d, 21.43d, 36.45d, 34.86d, 35.27d }; - createLineChart(section, timestamps, values, "KiB/s"); - createChartLinks(section, 4); + // in case of network usage, there are three elements in usage data: received, transmitted and total. we use total. + createAreaChartSection(cluster.getAggregatedNetworkStats(), "Network Usage (Aggregated)", 2, "KiB/s"); } private void createRunningTasksSection() { diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerSummaryView.java index 498c9fe0..dfbafa70 100644 --- a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerSummaryView.java +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerSummaryView.java @@ -23,8 +23,10 @@ package com.gluster.storage.management.gui.views; import java.util.ArrayList; import java.util.List; +import org.apache.log4j.Logger; import org.eclipse.birt.chart.util.CDateTime; import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.TableViewer; @@ -46,15 +48,20 @@ import org.eclipse.ui.forms.widgets.Hyperlink; import org.eclipse.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.part.ViewPart; +import com.gluster.storage.management.client.GlusterServersClient; import com.gluster.storage.management.core.model.ClusterListener; import com.gluster.storage.management.core.model.DefaultClusterListener; import com.gluster.storage.management.core.model.Event; 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.ServerStats; +import com.gluster.storage.management.core.model.ServerStatsRow; import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.Activator; import com.gluster.storage.management.gui.GlusterDataModelManager; import com.gluster.storage.management.gui.IImageKeys; import com.gluster.storage.management.gui.NetworkInterfaceTableLabelProvider; +import com.gluster.storage.management.gui.preferences.PreferenceConstants; import com.gluster.storage.management.gui.toolbar.GlusterToolbarManager; import com.gluster.storage.management.gui.utils.ChartViewerComposite; import com.gluster.storage.management.gui.utils.GUIHelper; @@ -69,6 +76,7 @@ public class GlusterServerSummaryView extends ViewPart { private GlusterServer server; private ClusterListener serverChangedListener; private static final int CHART_WIDTH = 350; + private static final Logger logger = Logger.getLogger(GlusterServerSummaryView.class); public enum NETWORK_INTERFACE_TABLE_COLUMN_INDICES { INTERFACE, MODEL, SPEED, IP_ADDRESS, NETMASK, GATEWAY @@ -154,34 +162,55 @@ public class GlusterServerSummaryView extends ViewPart { interfaceCombo.select(0); } - - private void createCPUUsageSection() { - Composite section = guiHelper.createSection(form, toolkit, "CPU Usage", null, 1, false); - //toolkit.createLabel(section, "Historical CPU Usage graph aggregated across\nall servers will be displayed here."); + private void extractChartData(ServerStats stats, List<Calendar> timestamps, List<Double> data, int dataColumnIndex) { + for(ServerStatsRow row : stats.getRows()) { + Double cpuUsage = row.getUsageData().get(dataColumnIndex); + if(!cpuUsage.isNaN()) { + timestamps.add(new CDateTime(row.getTimestamp() * 1000)); + data.add(cpuUsage); + } + } + } - Calendar[] timestamps = new Calendar[] { new CDateTime(1000l*1310468100), new CDateTime(1000l*1310468400), new CDateTime(1000l*1310468700), - new CDateTime(1000l*1310469000), new CDateTime(1000l*1310469300), new CDateTime(1000l*1310469600), new CDateTime(1000l*1310469900), - new CDateTime(1000l*1310470200), new CDateTime(1000l*1310470500), new CDateTime(1000l*1310470800), new CDateTime(1000l*1310471100), - new CDateTime(1000l*1310471400), new CDateTime(1000l*1310471700), new CDateTime(1000l*1310472000), new CDateTime(1000l*1310472300), - new CDateTime(1000l*1310472600), new CDateTime(1000l*1310472900), new CDateTime(1000l*1310473200), new CDateTime(1000l*1310473500), - new CDateTime(1000l*1310473800) }; - //Double[] values = new Double[] { 10d, 11.23d, 17.92d, 18.69d, 78.62d, 89.11d, 92.43d, 20.31d, 19.63d, 18.46d, 10.44d, 16.28d, 13.51d, 17.53d, 12.21, 20d, 40d, 10d, 90d, 40d }; - Double[] values = new Double[] { 10d, 11.23d, 17.92d, 18.69d, 78.62d, 89.11d, 92.43d, 89.31d, 57.39d, 18.46d, 10.44d, 16.28d, 13.51d, 17.53d, 12.21, 20d, 21.43d, 16.45d, 14.86d, 15.27d }; - createLineChart(section, timestamps, values, "%"); + private void createAreaChartSection(ServerStats stats, String sectionTitle, int dataColumnIndex, String unit) { + List<Calendar> timestamps = new ArrayList<Calendar>(); + List<Double> data = new ArrayList<Double>(); + extractChartData(stats, timestamps, data, dataColumnIndex); -// ServerStats stats = new GlusterServersClient().getAggregatedCPUStats(); -// List<Calendar> timestamps = new ArrayList<Calendar>(); -// List<Double> data = new ArrayList<Double>(); -// for(ServerStatsRow row : stats.getRows()) { -// timestamps.add(new CDateTime(row.getTimestamp() * 1000)); -// // in case of CPU usage, there are three elements in usage data: user, system and total. we use total. -// data.add(row.getUsageData().get(2)); -// } + if(timestamps.size() == 0) { + // Log a message saying no CPU stats available + return; + } + + Composite section = guiHelper.createSection(form, toolkit, sectionTitle, null, 1, false); + createLineChart(section, timestamps.toArray(new Calendar[0]), data.toArray(new Double[0]), unit); + +// Calendar[] timestamps = new Calendar[] { new CDateTime(1000l*1310468100), new CDateTime(1000l*1310468400), new CDateTime(1000l*1310468700), +// new CDateTime(1000l*1310469000), new CDateTime(1000l*1310469300), new CDateTime(1000l*1310469600), new CDateTime(1000l*1310469900), +// new CDateTime(1000l*1310470200), new CDateTime(1000l*1310470500), new CDateTime(1000l*1310470800), new CDateTime(1000l*1310471100), +// new CDateTime(1000l*1310471400), new CDateTime(1000l*1310471700), new CDateTime(1000l*1310472000), new CDateTime(1000l*1310472300), +// new CDateTime(1000l*1310472600), new CDateTime(1000l*1310472900), new CDateTime(1000l*1310473200), new CDateTime(1000l*1310473500), +// new CDateTime(1000l*1310473800) }; // -// createLineChart(section, timestamps.toArray(new Calendar[0]), data.toArray(new Double[0])); +// Double[] values = new Double[] { 10d, 11.23d, 17.92d, 18.69d, 78.62d, 89.11d, 92.43d, 89.31d, 57.39d, 18.46d, 10.44d, 16.28d, 13.51d, 17.53d, 12.21, 20d, 21.43d, 16.45d, 14.86d, 15.27d }; +// createLineChart(section, timestamps, values, "%"); createChartLinks(section, 4); } + private void createCPUUsageSection() { + IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore(); + String cpuStatsPeriod = preferenceStore.getString(PreferenceConstants.P_CPU_CHART_PERIOD); + + try { + ServerStats stats = new GlusterServersClient().getCpuStats(server.getName(), cpuStatsPeriod); + // in case of CPU usage, there are three elements in usage data: user, system and total. we use total. + createAreaChartSection(stats, "CPU Usage", 2, "%"); + } catch(Exception e) { + logger.error("Couldn't fetch CPU usage statistics for server [" + server.getName() + "]", e); + return; + } + } + private Composite createChartLinks(Composite section, int columnCount) { GridLayout layout = new org.eclipse.swt.layout.GridLayout(columnCount, false); layout.marginBottom = 0; 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 31342329..8048615e 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,139 +224,25 @@ 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(String serverName : serverNames) { - 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); +} |
