diff --git a/src/main/java/com/suse/matcher/Log4J.java b/src/main/java/com/suse/matcher/Log4J.java index a71a3351..5744f4b4 100644 --- a/src/main/java/com/suse/matcher/Log4J.java +++ b/src/main/java/com/suse/matcher/Log4J.java @@ -5,15 +5,18 @@ import org.apache.logging.log4j.core.LoggerContext; import org.apache.logging.log4j.core.appender.ConsoleAppender; import org.apache.logging.log4j.core.config.Configuration; +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.RootLoggerComponentBuilder; import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; +import org.apache.logging.log4j.core.impl.Log4jContextFactory; +import org.apache.logging.log4j.spi.LoggerContextFactory; import java.nio.file.Paths; +import java.util.List; import java.util.Optional; -import java.util.stream.Stream; /** * Facade on the log4j logging library. @@ -30,11 +33,13 @@ private Log4J() { * * @param level user chosen level * @param loggingDirectory directory for file logging + * + * @return the Log4j 2 {@link LoggerContext} */ - public static void initialize(Optional level, Optional loggingDirectory) { + public static LoggerContext initialize(Optional level, Optional loggingDirectory) { final ConfigurationBuilder builder = ConfigurationBuilderFactory.newConfigurationBuilder(); - builder.setStatusLevel(level.orElse(Level.INFO)); + builder.setStatusLevel(Level.INFO); builder.setConfigurationName("DefaultConfiguration"); // Build the root logger @@ -81,15 +86,20 @@ public static void initialize(Optional level, Optional loggingDir builder.add(builder.newLogger("org.drools.core.common.DefaultAgenda", Level.WARN)); Configuration configuration = builder.build(); - - // Update the configuration in the context. There are multiple contexts because slf4j binds loggers by - // name, so the log4j compatibility layer cannot use the classloader to define the context - Stream.of(LogManager.getContext(false), LogManager.getContext(ClassLoader.getSystemClassLoader(), false)) - .map(LoggerContext.class::cast) - .forEach(context -> { - context.reconfigure(configuration); - context.updateLoggers(); - }); + LoggerContext context = Configurator.initialize(configuration); + + // Update the configuration in the running contexts. There might be multiple contexts because slf4j binds + // loggers by name, so the log4j compatibility layer cannot use the classloader to define the context + LoggerContextFactory contextFactory = LogManager.getFactory(); + if (contextFactory instanceof Log4jContextFactory) { + List contexts = ((Log4jContextFactory) contextFactory).getSelector().getLoggerContexts(); + contexts.stream() + .distinct() + .filter(ctx -> ctx != context) + .forEach(ctx -> ctx.updateLoggers(configuration)); + } + + return context; } } diff --git a/src/main/java/com/suse/matcher/Main.java b/src/main/java/com/suse/matcher/Main.java index 1ad90c39..f634f7c9 100644 --- a/src/main/java/com/suse/matcher/Main.java +++ b/src/main/java/com/suse/matcher/Main.java @@ -14,8 +14,8 @@ import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.LoggerContext; import java.io.File; import java.nio.charset.Charset; @@ -35,50 +35,45 @@ public class Main { * @throws Exception if anything unexpected happens */ public static final void main(String[] args) throws Exception { - Logger logger = null; + long start = System.currentTimeMillis(); + CommandLine commandLine = parseCommandLine(args); - try { - long start = System.currentTimeMillis(); - CommandLine commandLine = parseCommandLine(args); - - // First initialize the logging system - Optional logLevel = commandLine.hasOption('v') ? - of(Level.toLevel(commandLine.getOptionValue('v'))) : - empty(); + // First initialize the logging system + Optional logLevel = commandLine.hasOption('v') ? + of(Level.toLevel(commandLine.getOptionValue('v'))) : + empty(); - Log4J.initialize(logLevel, ofNullable(commandLine.getOptionValue('l'))); - logger = LogManager.getLogger(Main.class); + try (LoggerContext context = Log4J.initialize(logLevel, ofNullable(commandLine.getOptionValue('l')))) { + Logger logger = context.getLogger(Main.class); + logger.info("Starting subscription-matcher process"); - // create output writing objects - Optional delimiter = commandLine.hasOption('d') ? + try { + // create output writing objects + Optional delimiter = commandLine.hasOption('d') ? of(commandLine.getOptionValue('d').charAt(0)) : empty(); - Optional outdir = ofNullable(commandLine.getOptionValue('o')); - OutputWriter writer = new OutputWriter(outdir, delimiter); + Optional outdir = ofNullable(commandLine.getOptionValue('o')); + OutputWriter writer = new OutputWriter(outdir, delimiter); - // load input data - String inputString = commandLine.hasOption('i') ? - Files.readString(Path.of(commandLine.getOptionValue('i'))) : - new String(System.in.readAllBytes(), Charset.defaultCharset()); + // load input data + String inputString = commandLine.hasOption('i') ? + Files.readString(Path.of(commandLine.getOptionValue('i'))) : + new String(System.in.readAllBytes(), Charset.defaultCharset()); - // save a copy of input data in the output directory - writer.writeJsonInput(inputString); + // save a copy of input data in the output directory + writer.writeJsonInput(inputString); - // do the matching - JsonInput input = new JsonIO().loadInput(inputString); - Assignment assignment = new Matcher(false).match(input); + // do the matching + JsonInput input = new JsonIO().loadInput(inputString); + Assignment assignment = new Matcher(false).match(input); - // write output data - writer.writeOutput(assignment, logLevel); + // write output data + writer.writeOutput(assignment, logLevel); - logger.info("Whole execution took {}ms", System.currentTimeMillis() - start); - } - catch (Throwable e) { - if( logger != null) { - logger.error("Unexpected exception: ", e); - } else { - System.err.println("Unexpected exception: " + e.getMessage()); - e.printStackTrace(); + logger.info("Whole execution took {}ms", System.currentTimeMillis() - start); + } + catch (Exception ex) { + logger.error("Unexpected exception: ", ex); } } } @@ -101,13 +96,13 @@ private static CommandLine parseCommandLine(String[] args) { help(opts); java.lang.System.exit(0); } - if (cmd.hasOption('o') && ! new File(cmd.getOptionValue('o')).isDirectory()) { + if (cmd.hasOption('o') && !new File(cmd.getOptionValue('o')).isDirectory()) { throw new ParseException("Given output directory does not exist " + - "or is not a directory"); + "or is not a directory"); } - if (cmd.hasOption('l') && ! new File(cmd.getOptionValue('l')).isDirectory()) { + if (cmd.hasOption('l') && !new File(cmd.getOptionValue('l')).isDirectory()) { throw new ParseException("Given logging directory does not exist " + - "or is not a directory"); + "or is not a directory"); } } catch (ParseException e) {