diff options
author | Bernard Normier <bernard@zeroc.com> | 2014-10-01 19:41:48 -0400 |
---|---|---|
committer | Bernard Normier <bernard@zeroc.com> | 2014-10-01 19:41:48 -0400 |
commit | 8fe3c5314bcc691ab5417f23d78404daf69430ed (patch) | |
tree | bffe12a070fa68a4e9408008e4b6e7a931bca98b | |
parent | Java packages updates (diff) | |
download | ice-8fe3c5314bcc691ab5417f23d78404daf69430ed.tar.bz2 ice-8fe3c5314bcc691ab5417f23d78404daf69430ed.tar.xz ice-8fe3c5314bcc691ab5417f23d78404daf69430ed.zip |
ICE-2400: new dialog to attach Remote Logger to Registry, Node, Server and IceBox service communicator
-rw-r--r-- | java/src/IceGridGUI/Coordinator.java | 53 | ||||
-rw-r--r-- | java/src/IceGridGUI/LiveActions.java | 21 | ||||
-rw-r--r-- | java/src/IceGridGUI/LiveDeployment/Node.java | 84 | ||||
-rw-r--r-- | java/src/IceGridGUI/LiveDeployment/Root.java | 152 | ||||
-rw-r--r-- | java/src/IceGridGUI/LiveDeployment/Server.java | 70 | ||||
-rw-r--r-- | java/src/IceGridGUI/LiveDeployment/Service.java | 58 | ||||
-rw-r--r-- | java/src/IceGridGUI/LiveDeployment/ShowIceLogDialog.java | 861 | ||||
-rw-r--r-- | java/src/IceGridGUI/LiveDeployment/ShowLogFileDialog.java (renamed from java/src/IceGridGUI/LiveDeployment/ShowLogDialog.java) | 20 | ||||
-rw-r--r-- | java/src/IceGridGUI/LiveDeployment/ShowPrefsDialog.java (renamed from java/src/IceGridGUI/LiveDeployment/ShowLogPrefsDialog.java) | 95 | ||||
-rw-r--r-- | java/src/IceGridGUI/LiveDeployment/Slave.java | 2 | ||||
-rw-r--r-- | java/src/IceGridGUI/LiveDeployment/TreeNode.java | 63 | ||||
-rw-r--r-- | java/src/IceGridGUI/SessionKeeper.java | 2 |
12 files changed, 1377 insertions, 104 deletions
diff --git a/java/src/IceGridGUI/Coordinator.java b/java/src/IceGridGUI/Coordinator.java index aae3b713e02..0334838be1e 100644 --- a/java/src/IceGridGUI/Coordinator.java +++ b/java/src/IceGridGUI/Coordinator.java @@ -40,6 +40,7 @@ import com.jgoodies.forms.util.LayoutStyle; import java.security.KeyStore; import java.security.cert.Certificate; import java.security.cert.X509Certificate; + import Ice.LocatorFinderPrxHelper; import IceGrid.*; @@ -426,6 +427,7 @@ public class Coordinator _nodeMenu = new JMenu("Node"); _nodeMenu.setEnabled(false); toolsMenu.add(_nodeMenu); + _nodeMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_ICE_LOG)); _nodeMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_STDOUT)); _nodeMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_STDERR)); _nodeMenu.addSeparator(); @@ -439,6 +441,7 @@ public class Coordinator toolsMenu.add(_registryMenu); _registryMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.ADD_OBJECT)); _registryMenu.addSeparator(); + _registryMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_ICE_LOG)); _registryMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_STDOUT)); _registryMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_STDERR)); _registryMenu.addSeparator(); @@ -459,9 +462,10 @@ public class Coordinator _serverMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.PATCH_SERVER)); _serverMenu.addSeparator(); _serverMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.WRITE_MESSAGE)); + _serverMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_ICE_LOG)); _serverMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_STDOUT)); _serverMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_STDERR)); - _serverMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_LOG)); + _serverMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_LOG_FILE)); _serverMenu.addSeparator(); _signalMenu = new JMenu("Send Signal"); _serverMenu.add(_signalMenu); @@ -484,7 +488,8 @@ public class Coordinator _serviceMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.START)); _serviceMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.STOP)); _serviceMenu.addSeparator(); - _serviceMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_LOG)); + _serviceMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_ICE_LOG)); + _serviceMenu.add(_liveActionsForMenu.get(IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_LOG_FILE)); // // Help menu @@ -2574,9 +2579,14 @@ public class Coordinator return file; } - public JFileChooser getSaveLogChooser() + public JFileChooser getSaveLogFileChooser() + { + return _saveLogFileChooser; + } + + public JFileChooser getSaveIceLogChooser() { - return _saveLogChooser; + return _saveIceLogChooser; } static private Ice.Properties createProperties(Ice.StringSeqHolder args) @@ -2650,7 +2660,6 @@ public class Coordinator } _saveXMLChooser = new JFileChooser(_prefs.get("current directory", null)); - _saveXMLChooser.addChoosableFileFilter(new FileFilter() { @Override @@ -2665,10 +2674,12 @@ public class Coordinator return ".xml files"; } }); + + _openChooser = new JFileChooser(_saveXMLChooser.getCurrentDirectory()); + _openChooser.addChoosableFileFilter(_saveXMLChooser.getChoosableFileFilters()[1]); - _saveLogChooser = new JFileChooser(_prefs.get("current directory", null)); - - _saveLogChooser.addChoosableFileFilter(new FileFilter() + _saveLogFileChooser = new JFileChooser(_prefs.get("current directory", null)); + _saveLogFileChooser.addChoosableFileFilter(new FileFilter() { @Override public boolean accept(File f) @@ -2686,13 +2697,25 @@ public class Coordinator return ".out .err .log .txt files"; } }); + + _saveIceLogChooser = new JFileChooser(_prefs.get("current directory", null)); + _saveIceLogChooser.addChoosableFileFilter(new FileFilter() + { + @Override + public boolean accept(File f) + { + return f.isDirectory() || f.getName().endsWith(".csv"); + } + @Override + public String getDescription() + { + return ".cvs files"; + } + }); + javax.swing.UIManager.put("FileChooser.readOnly", Boolean.TRUE); - _openChooser = new JFileChooser(_saveXMLChooser.getCurrentDirectory()); - - _openChooser.addChoosableFileFilter(_saveXMLChooser.getChoosableFileFilters()[1]); - final int MENU_MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); // @@ -3595,7 +3618,8 @@ public class Coordinator _serverMenu.setEnabled(availableActions[IceGridGUI.LiveDeployment.TreeNode.OPEN_DEFINITION]); _serviceMenu.setEnabled(node instanceof IceGridGUI.LiveDeployment.Service && - (availableActions[IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_LOG] || + (availableActions[IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_ICE_LOG] || + availableActions[IceGridGUI.LiveDeployment.TreeNode.RETRIEVE_LOG_FILE] || availableActions[IceGridGUI.LiveDeployment.TreeNode.START] || availableActions[IceGridGUI.LiveDeployment.TreeNode.STOP])); } @@ -3998,7 +4022,8 @@ public class Coordinator private JFileChooser _openChooser; private JFileChooser _saveXMLChooser; - private JFileChooser _saveLogChooser; + private JFileChooser _saveLogFileChooser; + private JFileChooser _saveIceLogChooser; private Process _icegridadminProcess; private String _fileParser; diff --git a/java/src/IceGridGUI/LiveActions.java b/java/src/IceGridGUI/LiveActions.java index 147a5946814..dbfbc237143 100644 --- a/java/src/IceGridGUI/LiveActions.java +++ b/java/src/IceGridGUI/LiveActions.java @@ -124,6 +124,17 @@ public class LiveActions }; _array[TreeNode.WRITE_MESSAGE].putValue(Action.SHORT_DESCRIPTION, "Write message to stdout or stderr"); + + _array[TreeNode.RETRIEVE_ICE_LOG] = new AbstractAction("Retrieve Ice log") + { + @Override + public void actionPerformed(ActionEvent e) + { + _target.retrieveIceLog(); + } + }; + _array[TreeNode.RETRIEVE_ICE_LOG].putValue(Action.SHORT_DESCRIPTION, "Attach RemoteLogger to Ice logger"); + _array[TreeNode.RETRIEVE_STDOUT] = new AbstractAction("Retrieve stdout") { @@ -133,7 +144,7 @@ public class LiveActions _target.retrieveOutput(true); } }; - _array[TreeNode.RETRIEVE_STDOUT].putValue(Action.SHORT_DESCRIPTION, "Retrieve stdout"); + _array[TreeNode.RETRIEVE_STDOUT].putValue(Action.SHORT_DESCRIPTION, "Retrieve stdout if redirected to file"); _array[TreeNode.RETRIEVE_STDERR] = new AbstractAction("Retrieve stderr") { @@ -143,17 +154,17 @@ public class LiveActions _target.retrieveOutput(false); } }; - _array[TreeNode.RETRIEVE_STDERR].putValue(Action.SHORT_DESCRIPTION, "Retrieve stderr"); + _array[TreeNode.RETRIEVE_STDERR].putValue(Action.SHORT_DESCRIPTION, "Retrieve stderr if redirected to file"); - _array[TreeNode.RETRIEVE_LOG] = new AbstractAction("Retrieve Log") + _array[TreeNode.RETRIEVE_LOG_FILE] = new AbstractAction("Retrieve log file") { @Override public void actionPerformed(ActionEvent e) { - _target.retrieveLog(); + _target.retrieveLogFile(); } }; - _array[TreeNode.RETRIEVE_LOG].putValue(Action.SHORT_DESCRIPTION, "Retrieve log file from the server"); + _array[TreeNode.RETRIEVE_LOG_FILE].putValue(Action.SHORT_DESCRIPTION, "Retrieve log file"); _array[TreeNode.SHUTDOWN_NODE] = new AbstractAction("Shutdown") { diff --git a/java/src/IceGridGUI/LiveDeployment/Node.java b/java/src/IceGridGUI/LiveDeployment/Node.java index 5170055c3bc..80fe45b3435 100644 --- a/java/src/IceGridGUI/LiveDeployment/Node.java +++ b/java/src/IceGridGUI/LiveDeployment/Node.java @@ -17,6 +17,7 @@ import javax.swing.JPopupMenu; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.tree.DefaultTreeCellRenderer; + import java.text.NumberFormat; import IceGrid.*; @@ -32,15 +33,81 @@ class Node extends ListTreeNode { boolean[] actions = new boolean[IceGridGUI.LiveDeployment.TreeNode.ACTION_COUNT]; actions[SHUTDOWN_NODE] = _up; + actions[RETRIEVE_ICE_LOG] = _up; actions[RETRIEVE_STDOUT] = _up; actions[RETRIEVE_STDERR] = _up; return actions; } @Override + public void retrieveIceLog() + { + if(_showIceLogDialog == null) + { + final String prefix = "Retrieving Admin proxy for Node " + _id + "..."; + final String errorTitle = "Failed to retrieve Admin Proxy for Node " + _id; + getRoot().getCoordinator().getStatusBar().setText(prefix); + + Callback_Admin_getNodeAdmin cb = new Callback_Admin_getNodeAdmin() + { + @Override + public void response(Ice.ObjectPrx prx) + { + final Ice.LoggerAdminPrx loggerAdmin = Ice.LoggerAdminPrxHelper.uncheckedCast(prx.ice_facet("Logger")); + final String title = "Node " + _id + " Ice log"; + final String defaultFileName = "node-" + _id; + + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { + success(prefix); + if(_showIceLogDialog == null) + { + _showIceLogDialog = new ShowIceLogDialog(Node.this, title, loggerAdmin, defaultFileName, + getRoot().getLogMaxLines(), getRoot().getLogInitialLines()); + } + else + { + _showIceLogDialog.toFront(); + } + } + }); + } + + @Override + public void exception(Ice.UserException e) + { + amiFailure(prefix, errorTitle, e); + } + + @Override + public void exception(Ice.LocalException e) + { + amiFailure(prefix, errorTitle, e.toString()); + } + }; + + try + { + getRoot().getCoordinator().getSession().getAdmin().begin_getNodeAdmin(_id, cb); + } + catch(Ice.LocalException e) + { + failure(prefix, errorTitle, e.toString()); + } + } + else + { + _showIceLogDialog.toFront(); + } + } + + @Override public void retrieveOutput(final boolean stdout) { - getRoot().openShowLogDialog(new ShowLogDialog.FileIteratorFactory() + getRoot().openShowLogFileDialog(new ShowLogFileDialog.FileIteratorFactory() { @Override public FileIteratorPrx open(int count) @@ -130,6 +197,7 @@ class Node extends ListTreeNode if(_popup == null) { _popup = new JPopupMenu(); + _popup.add(la.get(RETRIEVE_ICE_LOG)); _popup.add(la.get(RETRIEVE_STDOUT)); _popup.add(la.get(RETRIEVE_STDERR)); _popup.addSeparator(); @@ -198,6 +266,13 @@ class Node extends ListTreeNode return _cellRenderer.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); } + + @Override + public void clearShowIceLogDialog() + { + _showIceLogDialog = null; + } + Node(Root parent, NodeDynamicInfo info) { @@ -565,6 +640,11 @@ class Node extends ListTreeNode _up = false; _info.servers.clear(); _info.adapters.clear(); + + if(_showIceLogDialog != null) + { + _showIceLogDialog.stop(); + } if(_children.isEmpty()) { @@ -951,6 +1031,8 @@ class Node extends ListTreeNode private boolean _up = false; private NodeDynamicInfo _info; private boolean _windows = false; + + private ShowIceLogDialog _showIceLogDialog; static private DefaultTreeCellRenderer _cellRenderer; static private Icon _nodeUp; diff --git a/java/src/IceGridGUI/LiveDeployment/Root.java b/java/src/IceGridGUI/LiveDeployment/Root.java index 3c580e3bb5a..1a2a9633b51 100644 --- a/java/src/IceGridGUI/LiveDeployment/Root.java +++ b/java/src/IceGridGUI/LiveDeployment/Root.java @@ -16,9 +16,10 @@ import javax.swing.Icon; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JTree; - +import javax.swing.SwingUtilities; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; + import java.util.prefs.Preferences; import IceGrid.*; @@ -105,8 +106,6 @@ public class Root extends ListArrayTreeNode } return child; } - - private boolean _filtered; } private boolean matchFilter(TreeNode n) @@ -151,6 +150,12 @@ public class Root extends ListArrayTreeNode { return _applicationNameFilter; } + + @Override + public void clearShowIceLogDialog() + { + _showIceLogDialog = null; + } public Root(Coordinator coordinator) { @@ -205,6 +210,7 @@ public class Root extends ListArrayTreeNode boolean[] actions = new boolean[IceGridGUI.LiveDeployment.TreeNode.ACTION_COUNT]; actions[ADD_OBJECT] = _coordinator.connectedToMaster(); actions[SHUTDOWN_REGISTRY] = true; + actions[RETRIEVE_ICE_LOG] = true; actions[RETRIEVE_STDOUT] = true; actions[RETRIEVE_STDERR] = true; return actions; @@ -341,8 +347,6 @@ public class Root extends ListArrayTreeNode public void applicationInit(String instanceName, String replicaName, java.util.List<ApplicationInfo> applications) { - closeAllShowLogDialogs(); - _instanceName = instanceName; _replicaName = replicaName; _label = instanceName + " (" + _replicaName + ")"; @@ -765,6 +769,7 @@ public class Root extends ListArrayTreeNode _popup = new JPopupMenu(); _popup.add(la.get(ADD_OBJECT)); _popup.addSeparator(); + _popup.add(la.get(RETRIEVE_ICE_LOG)); _popup.add(la.get(RETRIEVE_STDOUT)); _popup.add(la.get(RETRIEVE_STDERR)); _popup.addSeparator(); @@ -1039,9 +1044,74 @@ public class Root extends ListArrayTreeNode } @Override + public void retrieveIceLog() + { + if(_showIceLogDialog == null) + { + final String prefix = "Retrieving Admin proxy for Registry..."; + final String errorTitle = "Failed to retrieve Admin Proxy for Registry"; + _coordinator.getStatusBar().setText(prefix); + + Callback_Admin_getRegistryAdmin cb = new Callback_Admin_getRegistryAdmin() + { + @Override + public void response(Ice.ObjectPrx prx) + { + final Ice.LoggerAdminPrx loggerAdmin = Ice.LoggerAdminPrxHelper.uncheckedCast(prx.ice_facet("Logger")); + final String title = "Registry " + _label + " Ice log"; + final String defaultFileName = "registry-" + _instanceName + "-" + _replicaName; + + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { + success(prefix); + if(_showIceLogDialog == null) + { + _showIceLogDialog = new ShowIceLogDialog(Root.this, title, loggerAdmin, defaultFileName, + getLogMaxLines(), getLogInitialLines()); + } + else + { + _showIceLogDialog.toFront(); + } + } + }); + } + + @Override + public void exception(Ice.UserException e) + { + amiFailure(prefix, errorTitle, e); + } + + @Override + public void exception(Ice.LocalException e) + { + amiFailure(prefix, errorTitle, e.toString()); + } + }; + + try + { + _coordinator.getSession().getAdmin().begin_getRegistryAdmin(_replicaName, cb); + } + catch(Ice.LocalException e) + { + failure(prefix, errorTitle, e.toString()); + } + } + else + { + _showIceLogDialog.toFront(); + } + } + + @Override public void retrieveOutput(final boolean stdout) { - getRoot().openShowLogDialog(new ShowLogDialog.FileIteratorFactory() + getRoot().openShowLogFileDialog(new ShowLogFileDialog.FileIteratorFactory() { @Override public FileIteratorPrx open(int count) @@ -1080,16 +1150,26 @@ public class Root extends ListArrayTreeNode ApplicationInfo app = _infoMap.get(applicationName); return app.descriptor.propertySets.get(name); } - - void openShowLogDialog(ShowLogDialog.FileIteratorFactory factory) + + void addShowIceLogDialog(String title, ShowIceLogDialog dialog) + { + _showIceLogDialogMap.put(title, dialog); + } + + void removeShowIceLogDialog(String title) { - ShowLogDialog d = _showLogDialogMap.get(factory.getTitle()); + _showIceLogDialogMap.remove(title); + } + + void openShowLogFileDialog(ShowLogFileDialog.FileIteratorFactory factory) + { + ShowLogFileDialog d = _showLogFileDialogMap.get(factory.getTitle()); if(d == null) { - d = new ShowLogDialog(this, factory, _logMaxLines, _logMaxSize, _logInitialLines, _logMaxReadSize, + d = new ShowLogFileDialog(this, factory, _logMaxLines, _logMaxSize, _logInitialLines, _logMaxReadSize, _logPeriod); - _showLogDialogMap.put(factory.getTitle(), d); + _showLogFileDialogMap.put(factory.getTitle(), d); } else { @@ -1097,20 +1177,26 @@ public class Root extends ListArrayTreeNode } } - void removeShowLogDialog(String title) + void removeShowLogFileDialog(String title) { - _showLogDialogMap.remove(title); + _showLogFileDialogMap.remove(title); } public void closeAllShowLogDialogs() { - for(ShowLogDialog p : _showLogDialogMap.values()) + for(ShowIceLogDialog p : _showIceLogDialogMap.values()) + { + p.close(false); + } + _showIceLogDialogMap.clear(); + + for(ShowLogFileDialog p : _showLogFileDialogMap.values()) { p.close(false); } - _showLogDialogMap.clear(); + _showLogFileDialogMap.clear(); } - + public int getMessageSizeMax() { return _messageSizeMax; @@ -1126,7 +1212,25 @@ public class Root extends ListArrayTreeNode storeLogPrefs(); } - + + public void setLogPrefs(int maxLines, int initialLines) + { + _logMaxLines = maxLines; + _logInitialLines = initialLines; + + storeLogPrefs(); + } + + public int getLogMaxLines() + { + return _logMaxLines; + } + + public int getLogInitialLines() + { + return _logInitialLines; + } + private void loadLogPrefs() { Preferences logPrefs = _coordinator.getPrefs().node("Log"); @@ -1174,6 +1278,7 @@ public class Root extends ListArrayTreeNode _treeModel.nodesWereInserted(this, new int[]{_slaves.size() + i}); } + @SuppressWarnings("rawtypes") private void removeNodes(int[] toRemoveIndices, java.util.List toRemove) { if(toRemove.size() > 0) @@ -1236,17 +1341,20 @@ public class Root extends ListArrayTreeNode private ObjectDialog _showObjectDialog; // - // ShowLogDialog + // ShowLogFileDialog and ShowIceLogFileDialog // - final int _messageSizeMax; - - java.util.Map<String, ShowLogDialog> _showLogDialogMap = new java.util.HashMap<String, ShowLogDialog>(); - + private final int _messageSizeMax; + + private final java.util.Map<String, ShowIceLogDialog> _showIceLogDialogMap = new java.util.HashMap<String, ShowIceLogDialog>(); + private final java.util.Map<String, ShowLogFileDialog> _showLogFileDialogMap = new java.util.HashMap<String, ShowLogFileDialog>(); + int _logMaxLines; int _logMaxSize; int _logInitialLines; int _logMaxReadSize; int _logPeriod; + + private ShowIceLogDialog _showIceLogDialog; private ApplicationDetailsDialog _applicationDetailsDialog; diff --git a/java/src/IceGridGUI/LiveDeployment/Server.java b/java/src/IceGridGUI/LiveDeployment/Server.java index 0d1542258c0..aa1d7cfdaa8 100644 --- a/java/src/IceGridGUI/LiveDeployment/Server.java +++ b/java/src/IceGridGUI/LiveDeployment/Server.java @@ -19,6 +19,7 @@ import javax.swing.JPopupMenu; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.tree.DefaultTreeCellRenderer; + import IceGrid.*; import IceGridGUI.*; @@ -40,13 +41,13 @@ public class Server extends ListArrayTreeNode actions[STOP] = _state != ServerState.Inactive; actions[ENABLE] = !_enabled; actions[DISABLE] = _enabled; - actions[WRITE_MESSAGE] = _state != ServerState.Inactive; + actions[WRITE_MESSAGE] = _state == ServerState.Active; + actions[RETRIEVE_ICE_LOG] = _state == ServerState.Active; actions[RETRIEVE_STDOUT] = true; actions[RETRIEVE_STDERR] = true; - actions[RETRIEVE_LOG] = _serverDescriptor.logs.length > 0; + actions[RETRIEVE_LOG_FILE] = _serverDescriptor.logs.length > 0; - actions[PATCH_SERVER] = - !_serverDescriptor.distrib.icepatch.equals(""); + actions[PATCH_SERVER] = !_serverDescriptor.distrib.icepatch.equals(""); if(_state != ServerState.Inactive) { @@ -180,9 +181,33 @@ public class Server extends ListArrayTreeNode } @Override + public void retrieveIceLog() + { + if(_showIceLogDialog == null) + { + Ice.ObjectPrx serverAdmin = getServerAdmin(); + if(serverAdmin == null) + { + JOptionPane.showMessageDialog(getCoordinator().getMainFrame(), "Admin not available", + "No Admin for server " + _id, JOptionPane.ERROR_MESSAGE); + return; + } + + Ice.LoggerAdminPrx loggerAdmin = Ice.LoggerAdminPrxHelper.uncheckedCast(serverAdmin.ice_facet("Logger")); + String title = "Server " + _id + " Ice log"; + _showIceLogDialog = new ShowIceLogDialog(this, title, loggerAdmin, _id, getRoot().getLogMaxLines(), + getRoot().getLogInitialLines()); + } + else + { + _showIceLogDialog.toFront(); + } + } + + @Override public void retrieveOutput(final boolean stdout) { - getRoot().openShowLogDialog(new ShowLogDialog.FileIteratorFactory() + getRoot().openShowLogFileDialog(new ShowLogFileDialog.FileIteratorFactory() { @Override public FileIteratorPrx open(int count) @@ -217,7 +242,7 @@ public class Server extends ListArrayTreeNode } @Override - public void retrieveLog() + public void retrieveLogFile() { assert _serverDescriptor.logs.length > 0; @@ -248,7 +273,7 @@ public class Server extends ListArrayTreeNode { final String fPath = path; - getRoot().openShowLogDialog(new ShowLogDialog.FileIteratorFactory() + getRoot().openShowLogFileDialog(new ShowLogFileDialog.FileIteratorFactory() { @Override public FileIteratorPrx open(int count) @@ -598,9 +623,10 @@ public class Server extends ListArrayTreeNode _popup.add(la.get(PATCH_SERVER)); _popup.addSeparator(); _popup.add(la.get(WRITE_MESSAGE)); + _popup.add(la.get(RETRIEVE_ICE_LOG)); _popup.add(la.get(RETRIEVE_STDOUT)); _popup.add(la.get(RETRIEVE_STDERR)); - _popup.add(la.get(RETRIEVE_LOG)); + _popup.add(la.get(RETRIEVE_LOG_FILE)); _popup.addSeparator(); _signalMenu = new JMenu("Send Signal"); @@ -737,6 +763,12 @@ public class Server extends ListArrayTreeNode return _cellRenderer.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); } + @Override + public void clearShowIceLogDialog() + { + _showIceLogDialog = null; + } + Server(Node parent, String serverId, Utils.Resolver resolver, ServerInstanceDescriptor instanceDescriptor, ServerDescriptor serverDescriptor, ApplicationDescriptor application, ServerState state, int pid, boolean enabled) @@ -964,6 +996,14 @@ public class Server extends ListArrayTreeNode rebuild(this, false); } } + + if(_state == ServerState.Inactive) + { + if(_showIceLogDialog != null) + { + _showIceLogDialog.stop(); + } + } if(_serverDescriptor instanceof IceBoxDescriptor) { @@ -1094,18 +1134,12 @@ public class Server extends ListArrayTreeNode { for(Service service: _services) { + service.stopShowIceLogDialog(); service.stopped(); } } } - else if(_state == null || _state == ServerState.Inactive) - { - for(Service service: _services) - { - service.stopped(); - } - } - + if(fireEvent) { getRoot().getTreeModel().nodeChanged(this); @@ -1257,8 +1291,7 @@ public class Server extends ListArrayTreeNode if(descriptor.template.length() > 0) { - TemplateDescriptor templateDescriptor - = _application.serviceTemplates.get(descriptor.template); + TemplateDescriptor templateDescriptor = _application.serviceTemplates.get(descriptor.template); assert templateDescriptor != null; @@ -1350,6 +1383,7 @@ public class Server extends ListArrayTreeNode private boolean _metricsRetrieved = false; private IceBox.ServiceObserverPrx _serviceObserver; + private ShowIceLogDialog _showIceLogDialog; static private DefaultTreeCellRenderer _cellRenderer; static private Icon[][][] _icons; diff --git a/java/src/IceGridGUI/LiveDeployment/Service.java b/java/src/IceGridGUI/LiveDeployment/Service.java index e4c9d5e7367..6a2de665305 100644 --- a/java/src/IceGridGUI/LiveDeployment/Service.java +++ b/java/src/IceGridGUI/LiveDeployment/Service.java @@ -10,12 +10,14 @@ package IceGridGUI.LiveDeployment; import java.awt.Component; + import javax.swing.Icon; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.tree.DefaultTreeCellRenderer; + import IceGrid.*; import IceGridGUI.*; @@ -33,10 +35,11 @@ public class Service extends ListArrayTreeNode if(serverState != null) { - actions[RETRIEVE_LOG] = _serviceDescriptor.logs.length > 0; + actions[RETRIEVE_LOG_FILE] = _serviceDescriptor.logs.length > 0; } if(serverState == ServerState.Active) { + actions[RETRIEVE_ICE_LOG] = serverState == ServerState.Active; if(((Server)_parent).hasServiceObserver()) { actions[START] = !_started; @@ -163,7 +166,34 @@ public class Service extends ListArrayTreeNode } @Override - public void retrieveLog() + public void retrieveIceLog() + { + if(_showIceLogDialog == null) + { + Ice.ObjectPrx serverAdmin = ((Server)_parent).getServerAdmin(); + if(serverAdmin == null) + { + JOptionPane.showMessageDialog(getCoordinator().getMainFrame(), "Admin not available", + "No Admin for server " + _parent.getId(), JOptionPane.ERROR_MESSAGE); + return; + } + + // TODO: add support for shared communicator + + Ice.LoggerAdminPrx loggerAdmin = Ice.LoggerAdminPrxHelper.uncheckedCast( + serverAdmin.ice_facet("IceBox.Service." + _id + ".Logger")); + String title = "Service " + _parent.getId() + "/" + _id + " Ice log"; + _showIceLogDialog = new ShowIceLogDialog(this, title, loggerAdmin, _parent.getId() + "-" + _id, + getRoot().getLogMaxLines(), getRoot().getLogInitialLines()); + } + else + { + _showIceLogDialog.toFront(); + } + } + + @Override + public void retrieveLogFile() { assert _serviceDescriptor.logs.length > 0; @@ -194,7 +224,7 @@ public class Service extends ListArrayTreeNode { final String fPath = path; - getRoot().openShowLogDialog(new ShowLogDialog.FileIteratorFactory() + getRoot().openShowLogFileDialog(new ShowLogFileDialog.FileIteratorFactory() { @Override public FileIteratorPrx open(int count) @@ -274,13 +304,21 @@ public class Service extends ListArrayTreeNode _popup.add(la.get(START)); _popup.add(la.get(STOP)); _popup.addSeparator(); - _popup.add(la.get(RETRIEVE_LOG)); + _popup.add(la.get(RETRIEVE_ICE_LOG)); + _popup.add(la.get(RETRIEVE_LOG_FILE)); } la.setTarget(this); return _popup; } - + + @Override + public void clearShowIceLogDialog() + { + _showIceLogDialog = null; + } + + Service(Server parent, String serviceName, Utils.Resolver resolver, ServiceInstanceDescriptor descriptor, ServiceDescriptor serviceDescriptor, PropertySetDescriptor serverInstancePSDescriptor) { @@ -299,6 +337,14 @@ public class Service extends ListArrayTreeNode createDbEnvs(); } + void stopShowIceLogDialog() + { + if(_showIceLogDialog != null) + { + _showIceLogDialog.stop(); + } + } + boolean updateAdapter(AdapterDynamicInfo info) { for(Adapter p : _adapters) @@ -619,6 +665,8 @@ public class Service extends ListArrayTreeNode private boolean _started = false; private boolean _metricsRetrieved = false; + private ShowIceLogDialog _showIceLogDialog; + static private ServiceEditor _editor; static private DefaultTreeCellRenderer _cellRenderer; static private JPopupMenu _popup; diff --git a/java/src/IceGridGUI/LiveDeployment/ShowIceLogDialog.java b/java/src/IceGridGUI/LiveDeployment/ShowIceLogDialog.java new file mode 100644 index 00000000000..d496d1f629a --- /dev/null +++ b/java/src/IceGridGUI/LiveDeployment/ShowIceLogDialog.java @@ -0,0 +1,861 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package IceGridGUI.LiveDeployment; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; + +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ButtonGroup; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JOptionPane; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JToggleButton; +import javax.swing.JToolBar; +import javax.swing.KeyStroke; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingUtilities; +import javax.swing.table.*; +import javax.swing.WindowConstants; + +import com.jgoodies.looks.BorderStyle; +import com.jgoodies.looks.HeaderStyle; +import com.jgoodies.looks.Options; +import com.jgoodies.looks.plastic.PlasticLookAndFeel; + +import Ice.Current; +import Ice.LocalException; +import Ice.LogMessage; +import Ice.LogMessageType; +import Ice.RemoteLoggerPrxHelper; +import Ice.UserException; +import IceGridGUI.*; + +class ShowIceLogDialog extends JDialog +{ + private class MenuBar extends JMenuBar + { + private MenuBar() + { + putClientProperty(Options.HEADER_STYLE_KEY, HeaderStyle.BOTH); + putClientProperty(PlasticLookAndFeel.BORDER_STYLE_KEY, BorderStyle.SEPARATOR); + + final int MENU_MASK = java.awt.Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + + // + // File menu + // + JMenu fileMenu = new JMenu("File"); + fileMenu.setMnemonic(java.awt.event.KeyEvent.VK_F); + add(fileMenu); + + ButtonGroup bg = new ButtonGroup(); + + _pauseItem = new JRadioButtonMenuItem(_pause); + fileMenu.add(_pauseItem); + bg.add(_pauseItem); + _playItem = new JRadioButtonMenuItem(_play); + fileMenu.add(_playItem); + bg.add(_playItem); + _stopItem = new JRadioButtonMenuItem(_stop); + fileMenu.add(_stopItem); + bg.add(_stopItem); + fileMenu.addSeparator(); + + Action save = new AbstractAction("Save As...") + { + @Override + public void actionPerformed(ActionEvent e) + { + JFileChooser fileChooser = _parent.getRoot().getCoordinator().getSaveIceLogChooser(); + + fileChooser.setSelectedFile(new java.io.File(fileChooser.getCurrentDirectory(), _defaultFileName + ".csv")); + + java.io.File file = null; + + while(file == null) + { + int result = fileChooser.showSaveDialog(ShowIceLogDialog.this); + if(result == JFileChooser.APPROVE_OPTION) + { + file = fileChooser.getSelectedFile(); + + if(file != null) + { + if(!file.exists() && file.getName().indexOf('.') == -1) + { + file = new java.io.File(file.getAbsolutePath() + ".csv"); + } + + java.io.OutputStreamWriter os = null; + + try + { + os = new java.io.OutputStreamWriter(new java.io.FileOutputStream(file)); + + for(Object p : _tableModel.getDataVector()) + { + @SuppressWarnings("unchecked") + java.util.Vector<Object> row = (java.util.Vector<Object>)p; + String txt = "\"" + renderDate((java.util.Date) row.elementAt(0)) + "\"," + + renderLogMessageType((LogMessageType) row.elementAt(1)) + ",\"" + + row.elementAt(2).toString().replace("\"", "\"\"") + "\",\"" + + row.elementAt(3).toString().replace("\"", "\"\"") + "\""; + + txt += "\r\n"; + os.write(txt, 0, txt.length()); + } + } + catch(java.io.IOException io) + { + JOptionPane.showMessageDialog( + ShowIceLogDialog.this, + io.toString(), + "Cannot write file", + JOptionPane.ERROR_MESSAGE); + } + finally + { + if(os != null) + { + try + { + os.close(); + } + catch(java.io.IOException io) + { + } + } + } + } + } + else + { + break; // while + } + } + } + }; + save.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, MENU_MASK)); + save.putValue(Action.SHORT_DESCRIPTION, "Save As..."); + fileMenu.add(save); + fileMenu.addSeparator(); + + fileMenu.add(new AbstractAction("Close") + { + @Override + public void actionPerformed(ActionEvent e) + { + close(true); + } + }); + JMenu editMenu = new JMenu("Edit"); + editMenu.setMnemonic(java.awt.event.KeyEvent.VK_E); + add(editMenu); + + Action copy = new AbstractAction("Copy") + { + @Override + public void actionPerformed(ActionEvent e) + { + String txt = new String(); + for(int i : _table.getSelectedRows()) + { + int j = _table.convertRowIndexToModel(i); + + txt += renderDate((java.util.Date)_tableModel.getValueAt(j, 0)) + "\t" + + renderLogMessageType((LogMessageType)_tableModel.getValueAt(j, 1)) + "\t" + + _tableModel.getValueAt(j, 2).toString() + "\t" + + renderMessage(_tableModel.getValueAt(j, 3).toString()) + "\n"; + } + + java.awt.datatransfer.StringSelection ss = new java.awt.datatransfer.StringSelection(txt); + + java.awt.Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null); + } + + }; + copy.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C, MENU_MASK)); + copy.putValue(Action.SHORT_DESCRIPTION, "Copy"); + _table.getActionMap().put("copy", copy); + + editMenu.add(copy); + + editMenu.addSeparator(); + Action selectAll = new AbstractAction("Select All") + { + @Override + public void actionPerformed(ActionEvent e) + { + _table.grabFocus(); + _table.selectAll(); + } + }; + selectAll.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_A, MENU_MASK)); + selectAll.putValue(Action.SHORT_DESCRIPTION, "Select All"); + + editMenu.add(selectAll); + editMenu.addSeparator(); + editMenu.add(new AbstractAction("Preferences...") + { + @Override + public void actionPerformed(ActionEvent e) + { + new ShowPrefsDialog(ShowIceLogDialog.this); + } + }); + } + } + + private class ToolBar extends JToolBar + { + private ToolBar() + { + putClientProperty(Options.HEADER_STYLE_KEY, HeaderStyle.BOTH); + putClientProperty(PlasticLookAndFeel.BORDER_STYLE_KEY, BorderStyle.SEPARATOR); + setFloatable(false); + putClientProperty("JToolBar.isRollover", Boolean.TRUE); + + _pauseButton = new JToggleButton(_pause); + _pauseButton.setText(null); + _pauseButton.setIcon(Utils.getIcon("/icons/16x16/pause.png")); + add(_pauseButton); + _playButton = new JToggleButton(_play); + _playButton.setText(null); + _playButton.setIcon(Utils.getIcon("/icons/16x16/start.png")); + add(_playButton); + _stopButton = new JToggleButton(_stop); + _stopButton.setText(null); + _stopButton.setIcon(Utils.getIcon("/icons/16x16/stop.png")); + add(_stopButton); + + ButtonGroup bg = new ButtonGroup(); + bg.add(_pauseButton); + bg.add(_playButton); + bg.add(_stopButton); + } + } + + private class RemoteLoggerI extends Ice._RemoteLoggerDisp + { + @Override + public synchronized void init(String prefix, LogMessage[] logMessages, Current current) + { + // Ignore prefix + + if(!_destroyed) + { + _rowCount = logMessages.length + _queue.size() < _maxRows ? logMessages.length + _queue.size() : _maxRows; + final Object[][] data = new Object[_rowCount][]; + + int i = _rowCount - 1; + + for(java.util.Iterator<LogMessage> p = _queue.descendingIterator(); p.hasNext() && i >= 0; i--) + { + data[i] = logMessageToRow(p.next()); + } + + int j = logMessages.length - 1; + while(i >= 0 && j >= 0) + { + data[i] = logMessageToRow(logMessages[j]); + i--; + j--; + } + + _queue.clear(); + _paused = false; + + SwingUtilities.invokeLater( + new Runnable() + { + @Override + public void run() + { + _tableModel.setDataVector(data, _columnNames); + _table.scrollRectToVisible(_table.getCellRect(_table.getRowCount() - 1, 0, true)); + _pause.setEnabled(true); + } + }); + } + + } + + @Override + public synchronized void log(LogMessage message, Current current) + { + if(_destroyed) + { + // Nothing to do + } + else if(_paused) + { + _queue.addLast(message); + // We keep up to _maxRow in the queue + while(_queue.size() > _maxRows) + { + _queue.removeFirst(); + } + } + else + { + showLogMessage(message); + } + } + + private synchronized void setMaxRows(int maxRows) + { + _maxRows = maxRows; + + final int rowsToRemove = _rowCount - _maxRows; + + if(rowsToRemove > 0) + { + _rowCount -= rowsToRemove; + + SwingUtilities.invokeLater( + new Runnable() + { + @Override + public void run() + { + + int i = rowsToRemove; + while(i-- > 0) + { + _tableModel.removeRow(0); + } + } + }); + } + } + + private synchronized void pause() + { + assert(!_destroyed); + _paused = true; + } + + private synchronized void play() + { + assert(!_destroyed); + for(LogMessage p : _queue) + { + showLogMessage(p); + } + _queue.clear(); + _paused = false; + } + + private synchronized void stop() + { + assert(!_destroyed); + _destroyed = true; + } + + private void showLogMessage(LogMessage msg) + { + final Object[] row = logMessageToRow(msg); + _rowCount++; + final int rowsToRemove = _rowCount - _maxRows; + if(rowsToRemove > 0) + { + _rowCount -= rowsToRemove; + } + + SwingUtilities.invokeLater( + new Runnable() + { + @Override + public void run() + { + _tableModel.addRow(row); + int i = rowsToRemove; + while(i-- > 0) + { + _tableModel.removeRow(0); + } + _table.scrollRectToVisible(_table.getCellRect(_table.getRowCount() - 1, 0, true)); + } + }); + } + + private boolean _paused = true; + private boolean _destroyed = false; + private final java.util.Deque<LogMessage> _queue = new java.util.ArrayDeque<LogMessage>(); + private int _rowCount = 0; + private int _maxRows = _maxMessages; + } + + static private class DateRenderer extends DefaultTableCellRenderer + { + @Override + public void setValue(Object value) + { + if(value == null) + { + setText(""); + } + else + { + setText(renderDate((java.util.Date) value)); + } + } + } + + static private class LogMessageTypeRenderer extends DefaultTableCellRenderer + { + @Override + public void setValue(Object value) + { + if(value == null) + { + setText(""); + } + else + { + setText(renderLogMessageType((LogMessageType) value)); + } + } + } + + static private class MessageRenderer extends DefaultTableCellRenderer + { + @Override + public void setValue(Object value) + { + if(value == null) + { + setText(""); + } + else + { + setText(renderMessage((String)value)); + } + } + } + + ShowIceLogDialog(TreeNode parent, String title, Ice.LoggerAdminPrx loggerAdmin, String defaultFileName, int maxMessages, int initialMessages) + { + super(parent.getRoot().getCoordinator().getMainFrame(), title + " - IceGrid Admin", false); + + _parent = parent; + _title = title; + _loggerAdmin = loggerAdmin; + _defaultFileName = defaultFileName; + _maxMessages = maxMessages; + _initialMessages = initialMessages; + + setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + addWindowListener(new java.awt.event.WindowAdapter() + { + @Override + public void windowClosing(java.awt.event.WindowEvent e) + { + close(true); + } + }); + + _pause = new AbstractAction("Pause") + { + @Override + public void actionPerformed(ActionEvent e) + { + pause(); + } + }; + + _play = new AbstractAction("Play") + { + @Override + public void actionPerformed(ActionEvent e) + { + play(); + } + }; + + _stop = new AbstractAction("Stop") + { + @Override + public void actionPerformed(ActionEvent e) + { + stop(); + } + }; + + + _tableModel = new DefaultTableModel(_columnNames, 0) + { + @Override + public boolean isCellEditable(int row, int column) + { + return false; + } + }; + + _table = new JTable(_tableModel) + { + @Override + public java.awt.Component prepareRenderer(javax.swing.table.TableCellRenderer renderer, int row, int column) + { + java.awt.Component c = super.prepareRenderer(renderer, row, column); + + if (!isRowSelected(row)) + { + int modelRow = convertRowIndexToModel(row); + LogMessageType type = (LogMessageType)getModel().getValueAt(modelRow, 1); + if(type != null) + { + switch(type) + { + case ErrorMessage: + { + c.setBackground(Color.RED); + break; + } + case WarningMessage: + { + c.setBackground(Color.ORANGE); + break; + } + case PrintMessage: + { + c.setBackground(Color.LIGHT_GRAY); + break; + } + default: + { + c.setBackground(getBackground()); + break; + } + } + } + } + return c; + } + + @Override + public String getToolTipText(java.awt.event.MouseEvent e) + { + String tip = null; + java.awt.Point p = e.getPoint(); + int row = rowAtPoint(p); + int col = columnAtPoint(p); + + if(col == 3 && row >= 0) // Log message + { + Object obj = getValueAt(row, col); + if(obj != null) + { + tip = "<html>" + obj.toString().replace("\n", "<br>")+ "</html>"; + } + } + return tip; + } + + }; + + _table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); + _table.setAutoCreateColumnsFromModel(false); + + _table.getColumnModel().getColumn(0).setCellRenderer(new DateRenderer()); + _table.getColumnModel().getColumn(0).setPreferredWidth(200); + _table.getColumnModel().getColumn(0).setMaxWidth(300); + _table.getColumnModel().getColumn(1).setCellRenderer(new LogMessageTypeRenderer()); + _table.getColumnModel().getColumn(1).setPreferredWidth(75); + _table.getColumnModel().getColumn(1).setMaxWidth(100); + _table.getColumnModel().getColumn(2).setPreferredWidth(150); + _table.getColumnModel().getColumn(2).setMaxWidth(300); + _table.getColumnModel().getColumn(3).setCellRenderer(new MessageRenderer()); + + _table.getTableHeader().setReorderingAllowed(false); + + // + // Adjust row height for larger fonts + // + int fontSize = _table.getFont().getSize(); + int minRowHeight = fontSize + fontSize / 3; + if(_table.getRowHeight() < minRowHeight) + { + _table.setRowHeight(minRowHeight); + } + + _table.setRowSelectionAllowed(true); + _table.setOpaque(false); + _table.setPreferredScrollableViewportSize(new Dimension(800, 400)); + _table.setFillsViewportHeight(true); + + setJMenuBar(new MenuBar()); + getContentPane().add(new ToolBar(), BorderLayout.PAGE_START); + + JScrollPane scrollPane = new JScrollPane(_table, + ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, + ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + + getContentPane().add(scrollPane); + + pack(); + setResizable(true); + + setLocationRelativeTo(_parent.getRoot().getCoordinator().getMainFrame()); + + _parent.getRoot().addShowIceLogDialog(_title, this); + + play(); + } + + private void pause() + { + _pauseItem.setSelected(true); + _pauseButton.setSelected(true); + assert(_remoteLogger != null); + _remoteLogger.pause(); + } + + private void play() + { + if(_remoteLogger == null) + { + _tableModel.setRowCount(0); + setVisible(true); + + _playItem.setSelected(true); + _playButton.setSelected(true); + _pause.setEnabled(false); // Init will enable Pause + + String id = _loggerAdmin.ice_getIdentity().name + "-" + java.util.UUID.randomUUID().toString(); + _remoteLogger = new RemoteLoggerI(); + _remoteLoggerPrx = RemoteLoggerPrxHelper.uncheckedCast(_parent.getRoot().getCoordinator().addCallback(_remoteLogger, id, "")); + + final String prefix = "Attaching remote logger to " + _loggerAdmin.ice_getIdentity().name + "..."; + final String errorTitle = "Failed to attach remote logger to " + _loggerAdmin.ice_getIdentity().name; + _parent.getRoot().getCoordinator().getStatusBar().setText(prefix); + + Ice.Callback_LoggerAdmin_attachRemoteLogger cb = new Ice.Callback_LoggerAdmin_attachRemoteLogger() + { + @Override + public void response() + { + _parent.getRoot().amiSuccess(prefix); + } + + @Override + public void exception(final UserException ex) + { + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { + _parent.getRoot().failure(prefix, errorTitle, ex.toString()); + stop(false); + } + }); + } + + @Override + public void exception(final LocalException ex) + { + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { + _parent.getRoot().failure(prefix, errorTitle, ex.toString()); + stop(false); + } + }); + } + }; + + try + { + _loggerAdmin.begin_attachRemoteLogger(_remoteLoggerPrx, null, null, _initialMessages, cb); + } + catch(LocalException ex) + { + _parent.getRoot().failure(prefix, errorTitle, ex.toString()); + stop(false); + } + } + else + { + _remoteLogger.play(); + _pause.setEnabled(true); + } + } + + private void stop(boolean detach) + { + if(_remoteLogger != null) + { + if(detach) + { + final String prefix = "Detaching remote logger from " + _loggerAdmin.ice_getIdentity().name + "..."; + _parent.getRoot().getCoordinator().getStatusBar().setText(prefix); + + Ice.Callback_LoggerAdmin_detachRemoteLogger cb = new Ice.Callback_LoggerAdmin_detachRemoteLogger() + { + @Override + public void response(boolean detached) + { + if(detached) + { + _parent.getRoot().amiSuccess(prefix); + } + else + { + _parent.getRoot().amiSuccess(prefix, "not found"); + } + } + + @Override + public void exception(LocalException ex) + { + _parent.getRoot().amiSuccess(prefix, ex.ice_name()); + } + }; + + try + { + _loggerAdmin.begin_detachRemoteLogger(_remoteLoggerPrx, cb); + } + catch(LocalException ex) + { + _parent.getRoot().success(prefix, ex.ice_name()); + } + } + + _remoteLogger.stop(); + _parent.getRoot().getCoordinator().removeCallback(_remoteLoggerPrx.ice_getIdentity().name, ""); + + _remoteLogger = null; + _remoteLoggerPrx = null; + } + + _stopItem.setSelected(true); + _stopButton.setSelected(true); + _pause.setEnabled(false); + } + + int getMaxMessages() + { + return _maxMessages; + } + + int getInitialMessages() + { + return _initialMessages; + } + + void setPrefs(int maxMessages, int initialMessages) + { + if(maxMessages < 50) + { + maxMessages = 50; + } + _maxMessages = maxMessages; + _initialMessages = initialMessages; + + if(_remoteLogger != null) + { + _remoteLogger.setMaxRows(_maxMessages); + } + + _parent.getRoot().setLogPrefs(_maxMessages, _initialMessages); + } + + void stop() + { + stop(true); + } + + void close(boolean notifyRoot) + { + stop(); + _parent.clearShowIceLogDialog(); + if(notifyRoot) + { + _parent.getRoot().removeShowIceLogDialog(_title); + } + dispose(); + } + + private Object[] logMessageToRow(LogMessage msg) + { + Object[] row = new Object[4]; + + row[0] = new java.util.Date(msg.timestamp / 1000); + row[1] = msg.type; + row[2] = msg.traceCategory; + row[3] = msg.message; + + return row; + } + + + private final TreeNode _parent; + private final Ice.LoggerAdminPrx _loggerAdmin; + private final String _title; + private final String _defaultFileName; + + private RemoteLoggerI _remoteLogger; + private Ice.RemoteLoggerPrx _remoteLoggerPrx; + + private int _maxMessages; + private int _initialMessages; + + private Action _play; + private Action _pause; + private Action _stop; + + private JRadioButtonMenuItem _playItem; + private JRadioButtonMenuItem _pauseItem; + private JRadioButtonMenuItem _stopItem; + + private JToggleButton _playButton; + private JToggleButton _pauseButton; + private JToggleButton _stopButton; + + private final Object[] _columnNames = new Object[]{"Timestamp", "Type", "Trace Category", "Log Message"}; + private final DefaultTableModel _tableModel; + private final JTable _table; + + private static String renderDate(java.util.Date date) + { + return _dateFormat.format(date) + _timeFormat.format(date); + } + + private static String renderLogMessageType(LogMessageType type) + { + // Remove "Message" from end of string. + String s = type.toString(); + assert(s.length() > 7); + return s.substring(0, s.length() - 7); + } + + private static String renderMessage(String msg) + { + return msg.replace("\n", " "); + } + + private static final java.text.DateFormat _dateFormat = java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT); + private static final java.text.DateFormat _timeFormat = new java.text.SimpleDateFormat(" HH:mm:ss:SSS"); +} + diff --git a/java/src/IceGridGUI/LiveDeployment/ShowLogDialog.java b/java/src/IceGridGUI/LiveDeployment/ShowLogFileDialog.java index a102ebcfb2d..4ac60aa8814 100644 --- a/java/src/IceGridGUI/LiveDeployment/ShowLogDialog.java +++ b/java/src/IceGridGUI/LiveDeployment/ShowLogFileDialog.java @@ -39,7 +39,7 @@ import com.jgoodies.looks.plastic.PlasticLookAndFeel; import IceGrid.*; import IceGridGUI.*; -class ShowLogDialog extends JDialog +class ShowLogFileDialog extends JDialog { static interface FileIteratorFactory { @@ -60,7 +60,7 @@ class ShowLogDialog extends JDialog setLineWrap(true); } - public void appendLines(final String[] lines, final int maxLines, final int maxSize) + void appendLines(final String[] lines, final int maxLines, final int maxSize) { SwingUtilities.invokeLater(new Runnable() { @@ -86,7 +86,7 @@ class ShowLogDialog extends JDialog }); } - public void removeLines(int maxLines, int maxSize) + void removeLines(int maxLines, int maxSize) { javax.swing.text.Document doc = getDocument(); javax.swing.text.Element rootElt = doc.getDefaultRootElement(); @@ -145,7 +145,7 @@ class ShowLogDialog extends JDialog } JOptionPane.showMessageDialog( - ShowLogDialog.this, + ShowLogFileDialog.this, message, _factory.getTitle() + ": cannot open file", JOptionPane.ERROR_MESSAGE); @@ -405,7 +405,7 @@ class ShowLogDialog extends JDialog @Override public void actionPerformed(ActionEvent e) { - JFileChooser fileChooser = _root.getCoordinator().getSaveLogChooser(); + JFileChooser fileChooser = _root.getCoordinator().getSaveLogFileChooser(); fileChooser.setSelectedFile(new java.io.File(fileChooser.getCurrentDirectory(), _factory.getDefaultFilename())); @@ -414,7 +414,7 @@ class ShowLogDialog extends JDialog while(file == null) { - int result = fileChooser.showSaveDialog(ShowLogDialog.this); + int result = fileChooser.showSaveDialog(ShowLogFileDialog.this); if(result == JFileChooser.APPROVE_OPTION) { file = fileChooser.getSelectedFile(); @@ -441,7 +441,7 @@ class ShowLogDialog extends JDialog catch(java.io.IOException io) { JOptionPane.showMessageDialog( - ShowLogDialog.this, + ShowLogFileDialog.this, io.toString(), "Cannot write file", JOptionPane.ERROR_MESSAGE); @@ -518,7 +518,7 @@ class ShowLogDialog extends JDialog @Override public void actionPerformed(ActionEvent e) { - new ShowLogPrefsDialog(ShowLogDialog.this); + new ShowPrefsDialog(ShowLogFileDialog.this); } }); } @@ -553,7 +553,7 @@ class ShowLogDialog extends JDialog } } - ShowLogDialog(Root root, FileIteratorFactory factory, int maxLines, int maxSize, int initialLines, int maxReadSize, + ShowLogFileDialog(Root root, FileIteratorFactory factory, int maxLines, int maxSize, int initialLines, int maxReadSize, int period) { super(root.getCoordinator().getMainFrame(), factory.getTitle() + " - IceGrid Admin", false); @@ -738,7 +738,7 @@ class ShowLogDialog extends JDialog if(notifyRoot) { - _root.removeShowLogDialog(_factory.getTitle()); + _root.removeShowLogFileDialog(_factory.getTitle()); } dispose(); } diff --git a/java/src/IceGridGUI/LiveDeployment/ShowLogPrefsDialog.java b/java/src/IceGridGUI/LiveDeployment/ShowPrefsDialog.java index 1b450d5fdf2..c9d197ddf5b 100644 --- a/java/src/IceGridGUI/LiveDeployment/ShowLogPrefsDialog.java +++ b/java/src/IceGridGUI/LiveDeployment/ShowPrefsDialog.java @@ -26,31 +26,31 @@ import com.jgoodies.forms.factories.Borders; import com.jgoodies.forms.layout.FormLayout; import com.jgoodies.forms.util.LayoutStyle; -class ShowLogPrefsDialog extends JDialog +class ShowPrefsDialog extends JDialog { - ShowLogPrefsDialog(final ShowLogDialog sld) + ShowPrefsDialog(final ShowLogFileDialog dialog) { - super(sld, "Preferences - IceGrid Admin", true); + super(dialog, "Preferences - IceGrid Admin", true); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); final JTextField maxLinesField = new JTextField(10); - maxLinesField.setText(Integer.toString(sld.getMaxLines())); + maxLinesField.setText(Integer.toString(dialog.getMaxLines())); maxLinesField.setToolTipText("Maximum number of lines in this dialog's buffer"); final JTextField maxSizeField = new JTextField(10); - maxSizeField.setText(Integer.toString(sld.getMaxSize())); + maxSizeField.setText(Integer.toString(dialog.getMaxSize())); maxSizeField.setToolTipText("Maximum number of characters in this dialog's buffer"); final JTextField initialLinesField = new JTextField(10); - initialLinesField.setText(Integer.toString(sld.getInitialLines())); + initialLinesField.setText(Integer.toString(dialog.getInitialLines())); initialLinesField.setToolTipText("Start by retrieving <num> lines from the server; -1 means retrieve all"); final JTextField maxReadSizeField = new JTextField(10); - maxReadSizeField.setText(Integer.toString(sld.getMaxReadSize())); + maxReadSizeField.setText(Integer.toString(dialog.getMaxReadSize())); maxReadSizeField.setToolTipText("Maximum number of bytes read by each request"); final JTextField periodField = new JTextField(10); - periodField.setText(Float.toString((float)sld.getPeriod() / 1000)); + periodField.setText(Float.toString((float)dialog.getPeriod() / 1000)); periodField.setToolTipText("After reaching EOF, check every <num> seconds for new output"); JButton okButton = new JButton("OK"); @@ -63,11 +63,11 @@ class ShowLogPrefsDialog extends JDialog { int maxLines = parseInt(maxLinesField, "Max lines in buffer"); int maxSize = parseInt(maxSizeField, "Max characters in buffer"); - int initialLines = parseInt(initialLinesField, "Initial tail (lines)"); + int initialLines = parseInt(initialLinesField, "Number of lines retrieved initially"); int maxReadSize = parseInt(maxReadSizeField, "Max bytes read per request"); int period = (int)(parseFloat(periodField, "Poll period (seconds)") * 1000); - sld.setPrefs(maxLines, maxSize, initialLines, maxReadSize, period); + dialog.setPrefs(maxLines, maxSize, initialLines, maxReadSize, period); dispose(); } catch(NumberFormatException ex) @@ -100,7 +100,7 @@ class ShowLogPrefsDialog extends JDialog builder.nextLine(); builder.append("Max characters in buffer", maxSizeField); builder.nextLine(); - builder.append("Initial tail (lines)", initialLinesField); + builder.append("Number of lines retrieved initially", initialLinesField); builder.nextLine(); builder.append("Max bytes read per request", maxReadSizeField); builder.nextLine(); @@ -117,7 +117,78 @@ class ShowLogPrefsDialog extends JDialog pack(); setResizable(false); - setLocationRelativeTo(sld); + setLocationRelativeTo(dialog); + setVisible(true); + } + + ShowPrefsDialog(final ShowIceLogDialog dialog) + { + super(dialog, "Preferences - IceGrid Admin", true); + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + + final JTextField maxMessagesField = new JTextField(10); + maxMessagesField.setText(Integer.toString(dialog.getMaxMessages())); + maxMessagesField.setToolTipText("Maximum number of log messages to keep in this dialog's buffer"); + + final JTextField initialMessagesField = new JTextField(10); + initialMessagesField.setText(Integer.toString(dialog.getInitialMessages())); + initialMessagesField.setToolTipText("Start by retrieving <num> log messages from the server; -1 means retrieve all"); + + JButton okButton = new JButton("OK"); + ActionListener okListener = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + try + { + int maxMessages = parseInt(maxMessagesField, "Max log messages in buffer"); + int initialMessages = parseInt(initialMessagesField, "Number of log messages retrieved initially"); + dialog.setPrefs(maxMessages, initialMessages); + dispose(); + } + catch(NumberFormatException ex) + { + return; + } + } + }; + okButton.addActionListener(okListener); + getRootPane().setDefaultButton(okButton); + + JButton cancelButton = new JButton("Cancel"); + ActionListener cancelListener = new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + dispose(); + } + }; + cancelButton.addActionListener(cancelListener); + + FormLayout layout = new FormLayout("left:pref, 3dlu, fill:pref:grow", ""); + DefaultFormBuilder builder = new DefaultFormBuilder(layout); + builder.border(Borders.DIALOG); + builder.rowGroupingEnabled(true); + builder.lineGapSize(LayoutStyle.getCurrent().getLinePad()); + + builder.append("Max log messages in buffer", maxMessagesField); + builder.nextLine(); + builder.append("Number of log messages retrieved initially", initialMessagesField); + builder.nextLine(); + + JComponent buttonBar = new ButtonBarBuilder().addGlue().addButton(okButton, cancelButton).build(); + buttonBar.setBorder(Borders.DIALOG); + + java.awt.Container contentPane = getContentPane(); + contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS)); + contentPane.add(builder.getPanel()); + contentPane.add(buttonBar); + + pack(); + setResizable(false); + setLocationRelativeTo(dialog); setVisible(true); } diff --git a/java/src/IceGridGUI/LiveDeployment/Slave.java b/java/src/IceGridGUI/LiveDeployment/Slave.java index 652775efbb5..75d4158f5b3 100644 --- a/java/src/IceGridGUI/LiveDeployment/Slave.java +++ b/java/src/IceGridGUI/LiveDeployment/Slave.java @@ -83,7 +83,7 @@ class Slave extends TreeNode @Override public void retrieveOutput(final boolean stdout) { - getRoot().openShowLogDialog(new ShowLogDialog.FileIteratorFactory() + getRoot().openShowLogFileDialog(new ShowLogFileDialog.FileIteratorFactory() { @Override public FileIteratorPrx open(int count) diff --git a/java/src/IceGridGUI/LiveDeployment/TreeNode.java b/java/src/IceGridGUI/LiveDeployment/TreeNode.java index 43a477268a1..be37680715c 100644 --- a/java/src/IceGridGUI/LiveDeployment/TreeNode.java +++ b/java/src/IceGridGUI/LiveDeployment/TreeNode.java @@ -47,23 +47,25 @@ public abstract class TreeNode extends TreeNodeBase public static final int WRITE_MESSAGE = 11; - public static final int RETRIEVE_STDOUT = 12; - public static final int RETRIEVE_STDERR = 13; - public static final int RETRIEVE_LOG = 14; + public static final int RETRIEVE_ICE_LOG = 12; + public static final int RETRIEVE_STDOUT = 13; + public static final int RETRIEVE_STDERR = 14; + public static final int RETRIEVE_LOG_FILE = 15; + - public static final int SHUTDOWN_NODE = 15; - public static final int SHUTDOWN_REGISTRY = 16; + public static final int SHUTDOWN_NODE = 16; + public static final int SHUTDOWN_REGISTRY = 17; - public static final int PATCH_SERVER = 17; + public static final int PATCH_SERVER = 18; - public static final int ADD_OBJECT = 18; + public static final int ADD_OBJECT = 19; - public static final int OPEN_DEFINITION = 19; + public static final int OPEN_DEFINITION = 20; - static public final int ENABLE_METRICS_VIEW = 20; - static public final int DISABLE_METRICS_VIEW = 21; + public static final int ENABLE_METRICS_VIEW = 21; + public static final int DISABLE_METRICS_VIEW = 22; - static public final int ACTION_COUNT = 22; + public static final int ACTION_COUNT = 23; public boolean[] getAvailableActions() { @@ -90,11 +92,15 @@ public abstract class TreeNode extends TreeNodeBase { assert false; } + public void retrieveIceLog() + { + assert false; + } public void retrieveOutput(boolean stdout) { assert false; } - public void retrieveLog() + public void retrieveLogFile() { assert false; } @@ -127,6 +133,11 @@ public abstract class TreeNode extends TreeNodeBase { assert false; } + + public void clearShowIceLogDialog() + { + assert false; + } // // Helpers @@ -138,7 +149,19 @@ public abstract class TreeNode extends TreeNodeBase @Override public void run() { - getCoordinator().getStatusBar().setText(prefix + "done."); + success(prefix); + } + }); + } + + protected void amiSuccess(final String prefix, final String detail) + { + SwingUtilities.invokeLater(new Runnable() + { + @Override + public void run() + { + success(prefix, detail); } }); } @@ -211,7 +234,7 @@ public abstract class TreeNode extends TreeNodeBase protected void failure(String prefix, String title, String message) { - getCoordinator().getStatusBar().setText(prefix + "failed!"); + getCoordinator().getStatusBar().setText(prefix + " failed!"); JOptionPane.showMessageDialog( getCoordinator().getMainFrame(), @@ -219,7 +242,17 @@ public abstract class TreeNode extends TreeNodeBase title, JOptionPane.ERROR_MESSAGE); } - + + protected void success(String prefix, String detail) + { + getCoordinator().getStatusBar().setText(prefix + " done (" + detail + ")."); + } + + protected void success(String prefix) + { + getCoordinator().getStatusBar().setText(prefix + " done."); + } + void reparent(TreeNode newParent) { assert newParent != null; diff --git a/java/src/IceGridGUI/SessionKeeper.java b/java/src/IceGridGUI/SessionKeeper.java index 90f180aa813..9308b78ba01 100644 --- a/java/src/IceGridGUI/SessionKeeper.java +++ b/java/src/IceGridGUI/SessionKeeper.java @@ -407,7 +407,7 @@ public class SessionKeeper Ice.Object removeCallback(String name, String facet) { - if(_adminCallbackCategory == null) + if(_adminCallbackCategory == null || _adapter == null) { return null; } |