Skip to content

Commit

Permalink
fix: Logging options were not applied for replication
Browse files Browse the repository at this point in the history
  • Loading branch information
jruaux committed Apr 22, 2024
1 parent 9b331d5 commit e7e5e57
Show file tree
Hide file tree
Showing 17 changed files with 82 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class Replication extends AbstractExport {
private static final String TARGET_VAR = "target";

private final Logger log = LoggerFactory.getLogger(Replication.class);
private final Function<byte[], String> toString = BatchUtils.toStringKeyFunction(ByteArrayCodec.INSTANCE);

private ReplicationMode mode = DEFAULT_MODE;
private ReplicationType type = DEFAULT_TYPE;
Expand Down Expand Up @@ -138,8 +139,6 @@ protected Job job() {
}
}

private static final Function<byte[], String> toString = BatchUtils.toStringKeyFunction(ByteArrayCodec.INSTANCE);

private void addLoggingWriteListener(SimpleStepBuilder<KeyValue<byte[], Object>, KeyValue<byte[], Object>> step) {
step.listener(new LoggingWriteListener<>(this::log));
}
Expand All @@ -149,7 +148,7 @@ private void log(Chunk<? extends KeyValue<byte[], Object>> chunk) {
}

private void log(KeyValue<byte[], Object> keyValue) {
log.info("Wrote {} {}", keyValue.getType().getCode(), toString.apply(keyValue.getKey()));
log.info("Wrote {}", toString.apply(keyValue.getKey()));
}

