partial work for --args

This commit is contained in:
Jonathan Shook 2020-10-23 02:35:54 -05:00
parent 262df57101
commit 3fa89ebc14
4 changed files with 244 additions and 17 deletions

View File

@ -0,0 +1,86 @@
# Args Files
An argsfile (Command Line Arguments File) is a simple text file which
contains defaults for command-line arguments. You can use an args
file to contain a set of global defaults that you want to use by
default and automatically.
A command, `-argsfile <path>` is used to specify an args file. You can
use it like an instant import statement in the middle of a command
line. Notice that this option uses only a single dash. This
distinguishes the argsfile options from the others in general. These are meta
options which can modify how options are loaded, so it is important
that the look distinctive from everything else.
## Default argsfile
The default args file location is `$HOME/.nosqlbench/argsfile`. If this
file is present, it is loaded by nosqlbench when it starts even if you
don't ask it to. That is, nosqlbench behaves as if your first set of
command line arguments is `-argsfile "$HOME/.nosqlbench/argsfile
`. However, unlike when you specify `-argsfile ...` explicitly on
your command line, this form will not throw an error if the file is
missing. This means that when you explicitly ask for an args file
to be loaded, and it does not exist, an error is thrown. If you
don't ask for it, but the default one does exist, it is loaded
automatically before other options are processed.
## Args file format
An args file simply contains an argument on each line, like this:
--docker-metrics
--annotate all
--grafana-baseurl http://localhost:3000/
## Pinning options
It is possible to pin an option to the default args file by use of the
`-pin` meta-option. This option will take the following command line
argument and add it to the currently active args file. That means, if
you use `-pin --docker-metrics`, then `--docker-metrics` is added to
the args file. If there is an exact duplicate of the same option
and value, then it is skipped, but if the option name is the same
with a different value, then it is added at the end. This allows
for options which may be called multiple times normally.
If the `-pin` option occurs after an explicit use of `-argsfile
<filename>`, then the filename used in this argument is the one that
is modified.
After the `-pin` option, the following argument is taken as any global
option (--with-double-dashes) and any non-option values after it which
are not commands (reserved words)
When the `-pin` option is used, it does not cause the pinned option
to be excluded from the current command line call. The effects of the
pinned option will take place in the current nosqlbench invocation
just as they would without the `-pin`. However, when pinning global
options when there are no commands on the command line, nosqlbench
will not run a scenario, so this form is suitable for setting
arguments.
As a special case, if the `-pin` is the last option of
## Unpinning options.
To reverse the effect of pinning an option, you simply use
`-unpin ...`.
The behavior of -unpin is slightly different than -pin. Specifically,
an option which is unpinned will be removed from the arg list, and will
not be used in the current invocation of nosqlbench after removal.
Further, you can specify `-unpin --grafana-baseurl` to unpin an option which
normally has an argument, and all instances of that argument will be
removed. If you want to unpin a specific instance of a multi-valued
option, or one that can be specified more than once with different
parameter values, then you must provide the value as well, as in
`-unpin --log-histograms 'histodata.log:.*:1m'`
# Setting defaults, the simple way
To simply set global defaults, you can run nosqlbench with a command
line like this:
./nb -pin --docker-metrics-at metricsnode -pin --annotate all

View File

@ -0,0 +1,56 @@
package io.nosqlbench.engine.cli;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ArgsFile {
private final Path argsPath;
public ArgsFile(String path) {
this.argsPath = Path.of(path);
}
public LinkedList<String> doArgsFile(String argsfileSpec, LinkedList<String> arglist) {
return null;
}
private LinkedList<String> spliceArgs(String argsfileSpec, LinkedList<String> arglist) {
Pattern envpattern = Pattern.compile("(?<envvar>\\$[A-Za-z_]+)");
Matcher matcher = envpattern.matcher(argsfileSpec);
StringBuilder sb = new StringBuilder();
while (matcher.find()) {
String envvar = matcher.group("envvar");
String value = System.getenv(envvar);
if (value == null) {
throw new RuntimeException("Env var '" + envvar + "' was not found in the environment.");
}
matcher.appendReplacement(sb, value);
}
matcher.appendTail(sb);
Path argfilePath = Path.of(sb.toString());
List<String> lines = null;
try {
lines = Files.readAllLines(argfilePath);
} catch (IOException e) {
throw new RuntimeException(e);
}
// TODO: finish update logic here
return arglist;
}
public LinkedList<String> pin(LinkedList<String> arglist) {
return arglist;
}
public LinkedList<String> unpin(LinkedList<String> arglist) {
return arglist;
}
}

