Commit f7d38b6f authored by Stefan Schuhbaeck's avatar Stefan Schuhbaeck
Browse files

fix #222. allow renaming and setting of log level programmatically

parent 9a0780f1
name=PropertiesConfig
property.filename = logs
appenders = console, file
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n
appender.file.type = RollingFile
appender.file.name = FILE
appender.file.fileName = log.out
appender.file.filePattern = out-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.file.layout.type = PatternLayout
appender.file.layout.pattern = %-5p [%t]: %m%n
appender.file.policies.type = Policies
appender.file.policies.size.type = SizeBasedTriggeringPolicy
appender.file.policies.size.size = 10000KB
rootLogger.level = trace
rootLogger.appenderRefs = console, file
rootLogger.appenderRef.console.ref = STDOUT
rootLogger.appenderRef.file.ref = FILE
\ No newline at end of file
name=PropertiesConfig name=PropertiesConfig
property.filename = logs property.logname = log.out
property.loglevel = INFO
appenders = console, file appenders = console, file
appender.console.type = Console appender.console.type = Console
appender.console.name = CONSOLE appender.console.name = CONSOLE
appender.console.layout.type = PatternLayout appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n appender.console.layout.pattern = %d{ABSOLUTE} %6p %c{1}:%L - %m%n
appender.file.type = RollingFile appender.file.type = RollingFile
appender.file.name = FILE appender.file.name = FILE
appender.file.fileName = log.out appender.file.fileName = ${main:logname}
appender.file.filePattern = out-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz appender.file.filePattern = ${main:logname}-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.file.layout.type = PatternLayout appender.file.layout.type = PatternLayout
appender.file.layout.pattern = %-5p [%t]: %m%n appender.file.layout.pattern = %d{ABSOLUTE} %6p %c{1}:%L - %m%n
appender.file.policies.type = Policies appender.file.policies.type = Policies
appender.file.policies.size.type = SizeBasedTriggeringPolicy appender.file.policies.size.type = SizeBasedTriggeringPolicy
appender.file.policies.size.size = 10000KB appender.file.policies.size.size = 10000KB
loggers = stdOutErr loggers = stdOutErr
logger.stdOutErr.name = STDOUTERR logger.stdOutErr.name = STDOUTERR
logger.stdOutErr.level = trace logger.stdOutErr.level = ${main:loglevel}
logger.stdOutErr.appenderRefs = file logger.stdOutErr.appenderRefs = file
logger.stdOutErr.appenderRef.file.ref = FILE logger.stdOutErr.appenderRef.file.ref = FILE
logger.stdOutErr.additivity = false logger.stdOutErr.additivity = false
rootLogger.level = trace rootLogger.level = ${main:loglevel}
rootLogger.appenderRefs = console, file rootLogger.appenderRefs = console, file
rootLogger.appenderRef.console.ref = CONSOLE rootLogger.appenderRef.console.ref = CONSOLE
rootLogger.appenderRef.file.ref = FILE rootLogger.appenderRef.file.ref = FILE
\ No newline at end of file
...@@ -12,37 +12,33 @@ import org.vadere.simulator.entrypoints.Version; ...@@ -12,37 +12,33 @@ import org.vadere.simulator.entrypoints.Version;
import org.vadere.simulator.entrypoints.cmd.commands.MigrationSubCommand; import org.vadere.simulator.entrypoints.cmd.commands.MigrationSubCommand;
import org.vadere.simulator.entrypoints.cmd.commands.ProjectRunSubCommand; import org.vadere.simulator.entrypoints.cmd.commands.ProjectRunSubCommand;
import org.vadere.simulator.entrypoints.cmd.commands.ScenarioRunSubCommand; import org.vadere.simulator.entrypoints.cmd.commands.ScenarioRunSubCommand;
import org.vadere.simulator.entrypoints.cmd.commands.SetLogLevelCommand;
import org.vadere.simulator.entrypoints.cmd.commands.SetLogNameCommand;
import org.vadere.simulator.entrypoints.cmd.commands.SuqSubCommand; import org.vadere.simulator.entrypoints.cmd.commands.SuqSubCommand;
import org.vadere.simulator.utils.scenariochecker.ScenarioChecker; import org.vadere.simulator.utils.scenariochecker.ScenarioChecker;
import org.vadere.util.logging.Logger; import org.vadere.util.logging.Logger;
import org.vadere.util.logging.StdOutErrLog; import org.vadere.util.logging.StdOutErrLog;
import org.vadere.util.opencl.CLUtils;
import javax.swing.*;
/** /**
* Provides the possibility to start Vadere in console mode. * Provides the possibility to start Vadere in console mode.
* Do not use Logging in this Class! The Logging framework needs information generated here
* to configure itself.
*/ */
public class VadereConsole { public class VadereConsole {
private final static Logger logger = Logger.getLogger(VadereConsole.class);
public static void main(String[] args) { public static void main(String[] args) {
Logger.setMainArguments(args);
// rimea_01_pathway_gnm1.scenario rimea_04_flow_gnm1_050_h.scenario // rimea_01_pathway_gnm1.scenario rimea_04_flow_gnm1_050_h.scenario
// String[] tmp = {"migrate", "--create-new-version", "0.7", "VadereSimulator/resources/"}; // String[] tmp = {"migrate", "--create-new-version", "0.7", "VadereSimulator/resources/"};
// args = tmp; // args = tmp;
ArgumentParser parser = createArgumentParser(); ArgumentParser parser = createArgumentParser();
try { try {
StdOutErrLog.addStdOutErrToLog();
//if (!CLUtils.isOpenCLSupported()) { //if (!CLUtils.isOpenCLSupported()) {
// System.out.println("Warning: OpenCL acceleration disabled, since no OpenCL support could be found!"); // System.out.println("Warning: OpenCL acceleration disabled, since no OpenCL support could be found!");
//} //}
Namespace ns = parser.parseArgs(args); Namespace ns = parser.parseArgs(args);
SubCommandRunner sRunner = ns.get("func"); SubCommandRunner sRunner = ns.get("func");
StdOutErrLog.addStdOutErrToLog();
sRunner.run(ns, parser); sRunner.run(ns, parser);
} catch (UnsatisfiedLinkError linkError) { } catch (UnsatisfiedLinkError linkError) {
...@@ -70,20 +66,20 @@ public class VadereConsole { ...@@ -70,20 +66,20 @@ public class VadereConsole {
} }
private static void addOptionsToParser(ArgumentParser parser) { private static void addOptionsToParser(ArgumentParser parser) {
// no action required call to Logger.setMainArguments(args) already configured Logger.
parser.addArgument("--loglevel") parser.addArgument("--loglevel")
.required(false) .required(false)
.type(String.class) .type(String.class)
.dest("loglevel") .dest("loglevel")
.choices("OFF", "FATAL", "TOPOGRAPHY_ERROR", "TOPOGRAPHY_WARN", "INFO", "DEBUG", "ALL") .choices("OFF", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "ALL")
.setDefault("INFO") .setDefault("INFO")
.action(new SetLogLevelCommand())
.help("Set Log Level."); .help("Set Log Level.");
// no action required call to Logger.setMainArguments(args) already configured Logger.
parser.addArgument("--logname") parser.addArgument("--logname")
.required(false) .required(false)
.type(String.class) .type(String.class)
.dest("logname") .dest("logname")
.action(new SetLogNameCommand())
.help("Write log to given file."); .help("Write log to given file.");
} }
......
package org.vadere.simulator.entrypoints.cmd.commands;
import net.sourceforge.argparse4j.inf.Argument;
import net.sourceforge.argparse4j.inf.ArgumentAction;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import org.vadere.util.logging.Logger;
import java.util.Map;
public class SetLogLevelCommand implements ArgumentAction {
@Override
public void run(ArgumentParser parser, Argument arg, Map<String, Object> attrs, String flag, Object value) throws ArgumentParserException {
Logger.setLevel((String) value);
}
@Override
public void onAttach(Argument arg) {
}
@Override
public boolean consumeArgument() {
return true;
}
}
package org.vadere.simulator.entrypoints.cmd.commands;
import net.sourceforge.argparse4j.inf.Argument;
import net.sourceforge.argparse4j.inf.ArgumentAction;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.LoggerConfig;
import java.util.Map;
public class SetLogNameCommand implements ArgumentAction {
@Override
public void run(ArgumentParser parser, Argument arg, Map<String, Object> attrs, String flag, Object value) throws ArgumentParserException {
String filename = (String) value;
final LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
final Configuration config = loggerContext.getConfiguration();
final LoggerConfig logConfig = config.getLoggerConfig("STDOUTERR");
final LoggerConfig rootConfig = config.getRootLogger();
rootConfig.removeAppender("FILE");
logConfig.removeAppender("FILE");
RollingFileAppender oldAppender = (RollingFileAppender) config.getAppender("FILE");
RollingFileAppender newAppender = RollingFileAppender.newBuilder()
.withName("FILE")
.withFileName(filename)
.withFilePattern(filename + "-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz")
.withLayout(oldAppender.getLayout())
.withPolicy(oldAppender.getTriggeringPolicy())
.build();
newAppender.start();
config.addAppender(newAppender);
logConfig.addAppender(newAppender, null, null);
rootConfig.addAppender(newAppender, null, null);
loggerContext.updateLoggers();
}
@Override
public void onAttach(Argument arg) {
}
@Override
public boolean consumeArgument() {
return true;
}
}
package org.vadere.simulator.entrypoints.cmd.commands;
import org.junit.Test;
import org.vadere.simulator.entrypoints.cmd.VadereConsole;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import static org.junit.Assert.*;
public class SetLogNameCommandTest {
@Test
public void testSetLogNameCommand(){
String path = "test.log";
VadereConsole.main(new String[] {"--logname", path, "scenario-run", "-f", "../VadereModelTests/TestOSM/scenarios/basic_2_density_discrete_ca.scenario"});
try {
assertTrue(Files.lines(Paths.get(path)).count() > 0);
} catch (IOException e) {
fail(e.getMessage());
}
}
}
name=PropertiesConfig
property.filename = logs
appenders = console, file
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n
appender.file.type = RollingFile
appender.file.name = FILE
appender.file.fileName = log.out
appender.file.filePattern = out-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.file.layout.type = PatternLayout
appender.file.layout.pattern = %-5p [%t]: %m%n
appender.file.policies.type = Policies
appender.file.policies.size.type = SizeBasedTriggeringPolicy
appender.file.policies.size.size = 10000KB
rootLogger.level = trace
rootLogger.appenderRefs = console, file
rootLogger.appenderRef.console.ref = STDOUT
rootLogger.appenderRef.file.ref = FILE
\ No newline at end of file
...@@ -4,6 +4,7 @@ import org.apache.logging.log4j.Level; ...@@ -4,6 +4,7 @@ import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.config.Configurator; import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.lookup.MainMapLookup;
import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MessageFactory; import org.apache.logging.log4j.message.MessageFactory;
import org.apache.logging.log4j.spi.AbstractLogger; import org.apache.logging.log4j.spi.AbstractLogger;
...@@ -11,7 +12,6 @@ import org.apache.logging.log4j.spi.ExtendedLoggerWrapper; ...@@ -11,7 +12,6 @@ import org.apache.logging.log4j.spi.ExtendedLoggerWrapper;
import org.apache.logging.log4j.util.MessageSupplier; import org.apache.logging.log4j.util.MessageSupplier;
import org.apache.logging.log4j.util.Supplier; import org.apache.logging.log4j.util.Supplier;
import javax.security.auth.login.Configuration;
/** /**
* Extended Logger interface with convenience methods for * Extended Logger interface with convenience methods for
...@@ -23,10 +23,29 @@ public final class Logger extends ExtendedLoggerWrapper { ...@@ -23,10 +23,29 @@ public final class Logger extends ExtendedLoggerWrapper {
private final ExtendedLoggerWrapper logger; private final ExtendedLoggerWrapper logger;
private static final String FQCN = Logger.class.getName(); private static final String FQCN = Logger.class.getName();
private static final Level STDERR = Level.forName("STDERR", 199); private static final Level STDERR = Level.forName("STDERR", 200);
private static final Level STDOUT = Level.forName("STDOUT", 401); private static final Level STDOUT = Level.forName("STDOUT", 400);
/**
* Add all arguments to the Log4j2 MapLookup and use them as variabes in the setup process.
*
* @param args arguments given in the main method.
*/
public static void setMainArguments(String[] args){
// [LOG4J2-1013] workaround:
// see https://issues.apache.org/jira/browse/LOG4J2-1013 and
// see https://stackoverflow.com/a/42498964
// This call allows to use ${main:myString} within the log4j2 config files where --myString
// is some argument given in the args[] array in the main method. Based on the bug
// [LOG4J2-1013] leading '-' must be removed.
String[] cleanedArgs = new String[args.length];
for (int i = 0; i < args.length; i++) {
cleanedArgs[i] = args[i].replaceAll("-", "");
}
MainMapLookup.setMainArguments(cleanedArgs);
}
private Logger(final org.apache.logging.log4j.Logger logger) { private Logger(final org.apache.logging.log4j.Logger logger) {
super((AbstractLogger) logger, logger.getName(), logger.getMessageFactory()); super((AbstractLogger) logger, logger.getName(), logger.getMessageFactory());
this.logger = this; this.logger = this;
......
...@@ -10,9 +10,9 @@ public class StdOutErrLog { ...@@ -10,9 +10,9 @@ public class StdOutErrLog {
* redirect StdOut and StdErr to logfile with custom log level STDOUT and STDERR. * redirect StdOut and StdErr to logfile with custom log level STDOUT and STDERR.
*/ */
public static void addStdOutErrToLog(){ public static void addStdOutErrToLog(){
System.setOut(redirectOut(System.out)); System.setOut(redirectOut(System.out));
System.setErr(redirectErr(System.err)); System.setErr(redirectErr(System.err));
logger.info("Redirect StdOut and StdErr"); logger.info("Redirect StdOut and StdErr");
} }
private static PrintStream redirectOut(PrintStream baseStream) { private static PrintStream redirectOut(PrintStream baseStream) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment