cloudstack/console-proxy/src/com/cloud/consoleproxy/ConsoleProxyMonitor.java

157 lines
4.7 KiB
Java

/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.cloud.consoleproxy;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.xml.DOMConfigurator;
import com.cloud.console.Logger;
//
// This class is not currently in use, was planning to add a simulated embedded VNC server and monitor console proxy health by
// creating a fake client within the class, but this looks over-complicated and it may not be a reliable approach
//
// I switched to a simpler solution to monitor only unrecoverable exceptions, under these cases, console proxy process will exit
// itself and the shell script will re-launch console proxy
//
public class ConsoleProxyMonitor {
private static final Logger s_logger = Logger.getLogger(ConsoleProxyMonitor.class);
private String[] _argv;
private Map<String, String> _argMap = new HashMap<String, String>();
private volatile Process _process;
private boolean _quit = false;
public ConsoleProxyMonitor(String[] argv) {
_argv = argv;
for(String arg : _argv) {
String[] tokens = arg.split("=");
if(tokens.length == 2) {
s_logger.info("Add argument " + tokens[0] + "=" + tokens[1] + " to the argument map");
_argMap.put(tokens[0].trim(), tokens[1].trim());
} else {
s_logger.warn("unrecognized argument, skip adding it to argument map");
}
}
}
private void run() {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
_quit = true;
onShutdown();
}
});
while(!_quit) {
String cmdLine = getLaunchCommandLine();
s_logger.info("Launch console proxy process with command line: " + cmdLine);
try {
_process = Runtime.getRuntime().exec(cmdLine);
} catch (IOException e) {
s_logger.error("Unexpected exception ", e);
System.exit(1);
}
boolean waitSucceeded = false;
int exitCode = 0;
while(!waitSucceeded) {
try {
exitCode = _process.waitFor();
waitSucceeded = true;
if(s_logger.isInfoEnabled())
s_logger.info("Console proxy process exits with code: " + exitCode);
} catch (InterruptedException e) {
if(s_logger.isInfoEnabled())
s_logger.info("InterruptedException while waiting for termination of console proxy, will retry");
}
}
}
}
private String getLaunchCommandLine() {
StringBuffer sb = new StringBuffer("java ");
String jvmOptions = _argMap.get("jvmoptions");
if(jvmOptions != null)
sb.append(jvmOptions);
for(Map.Entry<String, String> entry : _argMap.entrySet()) {
if(!"jvmoptions".equalsIgnoreCase(entry.getKey()))
sb.append(" ").append(entry.getKey()).append("=").append(entry.getValue());
}
return sb.toString();
}
private void onShutdown() {
if(_process != null) {
if(s_logger.isInfoEnabled())
s_logger.info("Console proxy monitor shuts dwon, terminate console proxy process");
_process.destroy();
}
}
private static void configLog4j() {
URL configUrl = System.class.getResource("/conf/log4j-cloud.xml");
if(configUrl == null)
configUrl = System.class.getClassLoader().getSystemResource("log4j-cloud.xml");
if(configUrl == null)
configUrl = System.class.getClassLoader().getSystemResource("conf/log4j-cloud.xml");
if(configUrl != null) {
try {
System.out.println("Configure log4j using " + configUrl.toURI().toString());
} catch (URISyntaxException e1) {
e1.printStackTrace();
}
try {
File file = new File(configUrl.toURI());
System.out.println("Log4j configuration from : " + file.getAbsolutePath());
DOMConfigurator.configureAndWatch(file.getAbsolutePath(), 10000);
} catch (URISyntaxException e) {
System.out.println("Unable to convert log4j configuration Url to URI");
}
} else {
System.out.println("Configure log4j with default properties");
}
}
public static void main(String[] argv) {
configLog4j();
(new ConsoleProxyMonitor(argv)).run();
}
}