gatk-3.8/java/src/org/broadinstitute/sting/utils/cmdLine/CommandLineProgram.java

247 lines
8.0 KiB
Java
Raw Normal View History

package org.broadinstitute.sting.utils.cmdLine;
import org.apache.log4j.*;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/**
* User: aaron
* Date: Mar 19, 2009
* Time: 3:54:56 PM
* <p/>
* The Broad Institute
* SOFTWARE COPYRIGHT NOTICE AGREEMENT
* This software and its documentation are copyright 2009 by the
* Broad Institute/Massachusetts Institute of Technology. All rights are reserved.
* <p/>
* This software is supplied without any warranty or guaranteed support whatsoever. Neither
* the Broad Institute nor MIT can be responsible for its use, misuse, or functionality.
* <p/>
* <p/>
* This class is our implementation of the command line parser, similar to Pickard's. We instead
* support GNU style command line arguements, and use this class to setup the global parser.
*/
public abstract class CommandLineProgram {
/**
* Our Argument parser, which handles parsing the command line in GNU format
*/
protected ArgumentParser m_parser;
/**
* our log, which we want to capture anything from org.broadinstitute.sting
*/
private static Logger logger = Logger.getRootLogger();// .getLogger(CommandLineProgram.class);
/**
* the default log level
*/
public String logging_level = "ERROR";
/**
* where to send the output of our logger
*/
public String toFile = null;
/**
* do we want to silence the command line output
*/
public Boolean quietMode = false;
/**
* do we want to generate debugging information with the logs
*/
public Boolean debugMode = false;
/**
* our logging output patterns
*/
private static String patternString = "%p %m %n";
private static String debugPatternString = "%n[level] %p%n[date]\t\t %d{dd MMM yyyy HH:mm:ss,SSS} %n[class]\t\t %C %n[location]\t %l %n[line number]\t %L %n[message]\t %m %n";
/**
* the contract for the inheriting class is that they have a setupArgs()
* function which sets up the args to the specific program.
*/
protected abstract void setupArgs();
/**
* this is the function that the inheriting class can expect to have called
* when all the argument processing is done
*
* @return the return code to exit the program with
*/
protected abstract int execute();
/**
* this is used to indicate if they've asked for help
*/
public Boolean help = false;
/**
* This function is called to start processing the command line, and kick
* off the execute message of the program.
*
* @param clp the command line program to execute
* @param args the command line arguments passed in
*/
public static void start(CommandLineProgram clp, String[] args) {
try {
// setup a basic log configuration
BasicConfigurator.configure();
// setup our log layout
PatternLayout layout = new PatternLayout();
// setup the parser
clp.m_parser = new ArgumentParser(clp.getClass().getName(), clp);
// setup the default help and logging args controlled by the base class
clp.setupDefaultArgs();
// setup the args
clp.setupArgs();
// process the args
clp.m_parser.processArgs(args);
// if we're in debug mode, set the mode up
if (clp.debugMode) {
//logger.info("Setting debug");
layout.setConversionPattern(debugPatternString);
} else {
//logger.info("not Setting debug");
layout.setConversionPattern(patternString);
}
// if they set the mode to quiet
if (clp.quietMode) {
// the only appender we should have is stdout, the following meathod is
// deprecated, but the standard remove all appenders doesn't seem to work
// TODO: find the right function
//Category root = Category.getRoot();
//root.removeAllAppenders();
//logger.removeAllAppenders();
}
// they asked for help, give it to them
if (clp.help) {
clp.m_parser.printHelp();
System.exit(1);
}
// if they specify a log location, output our data there
if (clp.toFile != null) {
FileAppender appender = null;
try {
appender = new FileAppender(layout, clp.toFile, false);
logger.addAppender(appender);
} catch (IOException e) {
throw new RuntimeException("Unable to re-route log output to " + clp.toFile + " make sure the destination exists");
}
}
// regardless of what happens next, generate the header information
generateHeaderInformation(clp, args);
// set the default logger level
clp.setupLoggerLevel();
// call the execute
int result = clp.execute();
// return the result
System.exit(result);
}
catch (Exception e) {
// we catch all exceptions here. if it makes it to this level, we're in trouble. Let's bail!
// TODO: what if the logger is the exception? hmm...
logger.fatal("Exception caught by base Command Line Program, with message: " + e.getMessage());
logger.fatal("with cause: " + e.getCause());
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
/**
* generateHeaderInformation
* <p/>
*
* Generate a standard header for the logger
* @param clp the command line program to execute
* @param args the command line arguments passed in
*
**/
protected static void generateHeaderInformation(CommandLineProgram clp, String[] args) {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
java.util.Date date = new java.util.Date();
logger.info("-------------------------------------------------------");
logger.info("Program Name: " + clp.getClass().getName());
String output = "";
for (String str : args) {
output = output + str + " ";
}
logger.info("Program Args: " + output);
logger.info("Time/Date: " + dateFormat.format(date));
logger.info("-------------------------------------------------------");
}
/**
* this function checks the logger level passed in on the command line, taking the lowest
* level that was provided.
*/
private void setupLoggerLevel() {
Level par = Level.ERROR;
if (logging_level.equals("DEBUG")) {
par = Level.DEBUG;
}
if (logging_level.equals("ERROR")) {
par = Level.ERROR;
}
if (logging_level.equals("FATAL")) {
par = Level.FATAL;
}
if (logging_level.equals("INFO")) {
par = Level.INFO;
}
if (logging_level.equals("WARN")) {
par = Level.WARN;
}
if (logging_level.equals("OFF")) {
par = Level.OFF;
}
logger.setLevel(par);
}
/**
* we have some default options that should always get checked for in the
* arguments provided to the program
*/
private void setupDefaultArgs() {
m_parser.addOptionalFlag("help", "h", "Generate this help message", "help");
m_parser.addOptionalArg("logging_level", "l", "Set the logging level", "logging_level");
m_parser.addOptionalArg("log_to_file", "log", "Set the logging location", "toFile");
m_parser.addOptionalFlag("quiet_output_mode", "quiet", "Set the logging to quiet mode, no output to stdout", "quietMode");
m_parser.addOptionalFlag("debug_mode", "debug", "Set the logging file string to include a lot of debugging information (SLOW!)", "debugMode");
}
}