View File

@ -9,12 +9,15 @@ import io.nosqlbench.engine.api.activityapi.input.InputType;
import io.nosqlbench.engine.api.activityapi.output.OutputType;
import io.nosqlbench.engine.api.metrics.ActivityMetrics;
import io.nosqlbench.engine.core.*;
import io.nosqlbench.engine.core.annotation.Annotators;
import io.nosqlbench.engine.core.metrics.GrafanaMetricsAnnotator;
import io.nosqlbench.engine.core.metrics.MetricReporters;
import io.nosqlbench.engine.core.script.MetricsMapper;
import io.nosqlbench.engine.core.script.Scenario;
import io.nosqlbench.engine.core.script.ScenariosExecutor;
import io.nosqlbench.engine.core.script.ScriptParams;
import io.nosqlbench.engine.docker.DockerMetricsManager;
import io.nosqlbench.nb.api.annotation.Annotator;
import io.nosqlbench.nb.api.content.Content;
import io.nosqlbench.nb.api.content.NBIO;
import io.nosqlbench.nb.api.errors.BasicError;
@ -30,17 +33,17 @@ import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.*;
import java.util.concurrent.locks.LockSupport;
import java.util.stream.Collectors;
public class NBCLI {
private static final Logger logger = LoggerFactory.getLogger(NBCLI.class);
private static final Logger EVENTS = LoggerFactory.getLogger("EVENTS");
private static final String CHART_HDR_LOG_NAME = "hdrdata-for-chart.log";
private final String commandName;
public NBCLI(String commandName) {
@ -52,8 +55,8 @@ public class NBCLI {
NBCLI cli = new NBCLI("eb");
cli.run(args);
} catch (Exception e) {
String error = ScenarioErrorHandler.handle(e,true);
if (error!=null) {
String error = ScenarioErrorHandler.handle(e, true);
if (error != null) {
System.err.println(error);
}
System.err.flush();
@ -64,8 +67,7 @@ public class NBCLI {
public void run(String[] args) {
NBCLIOptions globalOptions = new NBCLIOptions(args,NBCLIOptions.Mode.ParseGlobalsOnly);
NBCLIOptions globalOptions = new NBCLIOptions(args, NBCLIOptions.Mode.ParseGlobalsOnly);
// Global only processing
@ -84,13 +86,20 @@ public class NBCLI {
logger.warn(warn);
if (reportGraphiteTo != null) {
logger.warn(String.format("Docker metrics are enabled (--docker-metrics)" +
" but graphite reporting (--report-graphite-to) is set to %s \n" +
"usually only one of the two is configured.",
reportGraphiteTo));
" but graphite reporting (--report-graphite-to) is set to %s \n" +
"usually only one of the two is configured.",
reportGraphiteTo));
} else {
logger.info("Setting graphite reporting to localhost");
reportGraphiteTo = "localhost:9109";
}
if (globalOptions.getAnnotatorsConfig() != null) {
logger.warn("Docker metrics and separate annotations" +
"are configured (both --docker-metrics and --annotations).");
} else {
Annotators.init("grafana{http://localhost:3000/}");
}
}
if (args.length > 0 && args[0].toLowerCase().equals("virtdata")) {
@ -109,8 +118,14 @@ public class NBCLI {
NBCLIOptions options = new NBCLIOptions(args);
NBIO.addGlobalIncludes(options.wantsIncludes());
String sessionName = new SessionNamer().format(options.getSessionName());
ConsoleLogging.enableConsoleLogging(options.wantsConsoleLogLevel(), options.getConsoleLoggingPattern());
Annotators.init(options.getAnnotatorsConfig());
Annotators.recordAnnotation(sessionName, 0L, 0L,
Map.of(), Map.of());
ActivityMetrics.setHdrDigits(options.getHdrDigits());
if (options.wantsBasicHelp()) {
@ -228,7 +243,10 @@ public class NBCLI {
reporters.start(10, options.getReportInterval());
}
String sessionName = new SessionNamer().format(options.getSessionName());
Annotators.recordAnnotation(sessionName,
Map.of("event", "command-line", "args", String.join(" ", args)),
Map.of()
);
if (options.wantsEnableChart()) {
logger.info("Charting enabled");
@ -241,20 +259,25 @@ public class NBCLI {
}
}
for (NBCLIOptions.LoggerConfig histoLogger : options.getHistoLoggerConfigs()) {
for (
NBCLIOptions.LoggerConfig histoLogger : options.getHistoLoggerConfigs()) {
ActivityMetrics.addHistoLogger(sessionName, histoLogger.pattern, histoLogger.file, histoLogger.interval);
}
for (NBCLIOptions.LoggerConfig statsLogger : options.getStatsLoggerConfigs()) {
for (
NBCLIOptions.LoggerConfig statsLogger : options.getStatsLoggerConfigs()) {
ActivityMetrics.addStatsLogger(sessionName, statsLogger.pattern, statsLogger.file, statsLogger.interval);
}
for (NBCLIOptions.LoggerConfig classicConfigs : options.getClassicHistoConfigs()) {
for (
NBCLIOptions.LoggerConfig classicConfigs : options.getClassicHistoConfigs()) {
ActivityMetrics.addClassicHistos(sessionName, classicConfigs.pattern, classicConfigs.file, classicConfigs.interval);
}
// intentionally not shown for warn-only
logger.info("console logging level is " + options.wantsConsoleLogLevel());
if (options.getCommands().size() == 0) {
if (options.getCommands().
size() == 0) {
System.out.println(loadHelpFile("commandline.md"));
System.exit(0);
}
@ -295,6 +318,7 @@ public class NBCLI {
if (scenarioLogLevel.toInt() > consoleLogLevel.toInt()) {
logger.info("raising scenario logging level to accommodate console logging level");
}
Level maxLevel = Level.toLevel(Math.min(consoleLogLevel.toInt(), scenarioLogLevel.toInt()));
scenario.addScriptText(scriptData);
@ -330,13 +354,14 @@ public class NBCLI {
if (scenariosResults.hasError()) {
Exception exception = scenariosResults.getOne().getException().get();
// logger.warn(scenariosResults.getExecutionSummary());
ScenarioErrorHandler.handle(exception,options.wantsStackTraces());
ScenarioErrorHandler.handle(exception, options.wantsStackTraces());
System.err.println(exception.getMessage()); // TODO: make this consistent with ConsoleLogging sequencing
System.exit(2);
} else {
logger.info(scenariosResults.getExecutionSummary());
System.exit(0);
}
}
private String loadHelpFile(String filename) {

View File

@ -8,6 +8,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.nio.file.Path;
import java.security.InvalidParameterException;
import java.util.*;
import java.util.stream.Collectors;
@ -18,13 +19,27 @@ import java.util.stream.Collectors;
*/
public class NBCLIOptions {
private final static String userHome = System.getProperty("user.home");
private final static Path defaultOptFile = Path.of(userHome, ".nosqlbench/options");
private final static Logger logger = LoggerFactory.getLogger(NBCLIOptions.class);
// Options which may contextualize other CLI options or commands.
// These must be parsed first
private static final String ARGS_FILE = "-argsfile";
private static final String ARGS_FILE_DEFAULT = "$HOME/.nosqlbench/argsfile";
private static final String ARGS_PIN = "-pin";
private static final String ARGS_UNPIN = "-unpin";
private static final String INCLUDE = "--include";
private static final String METRICS_PREFIX = "--metrics-prefix";
// private static final String ANNOTATE_TO_GRAFANA = "--grafana-baseurl";
private static final String ANNOTATE_EVENTS = "--annotate";
private static final String ANNOTATORS_CONFIG = "--annotators";
private static final String DEFAULT_ANNOTATORS = "all";
// Discovery
private static final String HELP = "--help";
private static final String LIST_METRICS = "--list-metrics";
@ -68,6 +83,7 @@ public class NBCLIOptions {
private final static String LOG_LEVEL_OVERRIDE = "--log-level-override";
private final static String ENABLE_CHART = "--enable-chart";
private final static String DOCKER_METRICS = "--docker-metrics";
private final static String DOCKER_METRICS_AT = "--docker-metrics-at";
private static final String GRAALJS_ENGINE = "--graaljs";
private static final String NASHORN_ENGINE = "--nashorn";
@ -118,6 +134,13 @@ public class NBCLIOptions {
private boolean showStackTraces = false;
private boolean compileScript = false;
private String scriptFile = null;
private String[] annotateEvents = new String[]{"ALL"};
private String dockerMetricsHost;
private String annotatorsConfig = "";
public String getAnnotatorsConfig() {
return annotatorsConfig;
}
public enum Mode {
ParseGlobalsOnly,
@ -125,7 +148,7 @@ public class NBCLIOptions {
}
public NBCLIOptions(String[] args) {
this(args,Mode.ParseAllOptions);
this(args, Mode.ParseAllOptions);
}
public NBCLIOptions(String[] args, Mode mode) {
@ -140,6 +163,8 @@ public class NBCLIOptions {
}
private LinkedList<String> parseGlobalOptions(String[] args) {
ArgsFile argsfile = new ArgsFile(ARGS_FILE_DEFAULT);
LinkedList<String> arglist = new LinkedList<>() {{
addAll(Arrays.asList(args));
}};
@ -162,6 +187,33 @@ public class NBCLIOptions {
}
switch (word) {
case ARGS_FILE:
arglist.removeFirst();
String argsfileSpec = readWordOrThrow(arglist, "argsfile");
argsfile = new ArgsFile(argsfileSpec);
arglist = argsfile.doArgsFile(argsfileSpec, arglist);
break;
case ARGS_PIN:
arglist.removeFirst();
arglist = argsfile.pin(arglist);
break;
case ARGS_UNPIN:
arglist.removeFirst();
arglist = argsfile.unpin(arglist);
break;
case ANNOTATE_EVENTS:
arglist.removeFirst();
String toAnnotate = readWordOrThrow(arglist, "annotated events");
annotateEvents = toAnnotate.split("\\\\s*,\\\\s*");
break;
// case ANNOTATE_TO_GRAFANA:
// arglist.removeFirst();
// grafanaEndpoint = readWordOrThrow(arglist,"grafana API endpoint");
// break;
case ANNOTATORS_CONFIG:
arglist.removeFirst();
this.annotatorsConfig = readWordOrThrow(arglist, "annotators config");
break;
case INCLUDE:
arglist.removeFirst();
String include = readWordOrThrow(arglist, "path to include");
@ -191,6 +243,10 @@ public class NBCLIOptions {
arglist.removeFirst();
wantsVersionCoords = true;
break;
case DOCKER_METRICS_AT:
arglist.removeFirst();
dockerMetricsHost = readWordOrThrow(arglist, "docker metrics host");
break;
case DOCKER_METRICS:
arglist.removeFirst();
dockerMetrics = true;
@ -464,6 +520,10 @@ public class NBCLIOptions {
return dockerMetrics;
}
public String wantsDockerMetricsAt() {
return dockerMetricsHost;
}
public int getReportInterval() {
return reportInterval;
}