private FlowBuilder<SimpleFlow> flow(String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import picocli.CommandLine.ArgGroup;

public abstract class AbstractExportCommand extends AbstractJobCommand {
public abstract class AbstractExportCommand extends AbstractRiotCommand {

@ArgGroup(exclusive = false, heading = "Reader options%n")
RedisReaderArgs readerArgs = new RedisReaderArgs();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
LpushCommand.class, RpushCommand.class, SaddCommand.class, SetCommand.class, XaddCommand.class,
ZaddCommand.class, SugaddCommand.class, JsonSetCommand.class,
TsAddCommand.class }, subcommandsRepeatable = true, synopsisSubcommandLabel = "[REDIS COMMAND...]", commandListHeading = "Redis commands:%n")
public abstract class AbstractImportCommand extends AbstractJobCommand {
public abstract class AbstractImportCommand extends AbstractRiotCommand {

@Option(arity = "1..*", names = "--proc", description = "SpEL expressions in the form field1=\"exp\" field2=\"exp\"...", paramLabel = "<f=exp>")
Map<String, Expression> processorExpressions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,11 @@
import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
import picocli.CommandLine.IExecutionStrategy;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParseResult;
import picocli.CommandLine.RunFirst;
import picocli.CommandLine.RunLast;
import picocli.CommandLine.Spec;

@Command(subcommands = { DatabaseImportCommand.class, DatabaseExportCommand.class, FileDumpImportCommand.class,
@Command(subcommands = { DbImportCommand.class, DbExportCommand.class, FileDumpImportCommand.class,
FileImportCommand.class, FileDumpExportCommand.class, FakerImportCommand.class, GenerateCommand.class,
ReplicateCommand.class, PingCommand.class, GenerateCompletion.class })
public abstract class AbstractMainCommand extends BaseCommand implements Runnable {
Expand All @@ -30,15 +27,9 @@ public abstract class AbstractMainCommand extends BaseCommand implements Runnabl

PrintWriter err;

@Spec
CommandSpec spec;

@ArgGroup(exclusive = false, heading = "Redis connection options%n")
RedisArgs redisArgs = new RedisArgs();

@Option(names = { "-V", "--version" }, versionHelp = true, description = "Print version information and exit.")
boolean versionRequested;

@Override
public void run() {
spec.commandLine().usage(out);
Expand All @@ -64,7 +55,6 @@ public static int run(AbstractMainCommand cmd, PrintWriter out, PrintWriter err,
private static int execute(CommandLine commandLine, String[] args, IExecutionStrategy... executionStrategies) {
CompositeExecutionStrategy executionStrategy = new CompositeExecutionStrategy();
executionStrategy.addDelegates(executionStrategies);
executionStrategy.addDelegates(LoggingMixin::executionStrategy);
executionStrategy.addDelegates(AbstractMainCommand::executionStrategy);
commandLine.setExecutionStrategy(executionStrategy);
commandLine.registerConverter(Range.class, new RangeTypeConverter<>(Range::of));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
import me.tongfei.progressbar.ProgressBarBuilder;
import me.tongfei.progressbar.ProgressBarStyle;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParentCommand;

@Command
abstract class AbstractJobCommand extends BaseCommand implements Callable<Integer> {
abstract class AbstractRiotCommand extends BaseCommand implements Callable<Integer> {

public enum ProgressStyle {
BLOCK, BAR, ASCII, LOG, NONE
Expand All @@ -34,6 +35,9 @@ public enum ProgressStyle {
@ParentCommand
protected AbstractMainCommand parent;

@Mixin
LoggingMixin loggingMixin = new LoggingMixin();

@Option(names = "--sleep", description = "Duration in ms to sleep after each batch write (default: ${DEFAULT-VALUE}).", paramLabel = "<ms>")
long sleep;

Expand Down Expand Up @@ -82,6 +86,7 @@ private ProgressBarStyle progressBarStyle() {

@Override
public Integer call() throws Exception {
loggingMixin.configureLogging();
AbstractRedisRunnable runnable = runnable();
if (name != null) {
runnable.setName(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import picocli.CommandLine.ArgGroup;

public abstract class AbstractStructImportCommand extends AbstractJobCommand {
public abstract class AbstractStructImportCommand extends AbstractRiotCommand {

@ArgGroup(exclusive = false, heading = "Writer options%n")
RedisWriterArgs writerArgs = new RedisWriterArgs();
Expand Down
28 changes: 20 additions & 8 deletions plugins/riot/src/main/java/com/redis/riot/cli/BaseCommand.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
package com.redis.riot.cli;

import java.util.Map;

import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
import picocli.CommandLine.Spec;

/**
* @author Julien Ruaux
*/
@Command(usageHelpAutoWidth = true, abbreviateSynopsis = true)
public class BaseCommand {
abstract class BaseCommand {

static {
if (System.getenv().containsKey("RIOT_NO_COLOR")) {
System.setProperty("picocli.ansi", "false");
}
}

@Spec
CommandSpec spec;

@Option(names = "--help", usageHelp = true, description = "Show this help message and exit.")
boolean helpRequested;

@Mixin
LoggingMixin loggingMixin = new LoggingMixin();
@CommandLine.Option(names = "-D", paramLabel = "<key=value>", descriptionKey = "system-property", mapFallbackValue = "", hidden = true)
void setProperty(Map<String, String> props) {
props.forEach(System::setProperty);
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import picocli.CommandLine.Option;

public class DatabaseArgs {
public class DbArgs {

@Option(names = "--driver", description = "Fully qualified name of the JDBC driver.", paramLabel = "<class>")
String driver;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import picocli.CommandLine.Option;

public class DatabaseExportArgs extends DatabaseArgs {
public class DbExportArgs extends DbArgs {

@Option(names = "--key-regex", description = "Regex for key-field extraction (default: ${DEFAULT-VALUE}).", paramLabel = "<str>")
Pattern keyRegex = AbstractMapExport.DEFAULT_KEY_REGEX;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
import picocli.CommandLine.Parameters;

@Command(name = "db-export", description = "Export Redis data to a relational database.")
public class DatabaseExportCommand extends AbstractExportCommand {
public class DbExportCommand extends AbstractExportCommand {

@Parameters(arity = "1", description = "SQL INSERT statement.", paramLabel = "SQL")
String sql;

@ArgGroup(exclusive = false)
DatabaseExportArgs args = new DatabaseExportArgs();
DbExportArgs args = new DbExportArgs();

@Override
protected DatabaseExport exportRunnable() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import picocli.CommandLine.Option;

public class DatabaseImportArgs extends DatabaseArgs {
public class DbImportArgs extends DbArgs {

@Option(names = "--max", description = "Max number of rows to import.", paramLabel = "<count>")
int maxItemCount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
import picocli.CommandLine.Parameters;

@Command(name = "db-import", description = "Import from a relational database.")
public class DatabaseImportCommand extends AbstractImportCommand {
public class DbImportCommand extends AbstractImportCommand {

@Parameters(arity = "1", description = "SQL SELECT statement", paramLabel = "SQL")
String sql;

@ArgGroup(exclusive = false)
DatabaseImportArgs args = new DatabaseImportArgs();
DbImportArgs args = new DbImportArgs();

@Override
protected AbstractImport importRunnable() {
Expand Down
138 changes: 33 additions & 105 deletions plugins/riot/src/main/java/com/redis/riot/cli/LoggingMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,135 +9,63 @@
import org.slf4j.event.Level;
import org.slf4j.simple.SimpleLogger;

import picocli.CommandLine.ExecutionException;
import picocli.CommandLine.ExitCode;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParameterException;
import picocli.CommandLine.ParseResult;
import picocli.CommandLine.Spec;
import picocli.CommandLine.Spec.Target;

public class LoggingMixin {

@Spec(Target.MIXEE)
private CommandSpec mixee;

Level level = Level.WARN;
String logFile;
boolean showDateTime;
String dateTimeFormat;
boolean showThreadId;
boolean showThreadName;
boolean showLogName;
boolean showShortLogName;
boolean levelInBrackets;
Map<String, Level> logLevels = new LinkedHashMap<>();

@Option(names = { "-d", "--debug" }, description = "Log in debug mode.")
public void setDebug(boolean debug) {
if (debug) {
getTopLevelCommandLoggingMixin(mixee).level = Level.DEBUG;
}
}

@Option(names = { "-i", "--info" }, description = "Set log level to info.")
public void setInfo(boolean info) {
if (info) {
getTopLevelCommandLoggingMixin(mixee).level = Level.INFO;
}
}

// @Option(names = { "-w", "--warn" }, description = "Set log level to warn.")
public void setWarn(boolean warn) {
if (warn) {
getTopLevelCommandLoggingMixin(mixee).level = Level.WARN;
}
}

@Option(names = { "-q", "--quiet" }, description = "Log errors only.")
public void setError(boolean error) {
if (error) {
getTopLevelCommandLoggingMixin(mixee).level = Level.ERROR;
}
}

@Option(arity = "1..*", names = "--log", description = "Custom log levels (e.g.: io.lettuce=INFO).", paramLabel = "<lvl>")
public void setLogLevels(Map<String, Level> levels) {
getTopLevelCommandLoggingMixin(mixee).logLevels = levels;
}

private Level level = Level.WARN;
@Option(names = "--log-file", description = "Log output target. Can be a path or special values System.out and System.err (default: System.err).", paramLabel = "<file>")
public void setLogFile(String file) {
getTopLevelCommandLoggingMixin(mixee).logFile = file;
}

private String logFile;
@Option(names = "--log-time", description = "Include current date and time in log messages.")
public void setShowDateTime(boolean show) {
getTopLevelCommandLoggingMixin(mixee).showDateTime = show;
}

private boolean showDateTime;
@Option(names = "--log-time-format", description = "Date and time format to be used in log messages (default: milliseconds since startup).", paramLabel = "<f>")
public void setDateTimeFormat(String format) {
getTopLevelCommandLoggingMixin(mixee).dateTimeFormat = format;
}

private String dateTimeFormat;
@Option(names = "--log-thread-id", description = "Include current thread ID in log messages.", hidden = true)
public void setShowThreadId(boolean show) {
getTopLevelCommandLoggingMixin(mixee).showThreadId = show;
}

private boolean showThreadId;
@Option(names = "--log-thread-name", description = "Include current thread name in log messages.", hidden = true)
public void setShowThreadName(boolean show) {
getTopLevelCommandLoggingMixin(mixee).showThreadName = show;
}

private boolean showThreadName;
@Option(names = "--log-name", description = "Include logger instance name in log messages.", hidden = true)
public void setShowLogName(boolean show) {
getTopLevelCommandLoggingMixin(mixee).showLogName = show;
}

private boolean showLogName;
@Option(names = "--log-short", description = "Include last component of logger instance name in log messages.", hidden = true)
public void setShowShortLogName(boolean show) {
getTopLevelCommandLoggingMixin(mixee).showShortLogName = show;
}

private boolean showShortLogName;
@Option(names = "--log-level", description = "Output log level string in brackets.", hidden = true)
public void setLevelInBrackets(boolean enable) {
getTopLevelCommandLoggingMixin(mixee).levelInBrackets = enable;
}
private boolean levelInBrackets;
@Option(arity = "1..*", names = "--log", description = "Custom log levels (e.g.: io.lettuce=INFO).", paramLabel = "<lvl>")
private Map<String, Level> logLevels = new LinkedHashMap<>();

public static int executionStrategy(ParseResult parseResult) throws ExecutionException, ParameterException {
getTopLevelCommandLoggingMixin(parseResult.commandSpec()).configureLogging();
return ExitCode.OK;
@Option(names = { "-d", "--debug" }, description = "Log in debug mode.")
public void setDebug(boolean debug) {
this.level = Level.DEBUG;
}

private static LoggingMixin getTopLevelCommandLoggingMixin(CommandSpec commandSpec) {
return ((AbstractMainCommand) commandSpec.root().userObject()).loggingMixin;
@Option(names = { "-i", "--info" }, description = "Set log level to info.")
public void setInfo(boolean info) {
this.level = Level.INFO;
}

public void configureLogging() {
configureLogging(getTopLevelCommandLoggingMixin(mixee));
@Option(names = { "-q", "--quiet" }, description = "Log errors only.")
public void setError(boolean error) {
this.level = Level.ERROR;
}

private static void configureLogging(LoggingMixin mixin) {
setProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, mixin.level.name());
if (mixin.logFile != null) {
setProperty(SimpleLogger.LOG_FILE_KEY, mixin.logFile);
public void configureLogging() {
setProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, level.name());
if (logFile != null) {
setProperty(SimpleLogger.LOG_FILE_KEY, logFile);
}
setBoolean(SimpleLogger.SHOW_DATE_TIME_KEY, mixin.showDateTime);
if (mixin.dateTimeFormat != null) {
setProperty(SimpleLogger.DATE_TIME_FORMAT_KEY, mixin.dateTimeFormat);
setBoolean(SimpleLogger.SHOW_DATE_TIME_KEY, showDateTime);
if (dateTimeFormat != null) {
setProperty(SimpleLogger.DATE_TIME_FORMAT_KEY, dateTimeFormat);
}
setBoolean(SimpleLogger.SHOW_THREAD_ID_KEY, mixin.showThreadId);
setBoolean(SimpleLogger.SHOW_THREAD_NAME_KEY, mixin.showThreadName);
setBoolean(SimpleLogger.SHOW_LOG_NAME_KEY, mixin.showLogName);
setBoolean(SimpleLogger.SHOW_SHORT_LOG_NAME_KEY, mixin.showShortLogName);
setBoolean(SimpleLogger.LEVEL_IN_BRACKETS_KEY, mixin.levelInBrackets);
setBoolean(SimpleLogger.SHOW_THREAD_ID_KEY, showThreadId);
setBoolean(SimpleLogger.SHOW_THREAD_NAME_KEY, showThreadName);
setBoolean(SimpleLogger.SHOW_LOG_NAME_KEY, showLogName);
setBoolean(SimpleLogger.SHOW_SHORT_LOG_NAME_KEY, showShortLogName);
setBoolean(SimpleLogger.LEVEL_IN_BRACKETS_KEY, levelInBrackets);
setLogLevel("com.amazonaws.internal", Level.ERROR);
setLogLevel("org.springframework.batch.core.step.builder.FaultTolerantStepBuilder", Level.ERROR);
setLogLevel("org.springframework.batch.core.step.item.ChunkMonitor", Level.ERROR);
for (Entry<String, Level> entry : mixin.logLevels.entrySet()) {
for (Entry<String, Level> entry : logLevels.entrySet()) {
setLogLevel(entry.getKey(), entry.getValue());
}
}
Expand Down
Loading

0 comments on commit e7e5e57

Please sign in to comment.