From 667fbdbae9fa8f44164187dcf9b6365c7e836af5 Mon Sep 17 00:00:00 2001 From: Jonathan Shook Date: Mon, 16 Nov 2020 17:29:35 -0600 Subject: [PATCH] add log4j2 programmatic configuration --- .../java/io/nosqlbench/engine/cli/NBCLI.java | 34 +-- .../nosqlbench/engine/cli/NBCLIOptions.java | 8 +- .../engine/core/ScenarioLogger.java | 176 --------------- .../engine/core/logging/LoggerConfig.java | 152 +++++++++++++ .../engine/core/logging/ScenarioLogger.java | 27 +++ .../engine/core/logging/SessionLogConfig.java | 204 ++++++++++++++++++ .../engine/core/script/ScenariosExecutor.java | 6 +- .../script/AsyncScriptIntegrationTests.java | 5 +- 8 files changed, 418 insertions(+), 194 deletions(-) delete mode 100644 engine-core/src/main/java/io/nosqlbench/engine/core/ScenarioLogger.java create mode 100644 engine-core/src/main/java/io/nosqlbench/engine/core/logging/LoggerConfig.java create mode 100644 engine-core/src/main/java/io/nosqlbench/engine/core/logging/ScenarioLogger.java create mode 100644 engine-core/src/main/java/io/nosqlbench/engine/core/logging/SessionLogConfig.java diff --git a/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLI.java b/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLI.java index 34ee57d16..14c2d50a1 100644 --- a/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLI.java +++ b/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLI.java @@ -40,8 +40,7 @@ import java.util.stream.Collectors; public class NBCLI { - private static final Logger logger = LoggerFactory.getLogger("NBCLI"); - private static final Logger EVENTS = LoggerFactory.getLogger("EVENTS"); + private static Logger logger; private static final String CHART_HDR_LOG_NAME = "hdrdata-for-chart.log"; @@ -68,6 +67,14 @@ public class NBCLI { public void run(String[] args) { + // Initial logging config covers only command line parsing + // We don't want anything to go to console here unless it is a real problem + // as some integrations will depend on a stable and parsable program output + LoggerConfig loggerConfig = new LoggerConfig(NBLogLevel.ERROR, NBLogLevel.ERROR); + + ConfigurationFactory.setConfigurationFactory(loggerConfig); + logger = LogManager.getLogger("NBCLI"); + NBCLIOptions globalOptions = new NBCLIOptions(args, NBCLIOptions.Mode.ParseGlobalsOnly); // Global only processing @@ -128,11 +135,10 @@ public class NBCLI { 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()); + SessionLogConfig sessionLogConfig = new SessionLogConfig(sessionName); + sessionLogConfig.setConsolePattern(options.getConsoleLoggingPattern()); + sessionLogConfig.setLevel(options.wantsConsoleLogLevel()); + sessionLogConfig.start(); ActivityMetrics.setHdrDigits(options.getHdrDigits()); @@ -312,13 +318,12 @@ public class NBCLI { } - Level consoleLogLevel = options.wantsConsoleLogLevel(); - Level scenarioLogLevel = Level.toLevel(options.getLogsLevel()); - if (scenarioLogLevel.toInt() > consoleLogLevel.toInt()) { + NBLogLevel consoleLogLevel = options.wantsConsoleLogLevel(); + NBLogLevel scenarioLogLevel = options.getScenarioLogLevel(); + if (scenarioLogLevel.isGreaterOrEqualTo(consoleLogLevel)) { logger.info("raising scenario logging level to accommodate console logging level"); } - - Level maxLevel = Level.toLevel(Math.min(consoleLogLevel.toInt(), scenarioLogLevel.toInt())); + NBLogLevel maxLevel = NBLogLevel.max(consoleLogLevel, scenarioLogLevel); // Execute Scenario! if (options.getCommands().size() == 0) { @@ -330,7 +335,10 @@ public class NBCLI { ScriptParams scriptParams = new ScriptParams(); scriptParams.putAll(buffer.getCombinedParams()); scenario.addScenarioScriptParams(scriptParams); - ScenarioLogger sl = new ScenarioLogger(scenario) + + Path scenarioLogPath = SessionLogConfig.composeSessionLogName(options.getLogsDirectory(), scenario.getScenarioName()); + logger.info("Configuring scenario log at " + scenarioLogPath.toString()); + ScenarioLogger sl = new SessionLogConfig(scenario.getScenarioName()) .setLogDir(options.getLogsDirectory()) .setMaxLogs(options.getLogsMax()) .setLevel(maxLevel) diff --git a/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIOptions.java b/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIOptions.java index 10bafb9c2..f8e5c1308 100644 --- a/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIOptions.java +++ b/engine-cli/src/main/java/io/nosqlbench/engine/cli/NBCLIOptions.java @@ -90,7 +90,9 @@ public class NBCLIOptions { private static final String GRAALJS_COMPAT = "--graaljs-compat"; private static final String DOCKER_GRAFANA_TAG = "--docker-grafana-tag"; - private static final String DEFAULT_CONSOLE_LOGGING_PATTERN = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"; + private static final String DEFAULT_CONSOLE_LOGGING_PATTERN = "%7r %-5level [%t] %-12logger{0} %msg%n%throwable"; + + // private static final String DEFAULT_CONSOLE_LOGGING_PATTERN = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"; public static final String NBSTATEDIR = "NBSTATEDIR"; private final LinkedList cmdList = new LinkedList<>(); @@ -670,8 +672,8 @@ public class NBCLIOptions { return reportCsvTo; } - public String getLogsDirectory() { - return logsDirectory; + public Path getLogsDirectory() { + return Path.of(logsDirectory); } public int getLogsMax() { diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/ScenarioLogger.java b/engine-core/src/main/java/io/nosqlbench/engine/core/ScenarioLogger.java deleted file mode 100644 index 0b5482971..000000000 --- a/engine-core/src/main/java/io/nosqlbench/engine/core/ScenarioLogger.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * - * Copyright 2016 jshook - * 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 io.nosqlbench.engine.core; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.LoggerContext; -import ch.qos.logback.classic.encoder.PatternLayoutEncoder; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.ConsoleAppender; -import ch.qos.logback.core.FileAppender; -import io.nosqlbench.engine.core.script.Scenario; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.io.FileFilter; -import java.io.IOException; -import java.nio.file.Files; -import java.util.*; -import java.util.stream.Collectors; - -public class ScenarioLogger { - - private final Scenario scenario; - private File loggerDir = new File("logs"); - private int maxLogfiles = 10; - private Level logLevel = Level.INFO; - private Map logLevelOverrides = new HashMap<>(); - - public ScenarioLogger(Scenario scenario) { - this.scenario = scenario; - } - - public ScenarioLogger setLogDir(String logDir) { - this.loggerDir = new File(logDir); - return this; - } - - public ScenarioLogger setMaxLogs(int maxLogfiles) { - this.maxLogfiles = maxLogfiles; - return this; - } - - public ScenarioLogger setLevel(Level level) { - this.logLevel = level; - return this; - } - - public ScenarioLogger setLevel(String levelname) { - this.logLevel = Level.toLevel(levelname); - return this; - } - - public ScenarioLogger start() { - - if (!loggerDir.exists()) { - if (!loggerDir.mkdirs()) { - throw new RuntimeException("Unable to create logger directory:" + loggerDir.getPath()); - } - } - - LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); - //List copyOfListenerList = loggerContext.getCopyOfListenerList(); - - ConsoleAppender ca = new ConsoleAppender<>(); - ca.setContext(loggerContext); - - PatternLayoutEncoder ple = new PatternLayoutEncoder(); -// ple.setPattern("%date %level [%thread] %logger{10} [%file:%line] %msg%n"); - - ple.setPattern("%date %level [%thread] %logger{10} [%file:%line] %msg%n"); - ple.setContext(loggerContext); - ple.start(); - - String scenarioLog = loggerDir.getPath() + File.separator + scenario.getScenarioName()+".log"; - scenarioLog = scenarioLog.replaceAll("\\s","_"); - FileAppender fileAppender = new FileAppender(); - fileAppender.setFile(scenarioLog); - fileAppender.setEncoder(ple); - fileAppender.setContext(loggerContext); - fileAppender.setImmediateFlush(true); - System.err.println("Logging to " + scenarioLog); - fileAppender.start(); - - Logger logger = (Logger) LoggerFactory.getLogger("ROOT"); - logger.addAppender(fileAppender); - - logLevelOverrides.forEach((loggerName,loggingLevel) -> { - logger.debug("Overriding log level for " + loggerName + " to " + loggingLevel); - Logger toOverride = (Logger) LoggerFactory.getLogger(loggerName); - toOverride.setLevel(loggingLevel); - toOverride.debug("Log level was set to " + loggingLevel + - " by CLI option."); - }); - - logger.setLevel(logLevel); - logger.setAdditive(true); /* set to true if root should log too */ - - purgeOldFiles(logger); - - return this; - } - - private void purgeOldFiles(Logger logger) { - if (maxLogfiles==0) { - logger.debug("Not purging old files, since maxLogFiles is 0."); - return; - } - - - File[] files = loggerDir.listFiles(new FileFilter() { - @Override - public boolean accept(File pathname) { - return pathname.getPath().endsWith(".log"); - } - }); - if (files==null) { - return; - } - - List filesList = Arrays.asList(files); - int remove = filesList.size() - maxLogfiles; - if (remove<=0) { - return; - } - - List toDelete = filesList.stream() - .sorted(fileTimeComparator) - .limit(remove) - .collect(Collectors.toList()); - - for (File file : toDelete) { - logger.info("removing extra logfile: " + file.getPath()); - if (!file.delete()) { - logger.warn("unable to delete: " + file); - try { - Files.delete(file.toPath()); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } - } - - private static final Comparator fileTimeComparator = new Comparator() { - @Override - public int compare(File o1, File o2) { - return Long.compare(o1.lastModified(),o2.lastModified()); - } - }; - - - public ScenarioLogger setLogLevelOverrides(Map logLevelOverrides) { - this.logLevelOverrides = logLevelOverrides; - return this; - } - - public String getLogDir() { - return this.loggerDir.toString(); - } -} diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/logging/LoggerConfig.java b/engine-core/src/main/java/io/nosqlbench/engine/core/logging/LoggerConfig.java new file mode 100644 index 000000000..6427ecdb2 --- /dev/null +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/logging/LoggerConfig.java @@ -0,0 +1,152 @@ +package io.nosqlbench.engine.core.logging; + +import io.nosqlbench.nb.api.logging.NBLogLevel; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.appender.ConsoleAppender; +import org.apache.logging.log4j.core.appender.RollingFileAppender; +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.config.ConfigurationFactory; +import org.apache.logging.log4j.core.config.ConfigurationSource; +import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder; +import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder; +import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; +import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder; +import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; + +import java.net.URI; + +//@Plugin(name = "CustomConfigurationFactory", category = ConfigurationFactory.CATEGORY) +//@Order(50) +// Can't use plugin injection, since we need a tailored instance before logging +public class LoggerConfig extends ConfigurationFactory { + + private static final String LOG_PATTERN = "%d{DEFAULT}{GMT} [%t] %-5level: %msg%n"; + private static final String CONSOLE_PATTERN = "%7r %-5level [%t] %-12logger{0} %msg%n%throwable"; + public static final Level ROOT_LOG_LEVEL = Level.ALL; + private final NBLogLevel consoleLevel; + private final NBLogLevel fileLevel; + + public LoggerConfig(NBLogLevel consoleLevel, NBLogLevel fileLevel) { + this.consoleLevel = consoleLevel; + this.fileLevel = fileLevel; + } + + Configuration createConfiguration(final String name, ConfigurationBuilder builder) { + + Level internalLoggingStatusThreshold = Level.ERROR; + Level builderThresholdLevel = Level.INFO; +// Level rootLoggingLevel = Level.INFO; + + builder.setConfigurationName(name); + + builder.setStatusLevel(internalLoggingStatusThreshold); + +// builder.add( +// builder.newFilter( +// "ThresholdFilter", +// Filter.Result.ACCEPT, +// Filter.Result.NEUTRAL +// ).addAttribute("level", builderThresholdLevel) +// ); + + // CONSOLE appender + AppenderComponentBuilder appenderBuilder = + builder.newAppender("Stdout", "CONSOLE") + .addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT); + + appenderBuilder.add(builder.newLayout("PatternLayout") + .addAttribute("pattern", CONSOLE_PATTERN)); + +// appenderBuilder.add( +// builder.newFilter("MarkerFilter", Filter.Result.DENY, Filter.Result.NEUTRAL) +// .addAttribute("marker", "FLOW") +// ); + builder.add(appenderBuilder); + + // Log4J internal logging + builder.add(builder.newLogger("org.apache.logging.log4j", Level.DEBUG) + .add(builder.newAppenderRef("Stdout")) + .addAttribute("additivity", false)); + + + // LOGFILE appender + + LayoutComponentBuilder logfileLayout = builder.newLayout("PatternLayout") + .addAttribute("pattern", LOG_PATTERN); + + ComponentBuilder triggeringPolicy = builder.newComponent("Policies") + .addComponent(builder.newComponent("CronTriggeringPolicy").addAttribute("schedule", "0 0 0 * * ?")) + .addComponent(builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size", "100M")); + + AppenderComponentBuilder logsAppenderBuilder = + builder.newAppender("LOGS_APPENDER", RollingFileAppender.PLUGIN_NAME) + .addAttribute("fileName", "logs/irengine.log") + .addAttribute("filePattern", "logs/irengine-%d{MM-dd-yy}.log.gz") + .addAttribute("append", true) + .add(logfileLayout) + .addComponent(triggeringPolicy); + builder.add(logsAppenderBuilder); + +// LoggerComponentBuilder payloadBuilder = +// builder.newLogger(PAYLOADS, Level.TRACE) +// .addAttribute("additivity", false); +// +// +// if (consoleConfig.isPaylaodsEnabled()) { +// payloadBuilder = payloadBuilder.add(builder.newAppenderRef("Stdout").addAttribute("level", +// consoleConfig.getLogLevel())); +// } +// if (fileConfig.isPaylaodsEnabled()) { +// payloadBuilder = payloadBuilder.add(builder.newAppenderRef("LOGS_APPENDER").addAttribute("level", +// fileConfig.getLogLevel())); +// } +// builder.add(payloadBuilder); + + +// LoggerComponentBuilder stacktracesBuilder = +// builder.newLogger(STACKTRACES, Level.TRACE) +// .addAttribute("additivity", false); +// if (consoleConfig.isStackTracesEnabled()) { +// stacktracesBuilder = payloadBuilder.add(builder.newAppenderRef("Stdout").addAttribute("level", +// consoleConfig.getLogLevel())); +// } +// if (fileConfig.isStackTracesEnabled()) { +// stacktracesBuilder = payloadBuilder.add(builder.newAppenderRef("LOGS_APPENDER").addAttribute("level", +// fileConfig.getLogLevel())); +// } +// builder.add(stacktracesBuilder); + + // ROOT logging and appender + builder.add( + builder.newRootLogger(ROOT_LOG_LEVEL) + .add( + builder.newAppenderRef("Stdout") + .addAttribute("level", Level.valueOf(consoleLevel.toString())) + ) + .add( + builder.newAppenderRef("LOGS_APPENDER") + .addAttribute("level", Level.valueOf(fileLevel.toString())) + ) + ); + + + return builder.build(); + } + + @Override + public Configuration getConfiguration(final LoggerContext loggerContext, final ConfigurationSource source) { + return getConfiguration(loggerContext, source.toString(), null); + } + + @Override + public Configuration getConfiguration(final LoggerContext loggerContext, final String name, final URI configLocation) { + ConfigurationBuilder builder = newConfigurationBuilder(); + return createConfiguration(name, builder); + } + + @Override + protected String[] getSupportedTypes() { + return new String[]{"*"}; + } +} diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/logging/ScenarioLogger.java b/engine-core/src/main/java/io/nosqlbench/engine/core/logging/ScenarioLogger.java new file mode 100644 index 000000000..3cc0b6a9a --- /dev/null +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/logging/ScenarioLogger.java @@ -0,0 +1,27 @@ +package io.nosqlbench.engine.core.logging; + +import io.nosqlbench.nb.api.logging.NBLogLevel; +import org.apache.logging.log4j.Logger; + +import java.nio.file.Path; +import java.util.Map; + +public interface ScenarioLogger { + + ScenarioLogger setLogDir(Path logDir); + + Path getLogDir(); + + ScenarioLogger setMaxLogs(int maxLogfiles); + + void purgeOldFiles(Logger logger); + + ScenarioLogger setLevel(NBLogLevel levelname); + + NBLogLevel getLevel(); + + ScenarioLogger start(); + + ScenarioLogger setLogLevelOverrides(Map logLevelOverrides); + +} diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/logging/SessionLogConfig.java b/engine-core/src/main/java/io/nosqlbench/engine/core/logging/SessionLogConfig.java new file mode 100644 index 000000000..d34221691 --- /dev/null +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/logging/SessionLogConfig.java @@ -0,0 +1,204 @@ +package io.nosqlbench.engine.core.logging; + +import io.nosqlbench.nb.api.logging.NBLogLevel; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.appender.ConsoleAppender; +import org.apache.logging.log4j.core.config.Configurator; +import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder; +import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; +import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory; +import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder; +import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; +import org.apache.logging.log4j.spi.LoggerContext; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.stream.Collectors; + +public class SessionLogConfig implements ScenarioLogger { + + // private static final String LOG_PATTERN = "%d{DEFAULT}{GMT} [%t] %-5level: %msg%n"; + private static final String DEFAULT_CONSOLE_PATTERN = "%7r %-5level [%t] %-12logger{0} %msg%n%throwable"; + private final String session; + private String consolePattern = DEFAULT_CONSOLE_PATTERN; + // private final Scenario scenario; + private Path loggerDir = Path.of("logs"); + private NBLogLevel logLevel; + private int maxLogfiles = 100; + private Map logLevelOverrides = new LinkedHashMap<>(); + + public SessionLogConfig(String session) { + this.session = session; + } + + public ScenarioLogger setConsolePattern(String consolePattern) { + this.consolePattern = consolePattern; + return this; + } + + public String getConsolePattern() { + return consolePattern; + } + + public void configure() { + ConfigurationBuilder builder = ConfigurationBuilderFactory.newConfigurationBuilder(); + builder.setStatusLevel(Level.WARN); + + builder.setConfigurationName("ScenarioLogger"); + + // Append simple format to stdout + + AppenderComponentBuilder appenderBuilder = + builder.newAppender("console", "CONSOLE") + .addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT); + + appenderBuilder.add(builder.newLayout("PatternLayout") + .addAttribute("pattern", consolePattern)); + + builder.add(appenderBuilder); + + +// create a rolling file appender + + Path scenarioLog = composeSessionLogName(loggerDir, session); + + LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout") +// .addAttribute("pattern", "%d [%t] %-5level: %msg%n"); + .addAttribute("pattern", "%date %level [%thread] %logger{10} [%file:%line] %msg%n"); + + appenderBuilder = builder.newAppender("scenariolog", "File") + .addAttribute("fileName", scenarioLog.getFileName()) + .addAttribute("append", false) + .add(layoutBuilder); + builder.add(appenderBuilder); + + // Assemble the scenario logger instance + Level level = Level.valueOf(logLevel.toString()); + builder.add(builder.newRootLogger(level) + .add(builder.newAppenderRef("console")) + .add(builder.newAppenderRef("scenariolog")) + .addAttribute("additivity", true)); + + logLevelOverrides.forEach((k, v) -> { + Level olevel = Level.valueOf(v); + builder.add(builder.newLogger(k, olevel) + .add(builder.newAppenderRef("console")) + .add(builder.newAppenderRef("scenariolog")) + .addAttribute("additivity", true)); + }); + + LoggerContext ctx = Configurator.initialize(builder.build()); + } + + public static Path composeSessionLogName(Path loggerDir, String session) { + String logfilePath = loggerDir.toString() + File.separator + ".log"; + Path resolved = loggerDir.resolve(session.replaceAll("\\s", "_") + ".log"); + return resolved; + } + + @Override + public ScenarioLogger setLogDir(Path logDir) { + this.loggerDir = logDir; + return this; + } + + @Override + public Path getLogDir() { + return this.loggerDir; + } + + @Override + public ScenarioLogger setMaxLogs(int maxLogfiles) { + this.maxLogfiles = maxLogfiles; + return this; + } + + @Override + public void purgeOldFiles(Logger logger) { + if (maxLogfiles == 0) { + logger.debug("Not purging old files, since maxLogFiles is 0."); + return; + } + + + File[] files = loggerDir.toFile().listFiles(new FileFilter() { + @Override + public boolean accept(File pathname) { + return pathname.getPath().endsWith(".log"); + } + }); + if (files == null) { + return; + } + + List filesList = Arrays.asList(files); + int remove = filesList.size() - maxLogfiles; + if (remove <= 0) { + return; + } + + List toDelete = filesList.stream() + .sorted(fileTimeComparator) + .limit(remove) + .collect(Collectors.toList()); + + for (File file : toDelete) { + logger.info("removing extra logfile: " + file.getPath()); + if (!file.delete()) { + logger.warn("unable to delete: " + file); + try { + Files.delete(file.toPath()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + + private static final Comparator fileTimeComparator = new Comparator() { + @Override + public int compare(File o1, File o2) { + return Long.compare(o1.lastModified(), o2.lastModified()); + } + }; + + @Override + public ScenarioLogger setLevel(NBLogLevel levelname) { + this.logLevel = levelname; + return this; + } + + @Override + public NBLogLevel getLevel() { + return logLevel; + } + + @Override + public ScenarioLogger start() { + if (!Files.exists(loggerDir)) { + try { + Files.createDirectories(loggerDir); + } catch (Exception e) { + throw new RuntimeException("Unable to create logger directory:" + loggerDir); + } + } + + configure(); + org.apache.logging.log4j.Logger logger = LogManager.getLogger("LOGGER"); + + purgeOldFiles(logger); + return this; + } + + @Override + public ScenarioLogger setLogLevelOverrides(Map logLevelOverrides) { + this.logLevelOverrides = logLevelOverrides; + return this; + } +} diff --git a/engine-core/src/main/java/io/nosqlbench/engine/core/script/ScenariosExecutor.java b/engine-core/src/main/java/io/nosqlbench/engine/core/script/ScenariosExecutor.java index 566302dfb..26a8ab152 100644 --- a/engine-core/src/main/java/io/nosqlbench/engine/core/script/ScenariosExecutor.java +++ b/engine-core/src/main/java/io/nosqlbench/engine/core/script/ScenariosExecutor.java @@ -48,7 +48,11 @@ public class ScenariosExecutor { } public synchronized void execute(Scenario scenario) { - execute(scenario, new ScenarioLogger(scenario).setLogDir("logs").setMaxLogs(0)); + ScenarioLogger logs = new SessionLogConfig(scenario.getScenarioName()) + .setLogDir(Path.of("logs")) + .setMaxLogs(0) + .start(); + execute(scenario, logs); } public synchronized void execute(Scenario scenario, ScenarioLogger scenarioLogger) { diff --git a/nb/src/test/java/io/nosqlbench/engine/core/script/AsyncScriptIntegrationTests.java b/nb/src/test/java/io/nosqlbench/engine/core/script/AsyncScriptIntegrationTests.java index d0d734a1e..37e822d81 100644 --- a/nb/src/test/java/io/nosqlbench/engine/core/script/AsyncScriptIntegrationTests.java +++ b/nb/src/test/java/io/nosqlbench/engine/core/script/AsyncScriptIntegrationTests.java @@ -68,7 +68,10 @@ public class AsyncScriptIntegrationTests { } s.addScriptText(script); // s.addScriptText("load('classpath:scripts/async/" + scriptname + ".js');"); - ScenarioLogger scenarioLogger = new ScenarioLogger(s).setMaxLogs(0).setLogDir("logs/test").start(); + ScenarioLogger scenarioLogger = new SessionLogConfig(scenarioName) + .setMaxLogs(0) + .setLogDir(Path.of("logs/test")) + .start(); e.execute(s, scenarioLogger); ScenariosResults scenariosResults = e.awaitAllResults(); ScenarioResult scenarioResult = scenariosResults.getOne();