blob: e7496ae1d6d2956091edec7dd6e516cd251942fc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.ode.utils.cli;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.appender.FileAppender;
import org.apache.logging.log4j.core.config.AppenderRef;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.ode.utils.Version;
import org.apache.ode.utils.fs.TempFileManager;
import org.apache.ode.utils.msg.MessageBundle;
import org.slf4j.Logger;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
public abstract class BaseCommandlineTool {
public static final int TERSE = 0;
public static final int VERBOSE = 1;
public static final int EFFUSIVE = 2;
private static boolean _tempFileManagerRegistered = false;
private static Class CLAZZ = BaseCommandlineTool.class;
private static final String LOGGING_PATTERN = "%p - %d{ISO8601} - <%c> %m%n";
protected static final Flag HELP_FLAG = new Flag("h", "print usage and help to the console and exit.", false);
protected static final Fragments HELP = new Fragments(new CommandlineFragment[] { HELP_FLAG });
protected static final Flag QUIET_F = new Flag("q", "only produce error output in the event of an error.", false);
protected static final Flag VERBOSE_F = new Flag("v", "produce verbose (INFO-level) logging output.", false);
protected static final Flag VERYVERBOSE_F = new Flag("vv", "product effusive (DEBUG-level) logging output", false);
protected static final XorGroup LOGGING = new XorGroup(
"set logging output verbosity from quiet (-q), to verbose (-v), to effusive (-vv).", true);
static {
LOGGING.addFragment(QUIET_F);
LOGGING.addFragment(VERBOSE_F);
LOGGING.addFragment(VERYVERBOSE_F);
}
private static final CommandLineMessages __msgs = MessageBundle.getMessages(CommandLineMessages.class);
/**
* Print program banner.
*/
public static void outputHeader() {
if (QUIET_F.isSet()) {
return;
}
System.out.println(__msgs.msgCliHeader(getProgramName(), Version.getVersionName(), Version.getBuildDate()));
}
/**
* Initialize logging appropriate for command-line utilities. The logging
* will be limited to error messages on standard error, unless
* user-specified logging options are present. Among other things, this
* method looks for the <code>-v</code> option and configures logging
* verbosity appropriately
*
* @param level
*/
protected static void initLogging(int level) {
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
Layout layout = PatternLayout.createLayout(LOGGING_PATTERN,config,null,Charset.forName("UTF-8"),true,false,null,null);
Appender appender = ConsoleAppender.createAppender(layout, null, "SYSTEM_OUT", "stderr appender", "false", "true");
AppenderRef ref = initialize("stderr appender", level);
AppenderRef[] refs = new AppenderRef[] {ref};
loggerConfig.addAppender(appender, ref.getLevel(), null);
loggerConfig.setLevel(ref.getLevel());
ctx.updateLoggers();
}
protected static void initLogFile() throws IOException {
initLogFile(getLevel());
}
protected static void initLogFile(int level) throws IOException {
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
Layout layout = PatternLayout.createLayout(LOGGING_PATTERN,config,null,Charset.forName("UTF-8"),true,false,null,null);
Appender appender = FileAppender.createAppender(System.getProperty("ode.home") + "/logs/ode.log", "false", "false", "File", "false",
"true", "true", "8192", layout, null, "false", null, config);
AppenderRef ref = initialize("File", level);
AppenderRef[] refs = new AppenderRef[] {ref};
loggerConfig.addAppender(appender, ref.getLevel(), null);
loggerConfig.setLevel(ref.getLevel());
ctx.updateLoggers();
}
private static AppenderRef initialize(String name, int level) {
Level appenderLevel = null;
switch (level) {
case EFFUSIVE :
appenderLevel = Level.DEBUG;
break;
case VERBOSE :
appenderLevel = Level.INFO;
break;
default :
appenderLevel = Level.WARN;
break;
}
return AppenderRef.createAppenderRef(name, appenderLevel, null);
}
protected static void setClazz(Class c) {
CLAZZ = c;
}
protected static String getProgramName() {
return "java " + CLAZZ.getName();
}
protected static void initLogging() {
initLogging(getLevel());
}
private static int getLevel() {
if (QUIET_F.isSet()) {
return TERSE;
} else if (VERBOSE_F.isSet()) {
return VERBOSE;
} else if (VERYVERBOSE_F.isSet()) {
return EFFUSIVE;
} else {
// none of the above.
return -1;
}
}
protected synchronized static final void registerTempFileManager() {
if (!_tempFileManagerRegistered) {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
TempFileManager.cleanup();
}
});
}
}
protected static void consoleErr(String errMsg) {
String progName = getProgramName();
System.err.println(progName + ": " + errMsg);
}
}