/* * * Copyright 2013 LinkedIn Corp. All rights reserved * * Licensed 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 com.linkedin.databus2.tools.dtail; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Arrays; import java.util.concurrent.TimeUnit; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; import org.apache.log4j.Logger; import com.linkedin.databus.core.BaseCli; import com.linkedin.databus.core.util.ConfigHelper; import com.linkedin.databus.core.util.InvalidConfigException; import com.linkedin.databus2.tools.dtail.DtailPrinter.PrintVerbosity; /** * Base class for Dtail Cli */ public class DtailCliBase extends BaseCli { public static final String DURATION_OPTION_NAME = "duration"; public static final char DURATION_OPTION_CHAR = 'u'; public static final String EVENT_NUM_OPT_NAME = "event_num"; public static final char EVENT_NUM_OPT_CHAR = 'n'; public static final String OUTPUT_FORMAT_OPT_NAME = "output_format"; public static final char OUTPUT_FORMAT_OPT_CHAR = 'F'; public static final String OUTPUT_OPT_NAME = "output"; public static final char OUTPUT_OPT_CHAR = 'o'; public static final String PRINT_VERBOSITY_OPT_NAME = "print_verbosity"; public static final char PRINT_VERBOSITY_OPT_CHAR = 'V'; public static final String RESUME_OPT_NAME = "resume"; public static final String SCN_OPT_NAME = "scn"; public static final String STATS_OPT_NAME = "stats"; public static final String VERBOSE_OPT_NAME = "verbose"; public static final char VERBOSE_OPT_CHAR = 'v'; public static enum OutputFormat { JSON, AVRO_JSON, AVRO_BIN, NOOP, EVENT_INFO } public static final String BOB_SCN_STRING = "BOB"; public static final String EOB_SCN_STRING = "EOB"; public static final long BOB_SCN = -1000; public static final long EOB_SCN = -2000; public static final OutputFormat DEFAUL_OUTPUT_FORMAT = OutputFormat.JSON; public static final PrintVerbosity DEFAULT_PRINT_VERBOSITY = PrintVerbosity.EVENT; protected String _checkpointDirName; protected long _durationMs = Long.MAX_VALUE; protected long _maxEventNum = Long.MAX_VALUE; protected OutputFormat _outputFormat = DEFAUL_OUTPUT_FORMAT; protected PrintVerbosity _printVerbosity = DEFAULT_PRINT_VERBOSITY; protected OutputStream _out = System.out; protected boolean _showStats = false; protected long _sinceScn = BOB_SCN; public DtailCliBase(BaseCli.CliHelp help, Logger log) { super(help, log); _defaultLogLevelIdx = 1; } @SuppressWarnings("static-access") @Override protected void constructCommandLineOptions() { super.constructCommandLineOptions(); Option printVerbosityOption = OptionBuilder.withLongOpt(PRINT_VERBOSITY_OPT_NAME) .hasArg() .withArgName("print_verbosity") .withDescription("print verbosity: " + Arrays.toString(PrintVerbosity.values()) + "; default: " + DEFAULT_PRINT_VERBOSITY) .create(PRINT_VERBOSITY_OPT_CHAR); Option outputFormatOption = OptionBuilder.withLongOpt(OUTPUT_FORMAT_OPT_NAME) .hasArg() .withArgName("output_format") .withDescription("output format: " + Arrays.toString(OutputFormat.values()) + "; default: " + DEFAUL_OUTPUT_FORMAT) .create(OUTPUT_FORMAT_OPT_CHAR); Option outputOption = OptionBuilder.withLongOpt(OUTPUT_OPT_NAME) .hasArg() .withArgName("output_file") .withDescription("output file or - for STDOUT") .create(OUTPUT_OPT_CHAR); Option resumeOption = OptionBuilder.withLongOpt(RESUME_OPT_NAME) .hasArg() .withArgName("checkpoint_dir") .withDescription("resumes from a previous checkpoint") .create(); Option verboseOption = OptionBuilder.withLongOpt(VERBOSE_OPT_NAME) .withDescription("verbose logging: INFO or above") .create(VERBOSE_OPT_CHAR); Option eventNumOption = OptionBuilder.withLongOpt(EVENT_NUM_OPT_NAME) .hasArg() .withArgName("num") .withDescription("max number of events to return; default: no limit") .create(EVENT_NUM_OPT_CHAR); Option durationOption = OptionBuilder.withLongOpt(DURATION_OPTION_NAME) .hasArg() .withArgName("duration_value") .withDescription("max consumption duration: value[ns|us|ms|s|min|hr|d]; default: no limit") .create(DURATION_OPTION_CHAR); Option statsOption = OptionBuilder.withLongOpt(STATS_OPT_NAME) .withDescription("print statistics at the end; Default: off") .create(); Option sinceScnOption = OptionBuilder.withLongOpt(SCN_OPT_NAME) .hasArg() .withArgName("scn") .withDescription("starts consumption from the given scn; special values: BOB for current beginning of relay buffer, " + "EOB for current end of buffer; Default: BOB") .create(); _cliOptions.addOption(eventNumOption); _cliOptions.addOption(outputFormatOption); _cliOptions.addOption(outputOption); _cliOptions.addOption(printVerbosityOption); _cliOptions.addOption(resumeOption); _cliOptions.addOption(verboseOption); _cliOptions.addOption(durationOption); _cliOptions.addOption(statsOption); _cliOptions.addOption(sinceScnOption); } @Override public boolean processCommandLineArgs(String[] cliArgs) { super.processCommandLineArgs(cliArgs); if (!processOutputFormat()) { return false; } if (!processVerbosity()) { return false; } if (!processOutput()) { return false; } processResume(); if (!processMaxEventNum()) { return false; } if (!processDuration()) { return false; } processStats(); processSinceScn(); return true; } private boolean processOutputFormat() { if (_cmd.hasOption(OUTPUT_FORMAT_OPT_CHAR)) { try { _outputFormat = OutputFormat.valueOf(_cmd.getOptionValue(OUTPUT_FORMAT_OPT_CHAR) .toUpperCase()); } catch (IllegalArgumentException e) { printError("invalid output format: " + _cmd.getOptionValue(OUTPUT_FORMAT_OPT_CHAR), true); return false; } } return true; } private boolean processVerbosity() { if (_cmd.hasOption(PRINT_VERBOSITY_OPT_CHAR)) { try { _printVerbosity = PrintVerbosity.valueOf(_cmd.getOptionValue(PRINT_VERBOSITY_OPT_CHAR) .toUpperCase()); } catch (IllegalArgumentException e) { printError("invalid print verbosity: " + _cmd.getOptionValue(PRINT_VERBOSITY_OPT_CHAR), true); return false; } } return true; } private boolean processOutput() { if (_cmd.hasOption(OUTPUT_OPT_CHAR)) { String outputStr = _cmd.getOptionValue(OUTPUT_OPT_CHAR); if (outputStr.startsWith("hdfs://")) { printError("HDFS is not supported yet", false); return false; } else if (! outputStr.equals("-")) { try { _out = new FileOutputStream(outputStr); } catch (IOException e) { printError("unable to open output: " + outputStr, false); return false; } } } return true; } private void processResume() { if (_cmd.hasOption(RESUME_OPT_NAME)) { _checkpointDirName = _cmd.getOptionValue(RESUME_OPT_NAME); } } private boolean processMaxEventNum() { if (_cmd.hasOption(EVENT_NUM_OPT_CHAR)) { try { _maxEventNum = Long.parseLong(_cmd.getOptionValue(EVENT_NUM_OPT_CHAR)); } catch (NumberFormatException e) { printError("invalid max events number: " + _cmd.getOptionValue(EVENT_NUM_OPT_CHAR), false); return false; } } return true; } private boolean processDuration() { if (_cmd.hasOption(DURATION_OPTION_CHAR)) { String durationStr = _cmd.getOptionValue(DURATION_OPTION_CHAR); _log.info("Using duration: " + durationStr); try { _durationMs = ConfigHelper.parseDuration(durationStr, TimeUnit.MILLISECONDS); } catch (InvalidConfigException e) { printError("invalid duration: " + durationStr, true); return false; } } return true; } private void processStats() { _showStats = _cmd.hasOption(STATS_OPT_NAME); } private void processSinceScn() { if (_cmd.hasOption(SCN_OPT_NAME)) { String scnOption = _cmd.getOptionValue(SCN_OPT_NAME); if (scnOption.equals(BOB_SCN_STRING)) _sinceScn = BOB_SCN; else if (scnOption.equals(EOB_SCN_STRING)) _sinceScn = EOB_SCN; else { _sinceScn = Long.parseLong(scnOption); } } _log.info("starting from SCN: " + _sinceScn); } public String getCheckpointDirName() { return _checkpointDirName; } public long getDurationMs() { return _durationMs; } public boolean isShowStats() { return _showStats; } public long getMaxEventNum() { return _maxEventNum; } public OutputFormat getOutputFormat() { return _outputFormat; } public PrintVerbosity getPrintVerbosity() { return _printVerbosity; } public OutputStream getOut() { return _out; } public long getSinceScn() { return _sinceScn; } }