From 89696d3e8e4160dc651dd278ca35442aef26b142 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Thu, 6 Jul 2023 16:31:40 +0200 Subject: [PATCH] Switch to slf4j simple logger (fixes #835) --- client/pom.xml | 8 +- .../mvndaemon/mvnd/client/DefaultClient.java | 6 - .../mvndaemon/mvnd/client/DefaultClient.java | 14 +- .../mvnd/client/DaemonConnector.java | 6 +- .../mvnd/client/DaemonParameters.java | 23 +- .../mvndaemon/mvnd/common/Environment.java | 11 - .../org/apache/maven/cli/DaemonMavenCli.java | 35 +- .../org/apache/maven/cli/DaemonMavenCli.java | 35 +- daemon/pom.xml | 4 - .../maven/slf4j-configuration.properties | 19 -- dist-m39/src/main/provisio/maven-distro.xml | 8 +- dist-m40/src/main/provisio/maven-distro.xml | 8 +- .../main/distro/bin/mvnd-bash-completion.bash | 2 +- dist/src/main/distro/bin/mvnd-client.conf | 2 - dist/src/main/distro/bin/mvnd-daemon.conf | 2 - .../mvn/conf/logging/logback-client.xml | 34 -- .../mvn/conf/logging/logback-daemon.xml | 49 --- .../main/distro/mvn/conf/logging/logback.xml | 42 --- .../mvndaemon/mvnd/it/MaxHeapNativeIT.java | 29 +- .../mvndaemon/mvnd/it/MultiModuleTest.java | 8 +- .../mvnd/junit/MvndTestExtension.java | 3 - .../mvndaemon/mvnd/junit/TestParameters.java | 3 - .../src/test/resources/logback/logback.xml | 47 --- logging/pom.xml | 59 +++- .../mvnd/logging/internal/SimpleAppender.java | 69 ---- .../smart/ProjectBuildLogAppender.java | 78 +---- .../java/org/slf4j/impl/MvndBaseLogger.java | 299 ++++++++++++++++++ .../impl/MvndConfiguration.java} | 24 +- .../java/org/slf4j/impl/MvndDaemonLogger.java | 71 +++++ .../slf4j/impl/MvndFailOnSeverityLogger.java | 129 ++++++++ .../org/slf4j/impl/MvndLoggerFactory.java | 81 +++++ .../java/org/slf4j/impl/MvndSimpleLogger.java | 236 ++++++++++++++ .../org/slf4j/impl/StaticLoggerBinder.java | 82 +++++ .../java/org/slf4j/impl/StaticMDCBinder.java | 57 ++++ .../maven/slf4j-configuration.properties | 20 ++ pom.xml | 11 - 36 files changed, 1143 insertions(+), 471 deletions(-) delete mode 100644 daemon/src/main/resources/META-INF/maven/slf4j-configuration.properties delete mode 100644 dist/src/main/distro/mvn/conf/logging/logback-client.xml delete mode 100644 dist/src/main/distro/mvn/conf/logging/logback-daemon.xml delete mode 100644 dist/src/main/distro/mvn/conf/logging/logback.xml delete mode 100644 integration-tests/src/test/resources/logback/logback.xml delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/internal/SimpleAppender.java create mode 100644 logging/src/main/java/org/slf4j/impl/MvndBaseLogger.java rename logging/src/main/java/org/{mvndaemon/mvnd/logging/internal/MvndSlf4jConfiguration.java => slf4j/impl/MvndConfiguration.java} (67%) create mode 100644 logging/src/main/java/org/slf4j/impl/MvndDaemonLogger.java create mode 100644 logging/src/main/java/org/slf4j/impl/MvndFailOnSeverityLogger.java create mode 100644 logging/src/main/java/org/slf4j/impl/MvndLoggerFactory.java create mode 100644 logging/src/main/java/org/slf4j/impl/MvndSimpleLogger.java create mode 100644 logging/src/main/java/org/slf4j/impl/StaticLoggerBinder.java create mode 100644 logging/src/main/java/org/slf4j/impl/StaticMDCBinder.java create mode 100644 logging/src/main/resources/META-INF/maven/slf4j-configuration.properties diff --git a/client/pom.xml b/client/pom.xml index dfb357b2c..0cbd3b29c 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -43,12 +43,12 @@ mvnd-common - org.apache.maven - maven-embedder + org.apache.maven.daemon + mvnd-logging - org.slf4j - slf4j-simple + org.apache.maven + maven-embedder org.slf4j diff --git a/client/src/main/java-fallback/org/mvndaemon/mvnd/client/DefaultClient.java b/client/src/main/java-fallback/org/mvndaemon/mvnd/client/DefaultClient.java index ddc55b562..0dd015853 100644 --- a/client/src/main/java-fallback/org/mvndaemon/mvnd/client/DefaultClient.java +++ b/client/src/main/java-fallback/org/mvndaemon/mvnd/client/DefaultClient.java @@ -24,12 +24,6 @@ public class DefaultClient { public static void main(String[] argv) throws Exception { - final String logbackConfFallback = System.getProperty("logback.configurationFile.fallback"); - if (null != logbackConfFallback && !"".equals(logbackConfFallback)) { - System.setProperty("logback.configurationFile", logbackConfFallback); - System.clearProperty("logback.configurationFile.fallback"); - } - final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); LOGGER.warn("Found old JDK, fallback to the embedded maven!"); LOGGER.warn("Use JDK 11+ to run maven-mvnd client!"); diff --git a/client/src/main/java-mvnd/org/mvndaemon/mvnd/client/DefaultClient.java b/client/src/main/java-mvnd/org/mvndaemon/mvnd/client/DefaultClient.java index dd010ff3a..ee5f9ae09 100644 --- a/client/src/main/java-mvnd/org/mvndaemon/mvnd/client/DefaultClient.java +++ b/client/src/main/java-mvnd/org/mvndaemon/mvnd/client/DefaultClient.java @@ -60,6 +60,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.bridge.SLF4JBridgeHandler; +import org.slf4j.impl.MvndLoggerFactory; +import org.slf4j.impl.StaticLoggerBinder; import static org.mvndaemon.mvnd.client.DaemonParameters.LOG_EXTENSION; @@ -70,8 +72,6 @@ public class DefaultClient implements Client { private final DaemonParameters parameters; public static void main(String[] argv) throws Exception { - System.clearProperty("logback.configurationFile.fallback"); - final List args = new ArrayList<>(Arrays.asList(argv)); // Log file @@ -115,6 +115,10 @@ public static void main(String[] argv) throws Exception { // System properties setSystemPropertiesFromCommandLine(args); + if (StaticLoggerBinder.getSingleton().getLoggerFactory() instanceof MvndLoggerFactory) { + ((MvndLoggerFactory) StaticLoggerBinder.getSingleton().getLoggerFactory()).reconfigure(); + } + DaemonParameters parameters = new DaemonParameters(); if (parameters.serial()) { System.setProperty(Environment.MVND_THREADS.getProperty(), Integer.toString(1)); @@ -191,9 +195,13 @@ public static void setSystemPropertiesFromCommandLine(List args) { /* This needs to be done very early, otherwise various DaemonParameters do not work properly */ final int eqPos = val.indexOf('='); if (eqPos >= 0) { - System.setProperty(val.substring(0, eqPos), val.substring(eqPos + 1)); + String k = val.substring(0, eqPos); + String v = val.substring(eqPos + 1); + System.setProperty(k, v); + LOGGER.trace("Setting system property {} to {}", k, v); } else { System.setProperty(val, ""); + LOGGER.trace("Setting system property {}", val); } } } diff --git a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonConnector.java b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonConnector.java index 537f0bbba..912a05e92 100644 --- a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonConnector.java +++ b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonConnector.java @@ -57,6 +57,7 @@ import org.mvndaemon.mvnd.common.logging.ClientOutput; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.impl.SimpleLogger; import static java.lang.Thread.sleep; import static org.mvndaemon.mvnd.common.DaemonState.Canceled; @@ -433,10 +434,11 @@ private Process startDaemonProcess(String daemonId, ClientOutput output) { args.add("-Dmaven.conf=" + mvndHome.resolve("mvn").resolve("conf")); args.add("-Dclassworlds.conf=" + mvndHome.resolve("bin").resolve("mvnd-daemon.conf")); + args.add("-D" + SimpleLogger.LOG_FILE_KEY + "=" + + parameters.daemonStorage().resolve("daemon-" + daemonId + ".log")); + Environment.MVND_JAVA_HOME.addSystemProperty( args, parameters.javaHome().toString()); - Environment.LOGBACK_CONFIGURATION_FILE.addSystemProperty( - args, parameters.logbackConfigurationPath().toString()); Environment.MVND_ID.addSystemProperty(args, daemonId); Environment.MVND_DAEMON_STORAGE.addSystemProperty( args, parameters.daemonStorage().toString()); diff --git a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java index c0230f891..d14f3e41c 100644 --- a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java +++ b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java @@ -184,11 +184,21 @@ private static String javaHomeFromPath() { } public Path userDir() { - return value(Environment.USER_DIR).orSystemProperty().orFail().asPath().toAbsolutePath(); + return value(Environment.USER_DIR) + .orSystemProperty() + .orFail() + .cache(provider) + .asPath() + .toAbsolutePath(); } public Path userHome() { - return value(Environment.USER_HOME).orSystemProperty().orFail().asPath().toAbsolutePath(); + return value(Environment.USER_HOME) + .orSystemProperty() + .orFail() + .cache(provider) + .asPath() + .toAbsolutePath(); } public Path suppliedPropertiesPath() { @@ -256,15 +266,6 @@ public Path multiModuleProjectDirectory(Path projectDir) { .normalize(); } - public Path logbackConfigurationPath() { - return property(Environment.MVND_LOGBACK) - .orDefault(() -> mvndHome() - .resolve("mvn/conf/logging/logback-daemon.xml") - .toString()) - .orFail() - .asPath(); - } - public String minHeapSize() { return property(Environment.MVND_MIN_HEAP_SIZE).asString(); } diff --git a/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java b/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java index c0892f741..ac0e9a6c5 100644 --- a/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java +++ b/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java @@ -62,17 +62,6 @@ public enum Environment { /** Use one thread, no log buffering and the default project builder to behave like a standard maven */ SERIAL("mvnd.serial", null, Boolean.FALSE, OptionType.VOID, Flags.OPTIONAL, "mvnd:-1", "mvnd:--serial"), - // - // Log properties - // - - /** - * The location of the Logback configuration file the daemon should use to configure its logging. - */ - MVND_LOGBACK("mvnd.logback", null, null, OptionType.PATH, Flags.NONE), - /** The system property expected by logback to set the configuration file */ - LOGBACK_CONFIGURATION_FILE("logback.configurationFile", null, null, OptionType.PATH, Flags.INTERNAL), - // // System properties // diff --git a/daemon-m39/src/main/java/org/apache/maven/cli/DaemonMavenCli.java b/daemon-m39/src/main/java/org/apache/maven/cli/DaemonMavenCli.java index 7ddc25157..53301faa3 100644 --- a/daemon-m39/src/main/java/org/apache/maven/cli/DaemonMavenCli.java +++ b/daemon-m39/src/main/java/org/apache/maven/cli/DaemonMavenCli.java @@ -57,6 +57,8 @@ import org.apache.maven.cli.event.ExecutionEventLogger; import org.apache.maven.cli.internal.BootstrapCoreExtensionManager; import org.apache.maven.cli.internal.extension.model.CoreExtension; +import org.apache.maven.cli.logging.Slf4jConfiguration; +import org.apache.maven.cli.logging.Slf4jConfigurationFactory; import org.apache.maven.cli.transfer.QuietMavenTransferListener; import org.apache.maven.cli.transfer.Slf4jMavenTransferListener; import org.apache.maven.eventspy.internal.EventSpyDispatcher; @@ -113,6 +115,8 @@ import org.slf4j.ILoggerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.impl.MvndSimpleLogger; +import org.slf4j.spi.LocationAwareLogger; import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher; import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher; @@ -365,15 +369,17 @@ void logging(CliRequest cliRequest) { cliRequest.quiet = !cliRequest.debug && cliRequest.commandLine.hasOption(CLIManager.QUIET); cliRequest.showErrors = cliRequest.debug || cliRequest.commandLine.hasOption(CLIManager.ERRORS); - ch.qos.logback.classic.Level level; + Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration(slf4jLoggerFactory); + if (cliRequest.debug) { - level = ch.qos.logback.classic.Level.DEBUG; + cliRequest.request.setLoggingLevel(MavenExecutionRequest.LOGGING_LEVEL_DEBUG); + slf4jConfiguration.setRootLoggerLevel(Slf4jConfiguration.Level.DEBUG); } else if (cliRequest.quiet) { - level = ch.qos.logback.classic.Level.WARN; - } else { - level = ch.qos.logback.classic.Level.INFO; + cliRequest.request.setLoggingLevel(MavenExecutionRequest.LOGGING_LEVEL_ERROR); + slf4jConfiguration.setRootLoggerLevel(Slf4jConfiguration.Level.ERROR); } - ((ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)).setLevel(level); + // else fall back to default log level specified in conf + // see https://issues.apache.org/jira/browse/MNG-2570 // LOG COLOR String styleColor = cliRequest.getUserProperties().getProperty(STYLE_COLOR_PROPERTY, "auto"); @@ -389,11 +395,6 @@ void logging(CliRequest cliRequest) { MessageUtils.setColorEnabled(false); } - // Workaround for https://github.com/apache/maven-mvnd/issues/39 - final ch.qos.logback.classic.Logger mvndLogger = - (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("org.mvndaemon.mvnd"); - mvndLogger.setLevel(ch.qos.logback.classic.Level.toLevel(System.getProperty("mvnd.log.level"), null)); - // LOG STREAMS if (cliRequest.commandLine.hasOption(CLIManager.LOG_FILE)) { File logFile = new File(cliRequest.commandLine.getOptionValue(CLIManager.LOG_FILE)); @@ -413,15 +414,15 @@ void logging(CliRequest cliRequest) { .asOptional() .map(Boolean::parseBoolean) .orElse(Boolean.FALSE)) { - ch.qos.logback.classic.Logger stdout = - (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("stdout"); - ch.qos.logback.classic.Logger stderr = - (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("stderr"); - stdout.setLevel(ch.qos.logback.classic.Level.INFO); - stderr.setLevel(ch.qos.logback.classic.Level.INFO); + MvndSimpleLogger stdout = (MvndSimpleLogger) slf4jLoggerFactory.getLogger("stdout"); + MvndSimpleLogger stderr = (MvndSimpleLogger) slf4jLoggerFactory.getLogger("stderr"); + stdout.setLogLevel(LocationAwareLogger.INFO_INT); + stderr.setLogLevel(LocationAwareLogger.INFO_INT); System.setOut(new LoggingOutputStream(s -> stdout.info("[stdout] " + s)).printStream()); System.setErr(new LoggingOutputStream(s -> stderr.warn("[stderr] " + s)).printStream()); } + + slf4jConfiguration.activate(); } private void version(CliRequest cliRequest) throws ExitException { diff --git a/daemon-m40/src/main/java/org/apache/maven/cli/DaemonMavenCli.java b/daemon-m40/src/main/java/org/apache/maven/cli/DaemonMavenCli.java index d83324e03..96ec7b877 100644 --- a/daemon-m40/src/main/java/org/apache/maven/cli/DaemonMavenCli.java +++ b/daemon-m40/src/main/java/org/apache/maven/cli/DaemonMavenCli.java @@ -54,6 +54,8 @@ import org.apache.maven.cli.internal.extension.model.CoreExtension; import org.apache.maven.cli.jansi.JansiMessageBuilderFactory; import org.apache.maven.cli.jansi.MessageUtils; +import org.apache.maven.cli.logging.Slf4jConfiguration; +import org.apache.maven.cli.logging.Slf4jConfigurationFactory; import org.apache.maven.cli.transfer.QuietMavenTransferListener; import org.apache.maven.cli.transfer.Slf4jMavenTransferListener; import org.apache.maven.eventspy.internal.EventSpyDispatcher; @@ -103,6 +105,8 @@ import org.slf4j.ILoggerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.slf4j.impl.MvndSimpleLogger; +import org.slf4j.spi.LocationAwareLogger; import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher; import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher; @@ -411,15 +415,17 @@ void logging(CliRequest cliRequest) { cliRequest.quiet = !cliRequest.verbose && commandLine.hasOption(CLIManager.QUIET); cliRequest.showErrors = cliRequest.verbose || commandLine.hasOption(CLIManager.ERRORS); - ch.qos.logback.classic.Level level; + Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration(slf4jLoggerFactory); + if (cliRequest.verbose) { - level = ch.qos.logback.classic.Level.DEBUG; + cliRequest.request.setLoggingLevel(MavenExecutionRequest.LOGGING_LEVEL_DEBUG); + slf4jConfiguration.setRootLoggerLevel(Slf4jConfiguration.Level.DEBUG); } else if (cliRequest.quiet) { - level = ch.qos.logback.classic.Level.WARN; - } else { - level = ch.qos.logback.classic.Level.INFO; + cliRequest.request.setLoggingLevel(MavenExecutionRequest.LOGGING_LEVEL_ERROR); + slf4jConfiguration.setRootLoggerLevel(Slf4jConfiguration.Level.ERROR); } - ((ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)).setLevel(level); + // else fall back to default log level specified in conf + // see https://issues.apache.org/jira/browse/MNG-2570 // LOG COLOR String styleColor = cliRequest.getUserProperties().getProperty(STYLE_COLOR_PROPERTY, "auto"); @@ -438,11 +444,6 @@ void logging(CliRequest cliRequest) { } } - // Workaround for https://github.com/apache/maven-mvnd/issues/39 - final ch.qos.logback.classic.Logger mvndLogger = - (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("org.mvndaemon.mvnd"); - mvndLogger.setLevel(ch.qos.logback.classic.Level.toLevel(System.getProperty("mvnd.log.level"), null)); - // LOG STREAMS if (commandLine.hasOption(CLIManager.LOG_FILE)) { File logFile = new File(commandLine.getOptionValue(CLIManager.LOG_FILE)); @@ -462,15 +463,15 @@ void logging(CliRequest cliRequest) { .asOptional() .map(Boolean::parseBoolean) .orElse(Boolean.FALSE)) { - ch.qos.logback.classic.Logger stdout = - (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("stdout"); - ch.qos.logback.classic.Logger stderr = - (ch.qos.logback.classic.Logger) slf4jLoggerFactory.getLogger("stderr"); - stdout.setLevel(ch.qos.logback.classic.Level.INFO); - stderr.setLevel(ch.qos.logback.classic.Level.INFO); + MvndSimpleLogger stdout = (MvndSimpleLogger) slf4jLoggerFactory.getLogger("stdout"); + MvndSimpleLogger stderr = (MvndSimpleLogger) slf4jLoggerFactory.getLogger("stderr"); + stdout.setLogLevel(LocationAwareLogger.INFO_INT); + stderr.setLogLevel(LocationAwareLogger.INFO_INT); System.setOut(new LoggingOutputStream(s -> stdout.info("[stdout] " + s)).printStream()); System.setErr(new LoggingOutputStream(s -> stderr.warn("[stderr] " + s)).printStream()); } + + slf4jConfiguration.activate(); } private void version(CliRequest cliRequest) throws ExitException { diff --git a/daemon/pom.xml b/daemon/pom.xml index 5acd3fb0e..aee12fac3 100644 --- a/daemon/pom.xml +++ b/daemon/pom.xml @@ -64,10 +64,6 @@ - - ch.qos.logback - logback-classic - org.slf4j log4j-over-slf4j diff --git a/daemon/src/main/resources/META-INF/maven/slf4j-configuration.properties b/daemon/src/main/resources/META-INF/maven/slf4j-configuration.properties deleted file mode 100644 index 69dc8b64a..000000000 --- a/daemon/src/main/resources/META-INF/maven/slf4j-configuration.properties +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright 2019 the original author or authors. -# -# 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. -# - -# key = Slf4j effective logger factory implementation -# value = corresponding o.a.m.cli.logging.Slf4jConfiguration class -ch.qos.logback.classic.LoggerContext org.mvndaemon.mvnd.logging.internal.MvndSlf4jConfiguration diff --git a/dist-m39/src/main/provisio/maven-distro.xml b/dist-m39/src/main/provisio/maven-distro.xml index f2b2759c7..caa8d6edc 100644 --- a/dist-m39/src/main/provisio/maven-distro.xml +++ b/dist-m39/src/main/provisio/maven-distro.xml @@ -20,7 +20,7 @@ + excludes="lib/maven-slf4j-*" /> @@ -28,12 +28,6 @@ - - - - - - diff --git a/dist-m40/src/main/provisio/maven-distro.xml b/dist-m40/src/main/provisio/maven-distro.xml index d3ec052a5..0faf498f3 100644 --- a/dist-m40/src/main/provisio/maven-distro.xml +++ b/dist-m40/src/main/provisio/maven-distro.xml @@ -20,7 +20,7 @@ + excludes="lib/maven-slf4j-*,lib/plexus-utils-3.*" /> @@ -28,12 +28,6 @@ - - - - - - diff --git a/dist/src/main/distro/bin/mvnd-bash-completion.bash b/dist/src/main/distro/bin/mvnd-bash-completion.bash index 0dde19ffd..473eca900 100755 --- a/dist/src/main/distro/bin/mvnd-bash-completion.bash +++ b/dist/src/main/distro/bin/mvnd-bash-completion.bash @@ -218,7 +218,7 @@ _mvnd() local mvnd_opts="-1" local mvnd_long_opts="--color|--completion|--purge|--raw-streams|--serial|--status|--stop" - local mvnd_properties="-Djava.home|-Djdk.java.options|-Dmaven.multiModuleProjectDirectory|-Dmaven.repo.local|-Dmaven.settings|-Dmvnd.buildTime|-Dmvnd.builder|-Dmvnd.cancelConnectTimeout|-Dmvnd.connectTimeout|-Dmvnd.daemonStorage|-Dmvnd.debug|-Dmvnd.debug.address|-Dmvnd.duplicateDaemonGracePeriod|-Dmvnd.enableAssertions|-Dmvnd.expirationCheckDelay|-Dmvnd.home|-Dmvnd.idleTimeout|-Dmvnd.jvmArgs|-Dmvnd.keepAlive|-Dmvnd.logPurgePeriod|-Dmvnd.logback|-Dmvnd.maxHeapSize|-Dmvnd.maxLostKeepAlive|-Dmvnd.minHeapSize|-Dmvnd.minThreads|-Dmvnd.noBuffering|-Dmvnd.noDaemon|-Dmvnd.noModelCache|-Dmvnd.pluginRealmEvictPattern|-Dmvnd.propertiesPath|-Dmvnd.rawStreams|-Dmvnd.registry|-Dmvnd.rollingWindowSize|-Dmvnd.serial|-Dmvnd.socketConnectTimeout|-Dmvnd.socketFamily|-Dmvnd.threadStackSize|-Dmvnd.threads|-Dstyle.color|-Duser.dir|-Duser.home" + local mvnd_properties="-Djava.home|-Djdk.java.options|-Dmaven.multiModuleProjectDirectory|-Dmaven.repo.local|-Dmaven.settings|-Dmvnd.buildTime|-Dmvnd.builder|-Dmvnd.cancelConnectTimeout|-Dmvnd.connectTimeout|-Dmvnd.daemonStorage|-Dmvnd.debug|-Dmvnd.debug.address|-Dmvnd.duplicateDaemonGracePeriod|-Dmvnd.enableAssertions|-Dmvnd.expirationCheckDelay|-Dmvnd.home|-Dmvnd.idleTimeout|-Dmvnd.jvmArgs|-Dmvnd.keepAlive|-Dmvnd.logPurgePeriod|-Dmvnd.maxHeapSize|-Dmvnd.maxLostKeepAlive|-Dmvnd.minHeapSize|-Dmvnd.minThreads|-Dmvnd.noBuffering|-Dmvnd.noDaemon|-Dmvnd.noModelCache|-Dmvnd.pluginRealmEvictPattern|-Dmvnd.propertiesPath|-Dmvnd.rawStreams|-Dmvnd.registry|-Dmvnd.rollingWindowSize|-Dmvnd.serial|-Dmvnd.socketConnectTimeout|-Dmvnd.socketFamily|-Dmvnd.threadStackSize|-Dmvnd.threads|-Dstyle.color|-Duser.dir|-Duser.home" local opts="-am|-amd|-B|-C|-c|-cpu|-D|-e|-emp|-ep|-f|-fae|-ff|-fn|-gs|-h|-l|-N|-npr|-npu|-nsu|-o|-P|-pl|-q|-rf|-s|-T|-t|-U|-up|-V|-v|-X|${mvnd_opts}" local long_opts="--also-make|--also-make-dependents|--batch-mode|--strict-checksums|--lax-checksums|--check-plugin-updates|--define|--errors|--encrypt-master-password|--encrypt-password|--file|--fail-at-end|--fail-fast|--fail-never|--global-settings|--help|--log-file|--non-recursive|--no-plugin-registry|--no-plugin-updates|--no-snapshot-updates|--offline|--activate-profiles|--projects|--quiet|--resume-from|--settings|--threads|--toolchains|--update-snapshots|--update-plugins|--show-version|--version|--debug|${mvnd_long_opts}" diff --git a/dist/src/main/distro/bin/mvnd-client.conf b/dist/src/main/distro/bin/mvnd-client.conf index ed682f0b8..0b6487777 100644 --- a/dist/src/main/distro/bin/mvnd-client.conf +++ b/dist/src/main/distro/bin/mvnd-client.conf @@ -20,8 +20,6 @@ set maven.home default ${mvnd.home}/mvn set maven.conf default ${maven.home}/conf set java.util.logging.config.file default ${maven.conf}/logging/java.util.logging.properties -set logback.configurationFile default ${maven.conf}/logging/logback-client.xml -set logback.configurationFile.fallback default ${maven.conf}/logging/logback.xml [plexus.core] load ${maven.conf}/logging diff --git a/dist/src/main/distro/bin/mvnd-daemon.conf b/dist/src/main/distro/bin/mvnd-daemon.conf index b387bd2df..7a2b40b5e 100644 --- a/dist/src/main/distro/bin/mvnd-daemon.conf +++ b/dist/src/main/distro/bin/mvnd-daemon.conf @@ -20,8 +20,6 @@ set maven.home default ${mvnd.home}/mvn set maven.conf default ${maven.home}/conf set java.util.logging.config.file default ${maven.conf}/logging/java.util.logging.properties -set logback.configurationFile default ${maven.conf}/logging/logback-daemon.xml -set logback.configurationFile.fallback default ${maven.conf}/logging/logback.xml [plexus.core] load ${maven.conf}/logging diff --git a/dist/src/main/distro/mvn/conf/logging/logback-client.xml b/dist/src/main/distro/mvn/conf/logging/logback-client.xml deleted file mode 100644 index abadf029d..000000000 --- a/dist/src/main/distro/mvn/conf/logging/logback-client.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - %-5relative %-5level %logger{35} - %msg%n - - - - - - - diff --git a/dist/src/main/distro/mvn/conf/logging/logback-daemon.xml b/dist/src/main/distro/mvn/conf/logging/logback-daemon.xml deleted file mode 100644 index 97a6053be..000000000 --- a/dist/src/main/distro/mvn/conf/logging/logback-daemon.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - ${mvnd.daemonStorage}/daemon-${mvnd.id}.log - - %d{HH:mm:ss.SSS} %.-1level %msg%n - - - - - - - - - - - - - - - - - - diff --git a/dist/src/main/distro/mvn/conf/logging/logback.xml b/dist/src/main/distro/mvn/conf/logging/logback.xml deleted file mode 100644 index 1628306d0..000000000 --- a/dist/src/main/distro/mvn/conf/logging/logback.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MaxHeapNativeIT.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MaxHeapNativeIT.java index 2b00562fe..4e0173b57 100644 --- a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MaxHeapNativeIT.java +++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MaxHeapNativeIT.java @@ -20,10 +20,9 @@ import javax.inject.Inject; -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.read.ListAppender; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -32,6 +31,8 @@ import org.mvndaemon.mvnd.client.Client; import org.mvndaemon.mvnd.junit.MvndNativeTest; import org.slf4j.LoggerFactory; +import org.slf4j.impl.MvndSimpleLogger; +import org.slf4j.spi.LocationAwareLogger; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -42,33 +43,31 @@ static class BaseTest { @Inject Client client; - static ListAppender appender = new ListAppender<>(); + static List messages = new CopyOnWriteArrayList<>(); @BeforeAll static void setup() { - Logger logger = (Logger) LoggerFactory.getLogger("org.mvndaemon.mvnd.client.DaemonConnector"); - logger.setLevel(Level.DEBUG); - logger.addAppender(appender); - appender.start(); + MvndSimpleLogger logger = + (MvndSimpleLogger) LoggerFactory.getLogger("org.mvndaemon.mvnd.client.DaemonConnector"); + logger.setLogLevel(LocationAwareLogger.DEBUG_INT); + MvndSimpleLogger.setLogSink(messages::add); } @AfterAll static void tearDown() { - Logger logger = (Logger) LoggerFactory.getLogger("org.mvndaemon.mvnd.client.DaemonConnector"); - logger.detachAppender(appender); + MvndSimpleLogger.setLogSink(null); } static String getDaemonArgs() { - return appender.list.stream() - .filter(e -> e.getMessage().contains("Starting daemon process")) - .map(e -> e.getArgumentArray()[2].toString()) + return messages.stream() + .filter(e -> e.contains("Starting daemon process")) .findAny() .orElseThrow(); } @BeforeEach void unitSetup() { - appender.list.clear(); + messages.clear(); } } diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MultiModuleTest.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MultiModuleTest.java index 2695d7da5..12cf18449 100644 --- a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MultiModuleTest.java +++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/MultiModuleTest.java @@ -74,7 +74,13 @@ void cleanInstall() throws IOException, InterruptedException { Stream.of(installedJars).forEach(jar -> Assertions.assertThat(jar).doesNotExist()); final TestClientOutput output = new TestClientOutput(); - client.execute(output, "clean", "install", "-e").assertSuccess(); + client.execute( + output, + "-Dorg.slf4j.simpleLogger.log.io.takari.maven.builder.smart=DEBUG", + "clean", + "install", + "-e") + .assertSuccess(); { final List filteredMessages = output.getMessages().stream() diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/MvndTestExtension.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/MvndTestExtension.java index d4295d744..13eef6165 100644 --- a/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/MvndTestExtension.java +++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/MvndTestExtension.java @@ -238,8 +238,6 @@ public static MvndResource create( LOG.info("Building with mrm-maven-plugin"); settingsPath = createSettings(testDir.resolve("settings.xml"), mrmRepoUrl); } - final Path logback = - Paths.get("src/test/resources/logback/logback.xml").toAbsolutePath(); final Path home = deleteDir(testDir.resolve("home")); final TestParameters parameters = new TestParameters( testDir, @@ -251,7 +249,6 @@ public static MvndResource create( Paths.get(System.getProperty("java.home")).toAbsolutePath().normalize(), localMavenRepository, settingsPath, - logback, TimeUtils.toDuration(Environment.MVND_IDLE_TIMEOUT.getDefault()), keepAlive != null && !keepAlive.isEmpty() ? TimeUtils.toDuration(keepAlive) diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/TestParameters.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/TestParameters.java index 2f8b291ea..fa7eb38d0 100644 --- a/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/TestParameters.java +++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/junit/TestParameters.java @@ -40,7 +40,6 @@ public TestParameters( Path javaHome, Path localMavenRepository, Path settings, - Path logbackConfigurationPath, Duration idleTimeout, Duration keepAlive, int maxLostKeepAlive, @@ -55,7 +54,6 @@ public TestParameters( .put(Environment.JAVA_HOME, javaHome) .put(Environment.MAVEN_REPO_LOCAL, localMavenRepository) .put(Environment.MAVEN_SETTINGS, settings) - .put(Environment.MVND_LOGBACK, logbackConfigurationPath) .put(Environment.MVND_IDLE_TIMEOUT, TimeUtils.printDuration(idleTimeout)) .put(Environment.MVND_KEEP_ALIVE, TimeUtils.printDuration(keepAlive)) .put(Environment.MVND_MAX_LOST_KEEP_ALIVE, maxLostKeepAlive) @@ -83,7 +81,6 @@ public TestParameters withTransferProgress() { value(Environment.JAVA_HOME).asPath(), value(Environment.MAVEN_REPO_LOCAL).asPath(), value(Environment.MAVEN_SETTINGS).asPath(), - value(Environment.MVND_LOGBACK).asPath(), value(Environment.MVND_IDLE_TIMEOUT).asDuration(), value(Environment.MVND_KEEP_ALIVE).asDuration(), value(Environment.MVND_MAX_LOST_KEEP_ALIVE).asInt(), diff --git a/integration-tests/src/test/resources/logback/logback.xml b/integration-tests/src/test/resources/logback/logback.xml deleted file mode 100644 index 573dc0785..000000000 --- a/integration-tests/src/test/resources/logback/logback.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - ${mvnd.daemonStorage}/daemon-${mvnd.id}.log - - %d{HH:mm:ss.SSS} %.-1level %msg%n - - - - - - - - - - - - - - - - diff --git a/logging/pom.xml b/logging/pom.xml index 1f8898d94..c9794dad2 100644 --- a/logging/pom.xml +++ b/logging/pom.xml @@ -41,10 +41,6 @@ - - ch.qos.logback - logback-classic - org.slf4j log4j-over-slf4j @@ -59,4 +55,59 @@ + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.6.0 + + + extract + + unpack + + + + + org.apache.maven + maven-slf4j-wrapper + ${maven4.version} + sources + + + org.slf4j + slf4j-simple + ${slf4j.version} + sources + + + org/apache/maven/logwrapper/*.java,org/slf4j/impl/*.java + **/StaticLoggerBinder.java,**/StaticMDCBinder.java + ${project.build.directory}/generated-sources/unpack + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.4.0 + + + add-unpacked-source-dir + + add-source + + + + ${project.build.directory}/generated-sources/unpack + + + + + + + + diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/SimpleAppender.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/SimpleAppender.java deleted file mode 100644 index 24b4f6861..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/SimpleAppender.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 org.mvndaemon.mvnd.logging.internal; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.classic.spi.IThrowableProxy; -import ch.qos.logback.classic.spi.ThrowableProxyUtil; -import ch.qos.logback.core.AppenderBase; -import ch.qos.logback.core.CoreConstants; - -import static org.apache.maven.shared.utils.logging.MessageUtils.level; - -/** - * This appender acts like the slf4j simple logger. - * It's used - */ -public class SimpleAppender extends AppenderBase { - - @Override - protected void append(ILoggingEvent eventObject) { - StringBuilder buf = new StringBuilder(); - buf.append('['); - buf.append(renderLevel(eventObject.getLevel())); - buf.append(']'); - buf.append(' '); - buf.append(eventObject.getFormattedMessage()); - buf.append(CoreConstants.LINE_SEPARATOR); - IThrowableProxy tp = eventObject.getThrowableProxy(); - if (tp != null) { - buf.append(CoreConstants.LINE_SEPARATOR); - buf.append(ThrowableProxyUtil.asString(tp)); - } - System.out.print(buf.toString()); - } - - private String renderLevel(Level level) { - switch (level.toInt()) { - case Level.TRACE_INT: - return level().debug("TRACE"); - case Level.DEBUG_INT: - return level().debug("DEBUG"); - case Level.INFO_INT: - return level().info("INFO"); - case Level.WARN_INT: - return level().warning("WARNING"); - case Level.ERROR_INT: - return level().error("ERROR"); - default: - throw new IllegalStateException("Level " + level + " is unknown."); - } - } -} diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/ProjectBuildLogAppender.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/ProjectBuildLogAppender.java index 64ea08720..15177c7da 100644 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/ProjectBuildLogAppender.java +++ b/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/ProjectBuildLogAppender.java @@ -18,24 +18,13 @@ */ package org.mvndaemon.mvnd.logging.smart; -import java.util.Map; - -import ch.qos.logback.classic.Level; -import ch.qos.logback.classic.Logger; -import ch.qos.logback.classic.PatternLayout; -import ch.qos.logback.classic.pattern.ClassicConverter; -import ch.qos.logback.classic.spi.ILoggingEvent; -import ch.qos.logback.core.AppenderBase; -import ch.qos.logback.core.Context; -import org.apache.maven.shared.utils.logging.LoggerLevelRenderer; -import org.apache.maven.shared.utils.logging.MessageUtils; -import org.slf4j.LoggerFactory; import org.slf4j.MDC; +import org.slf4j.impl.MvndSimpleLogger; /** * Forwards log messages to the client. */ -public class ProjectBuildLogAppender extends AppenderBase implements AutoCloseable { +public class ProjectBuildLogAppender implements AutoCloseable { private static final String KEY_PROJECT_ID = "maven.project.id"; private static final ThreadLocal PROJECT_ID = new InheritableThreadLocal<>(); @@ -80,71 +69,20 @@ public static void updateMdc() { } } - private static final String pattern = "[%level] %msg%n"; - private final PatternLayout layout; private final BuildEventListener buildEventListener; public ProjectBuildLogAppender(BuildEventListener buildEventListener) { this.buildEventListener = buildEventListener; - this.name = ProjectBuildLogAppender.class.getName(); - this.context = (Context) LoggerFactory.getILoggerFactory(); - - final PatternLayout l = new PatternLayout(); - l.setContext(context); - l.setPattern(pattern); - final Map instanceConverterMap = l.getInstanceConverterMap(); - final String levelConverterClassName = LevelConverter.class.getName(); - instanceConverterMap.put("level", levelConverterClassName); - instanceConverterMap.put("le", levelConverterClassName); - instanceConverterMap.put("p", levelConverterClassName); - this.layout = l; - - final Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - root.addAppender(this); - - start(); + MvndSimpleLogger.setLogSink(this::accept); } - @Override - public void start() { - layout.start(); - super.start(); - } - - @Override - protected void append(ILoggingEvent event) { - String projectId = event.getMDCPropertyMap().get(KEY_PROJECT_ID); - buildEventListener.projectLogMessage(projectId, layout.doLayout(event)); - } - - public static class LevelConverter extends ClassicConverter { - @Override - public String convert(ILoggingEvent event) { - LoggerLevelRenderer llr = MessageUtils.level(); - Level level = event.getLevel(); - switch (level.toInt()) { - case Level.ERROR_INT: - return llr.error(level.toString()); - case Level.WARN_INT: - return llr.warning(level.toString()); - case Level.INFO_INT: - return llr.info(level.toString()); - default: - return llr.debug(level.toString()); - } - } - } - - @Override - public void close() { - stop(); - final Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - root.detachAppender(this); + protected void accept(String message) { + String projectId = MDC.get(KEY_PROJECT_ID); + buildEventListener.projectLogMessage(projectId, message); } @Override - public void stop() { - layout.stop(); - super.stop(); + public void close() throws Exception { + MvndSimpleLogger.setLogSink(null); } } diff --git a/logging/src/main/java/org/slf4j/impl/MvndBaseLogger.java b/logging/src/main/java/org/slf4j/impl/MvndBaseLogger.java new file mode 100644 index 000000000..5e44cefbd --- /dev/null +++ b/logging/src/main/java/org/slf4j/impl/MvndBaseLogger.java @@ -0,0 +1,299 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.slf4j.impl; + +import org.slf4j.event.LoggingEvent; +import org.slf4j.helpers.FormattingTuple; +import org.slf4j.helpers.MarkerIgnoringBase; +import org.slf4j.helpers.MessageFormatter; +import org.slf4j.spi.LocationAwareLogger; + +public abstract class MvndBaseLogger extends MarkerIgnoringBase { + + protected static final int LOG_LEVEL_TRACE = LocationAwareLogger.TRACE_INT; + protected static final int LOG_LEVEL_DEBUG = LocationAwareLogger.DEBUG_INT; + protected static final int LOG_LEVEL_INFO = LocationAwareLogger.INFO_INT; + protected static final int LOG_LEVEL_WARN = LocationAwareLogger.WARN_INT; + protected static final int LOG_LEVEL_ERROR = LocationAwareLogger.ERROR_INT; + + /** The current log level */ + protected int currentLogLevel = LOG_LEVEL_INFO; + + public MvndBaseLogger(String name) { + this.name = name; + } + + protected void formatAndLog(int level, String format, Object arg1, Object arg2) { + if (!isLevelEnabled(level)) { + return; + } + FormattingTuple tp = MessageFormatter.format(format, arg1, arg2); + log(level, tp.getMessage(), tp.getThrowable()); + } + + protected void formatAndLog(int level, String format, Object... arguments) { + if (!isLevelEnabled(level)) { + return; + } + FormattingTuple tp = MessageFormatter.arrayFormat(format, arguments); + log(level, tp.getMessage(), tp.getThrowable()); + } + + protected void log(int level, String message, Throwable t) { + if (!isLevelEnabled(level)) { + return; + } + doLog(level, message, t); + } + + protected abstract void doLog(int level, String message, Throwable t); + + /** + * Is the given log level currently enabled? + * + * @param logLevel + * is this level enabled? + */ + protected boolean isLevelEnabled(int logLevel) { + // log level are numerically ordered so can use simple numeric + // comparison + return (logLevel >= currentLogLevel); + } + + /** Are {@code trace} messages currently enabled? */ + public boolean isTraceEnabled() { + return isLevelEnabled(LOG_LEVEL_TRACE); + } + + /** + * A simple implementation which logs messages of level TRACE according to + * the format outlined above. + */ + public void trace(String msg) { + log(LOG_LEVEL_TRACE, msg, null); + } + + /** + * Perform single parameter substitution before logging the message of level + * TRACE according to the format outlined above. + */ + public void trace(String format, Object param1) { + formatAndLog(LOG_LEVEL_TRACE, format, param1, null); + } + + /** + * Perform double parameter substitution before logging the message of level + * TRACE according to the format outlined above. + */ + public void trace(String format, Object param1, Object param2) { + formatAndLog(LOG_LEVEL_TRACE, format, param1, param2); + } + + /** + * Perform double parameter substitution before logging the message of level + * TRACE according to the format outlined above. + */ + public void trace(String format, Object... argArray) { + formatAndLog(LOG_LEVEL_TRACE, format, argArray); + } + + /** Log a message of level TRACE, including an exception. */ + public void trace(String msg, Throwable t) { + log(LOG_LEVEL_TRACE, msg, t); + } + + /** Are {@code debug} messages currently enabled? */ + public boolean isDebugEnabled() { + return isLevelEnabled(LOG_LEVEL_DEBUG); + } + + /** + * A simple implementation which logs messages of level DEBUG according to + * the format outlined above. + */ + public void debug(String msg) { + log(LOG_LEVEL_DEBUG, msg, null); + } + + /** + * Perform single parameter substitution before logging the message of level + * DEBUG according to the format outlined above. + */ + public void debug(String format, Object param1) { + formatAndLog(LOG_LEVEL_DEBUG, format, param1, null); + } + + /** + * Perform double parameter substitution before logging the message of level + * DEBUG according to the format outlined above. + */ + public void debug(String format, Object param1, Object param2) { + formatAndLog(LOG_LEVEL_DEBUG, format, param1, param2); + } + + /** + * Perform double parameter substitution before logging the message of level + * DEBUG according to the format outlined above. + */ + public void debug(String format, Object... argArray) { + formatAndLog(LOG_LEVEL_DEBUG, format, argArray); + } + + /** Log a message of level DEBUG, including an exception. */ + public void debug(String msg, Throwable t) { + log(LOG_LEVEL_DEBUG, msg, t); + } + + /** Are {@code info} messages currently enabled? */ + public boolean isInfoEnabled() { + return isLevelEnabled(LOG_LEVEL_INFO); + } + + /** + * A simple implementation which logs messages of level INFO according to + * the format outlined above. + */ + public void info(String msg) { + log(LOG_LEVEL_INFO, msg, null); + } + + /** + * Perform single parameter substitution before logging the message of level + * INFO according to the format outlined above. + */ + public void info(String format, Object arg) { + formatAndLog(LOG_LEVEL_INFO, format, arg, null); + } + + /** + * Perform double parameter substitution before logging the message of level + * INFO according to the format outlined above. + */ + public void info(String format, Object arg1, Object arg2) { + formatAndLog(LOG_LEVEL_INFO, format, arg1, arg2); + } + + /** + * Perform double parameter substitution before logging the message of level + * INFO according to the format outlined above. + */ + public void info(String format, Object... argArray) { + formatAndLog(LOG_LEVEL_INFO, format, argArray); + } + + /** Log a message of level INFO, including an exception. */ + public void info(String msg, Throwable t) { + log(LOG_LEVEL_INFO, msg, t); + } + + /** Are {@code warn} messages currently enabled? */ + public boolean isWarnEnabled() { + return isLevelEnabled(LOG_LEVEL_WARN); + } + + /** + * A simple implementation which always logs messages of level WARN + * according to the format outlined above. + */ + public void warn(String msg) { + log(LOG_LEVEL_WARN, msg, null); + } + + /** + * Perform single parameter substitution before logging the message of level + * WARN according to the format outlined above. + */ + public void warn(String format, Object arg) { + formatAndLog(LOG_LEVEL_WARN, format, arg, null); + } + + /** + * Perform double parameter substitution before logging the message of level + * WARN according to the format outlined above. + */ + public void warn(String format, Object arg1, Object arg2) { + formatAndLog(LOG_LEVEL_WARN, format, arg1, arg2); + } + + /** + * Perform double parameter substitution before logging the message of level + * WARN according to the format outlined above. + */ + public void warn(String format, Object... argArray) { + formatAndLog(LOG_LEVEL_WARN, format, argArray); + } + + /** Log a message of level WARN, including an exception. */ + public void warn(String msg, Throwable t) { + log(LOG_LEVEL_WARN, msg, t); + } + + /** Are {@code error} messages currently enabled? */ + public boolean isErrorEnabled() { + return isLevelEnabled(LOG_LEVEL_ERROR); + } + + /** + * A simple implementation which always logs messages of level ERROR + * according to the format outlined above. + */ + public void error(String msg) { + log(LOG_LEVEL_ERROR, msg, null); + } + + /** + * Perform single parameter substitution before logging the message of level + * ERROR according to the format outlined above. + */ + public void error(String format, Object arg) { + formatAndLog(LOG_LEVEL_ERROR, format, arg, null); + } + + /** + * Perform double parameter substitution before logging the message of level + * ERROR according to the format outlined above. + */ + public void error(String format, Object arg1, Object arg2) { + formatAndLog(LOG_LEVEL_ERROR, format, arg1, arg2); + } + + /** + * Perform double parameter substitution before logging the message of level + * ERROR according to the format outlined above. + */ + public void error(String format, Object... argArray) { + formatAndLog(LOG_LEVEL_ERROR, format, argArray); + } + + /** Log a message of level ERROR, including an exception. */ + public void error(String msg, Throwable t) { + log(LOG_LEVEL_ERROR, msg, t); + } + + public void log(LoggingEvent event) { + int levelInt = event.getLevel().toInt(); + + if (!isLevelEnabled(levelInt)) { + return; + } + FormattingTuple tp = + MessageFormatter.arrayFormat(event.getMessage(), event.getArgumentArray(), event.getThrowable()); + log(levelInt, tp.getMessage(), event.getThrowable()); + } +} diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/MvndSlf4jConfiguration.java b/logging/src/main/java/org/slf4j/impl/MvndConfiguration.java similarity index 67% rename from logging/src/main/java/org/mvndaemon/mvnd/logging/internal/MvndSlf4jConfiguration.java rename to logging/src/main/java/org/slf4j/impl/MvndConfiguration.java index 7e6ecf37f..e075a03e1 100644 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/MvndSlf4jConfiguration.java +++ b/logging/src/main/java/org/slf4j/impl/MvndConfiguration.java @@ -16,32 +16,36 @@ * specific language governing permissions and limitations * under the License. */ -package org.mvndaemon.mvnd.logging.internal; +package org.slf4j.impl; import org.apache.maven.cli.logging.Slf4jConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.slf4j.ILoggerFactory; -public class MvndSlf4jConfiguration implements Slf4jConfiguration { +public class MvndConfiguration implements Slf4jConfiguration { @Override public void setRootLoggerLevel(Level level) { - ch.qos.logback.classic.Level value; + String value; switch (level) { case DEBUG: - value = ch.qos.logback.classic.Level.DEBUG; + value = "debug"; break; case INFO: - value = ch.qos.logback.classic.Level.INFO; + value = "info"; break; default: - value = ch.qos.logback.classic.Level.ERROR; + value = "error"; break; } - ((ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME)).setLevel(value); + System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", value); } @Override - public void activate() {} + public void activate() { + ILoggerFactory lf = StaticLoggerBinder.getSingleton().getLoggerFactory(); + if (lf instanceof MvndLoggerFactory) { + ((MvndLoggerFactory) lf).reconfigure(); + } + } } diff --git a/logging/src/main/java/org/slf4j/impl/MvndDaemonLogger.java b/logging/src/main/java/org/slf4j/impl/MvndDaemonLogger.java new file mode 100644 index 000000000..02977aea4 --- /dev/null +++ b/logging/src/main/java/org/slf4j/impl/MvndDaemonLogger.java @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.slf4j.impl; + +import java.io.PrintStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; + +public class MvndDaemonLogger extends MvndBaseLogger { + + final DateTimeFormatter dateTimeFormatter = + new DateTimeFormatterBuilder().appendPattern("HH:mm:ss.SSS").toFormatter(); + + PrintStream printStream; + + public MvndDaemonLogger(String name) { + super(name); + } + + @Override + protected void doLog(int level, String message, Throwable t) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + pw.append(dateTimeFormatter.format(LocalTime.now())); + pw.append(" "); + switch (level) { + case LOG_LEVEL_ERROR: + pw.append("E"); + break; + case LOG_LEVEL_WARN: + pw.append("W"); + break; + case LOG_LEVEL_INFO: + pw.append("I"); + break; + case LOG_LEVEL_DEBUG: + pw.append("D"); + break; + case LOG_LEVEL_TRACE: + pw.append("T"); + break; + } + pw.append(" "); + pw.append(message); + if (t != null) { + t.printStackTrace(pw); + } + PrintStream printStream = MvndSimpleLogger.CONFIG_PARAMS.outputChoice.getTargetPrintStream(); + printStream.println(sw); + printStream.flush(); + } +} diff --git a/logging/src/main/java/org/slf4j/impl/MvndFailOnSeverityLogger.java b/logging/src/main/java/org/slf4j/impl/MvndFailOnSeverityLogger.java new file mode 100644 index 000000000..27b43fd68 --- /dev/null +++ b/logging/src/main/java/org/slf4j/impl/MvndFailOnSeverityLogger.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.slf4j.impl; + +import org.apache.maven.logwrapper.LogLevelRecorder; +import org.slf4j.event.Level; + +/** + * A proxy which enhances the MavenSimpleLogger with functionality to track whether a logging threshold is hit. + * Currently only support WARN and ERROR states, since it's been used for the --fail-on-severity flag. + */ +public class MvndFailOnSeverityLogger extends MvndSimpleLogger { + private final LogLevelRecorder logLevelRecorder; + + MvndFailOnSeverityLogger(String name, LogLevelRecorder logLevelRecorder) { + super(name); + this.logLevelRecorder = logLevelRecorder; + } + + /** + * A simple implementation which always logs messages of level WARN + * according to the format outlined above. + */ + @Override + public void warn(String msg) { + super.warn(msg); + logLevelRecorder.record(Level.WARN); + } + + /** + * Perform single parameter substitution before logging the message of level + * WARN according to the format outlined above. + */ + @Override + public void warn(String format, Object arg) { + super.warn(format, arg); + logLevelRecorder.record(Level.WARN); + } + + /** + * Perform double parameter substitution before logging the message of level + * WARN according to the format outlined above. + */ + @Override + public void warn(String format, Object arg1, Object arg2) { + super.warn(format, arg1, arg2); + logLevelRecorder.record(Level.WARN); + } + + /** + * Perform double parameter substitution before logging the message of level + * WARN according to the format outlined above. + */ + @Override + public void warn(String format, Object... argArray) { + super.warn(format, argArray); + logLevelRecorder.record(Level.WARN); + } + + /** Log a message of level WARN, including an exception. */ + @Override + public void warn(String msg, Throwable t) { + super.warn(msg, t); + logLevelRecorder.record(Level.WARN); + } + + /** + * A simple implementation which always logs messages of level ERROR + * according to the format outlined above. + */ + @Override + public void error(String msg) { + super.error(msg); + logLevelRecorder.record(Level.ERROR); + } + + /** + * Perform single parameter substitution before logging the message of level + * ERROR according to the format outlined above. + */ + @Override + public void error(String format, Object arg) { + super.error(format, arg); + logLevelRecorder.record(Level.ERROR); + } + + /** + * Perform double parameter substitution before logging the message of level + * ERROR according to the format outlined above. + */ + @Override + public void error(String format, Object arg1, Object arg2) { + super.error(format, arg1, arg2); + logLevelRecorder.record(Level.ERROR); + } + + /** + * Perform double parameter substitution before logging the message of level + * ERROR according to the format outlined above. + */ + @Override + public void error(String format, Object... argArray) { + super.error(format, argArray); + logLevelRecorder.record(Level.ERROR); + } + + /** Log a message of level ERROR, including an exception. */ + @Override + public void error(String msg, Throwable t) { + super.error(msg, t); + logLevelRecorder.record(Level.ERROR); + } +} diff --git a/logging/src/main/java/org/slf4j/impl/MvndLoggerFactory.java b/logging/src/main/java/org/slf4j/impl/MvndLoggerFactory.java new file mode 100644 index 000000000..7de5cba31 --- /dev/null +++ b/logging/src/main/java/org/slf4j/impl/MvndLoggerFactory.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.slf4j.impl; + +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.apache.maven.logwrapper.LogLevelRecorder; +import org.apache.maven.logwrapper.MavenSlf4jWrapperFactory; +import org.slf4j.Logger; + +/** + * LogFactory for Maven which can create a simple logger or one which, if set, fails the build on a severity threshold. + */ +public class MvndLoggerFactory implements MavenSlf4jWrapperFactory { + private LogLevelRecorder logLevelRecorder = null; + private final ConcurrentMap loggerMap = new ConcurrentHashMap<>(); + + public MvndLoggerFactory() { + MvndSimpleLogger.lazyInit(); + } + + @Override + public void setLogLevelRecorder(LogLevelRecorder logLevelRecorder) { + if (this.logLevelRecorder != null) { + throw new IllegalStateException("LogLevelRecorder has already been set."); + } + + this.logLevelRecorder = logLevelRecorder; + } + + @Override + public Optional getLogLevelRecorder() { + return Optional.ofNullable(logLevelRecorder); + } + + /** + * Return an appropriate {@link Logger} instance by name. + */ + @Override + public Logger getLogger(String name) { + return loggerMap.computeIfAbsent(name, this::getNewLoggingInstance); + } + + private Logger getNewLoggingInstance(String name) { + if (name.startsWith("org.mvndaemon.mvnd.daemon")) { + return new MvndDaemonLogger(name); + } else if (logLevelRecorder == null) { + return new MvndSimpleLogger(name); + } else { + return new MvndFailOnSeverityLogger(name, logLevelRecorder); + } + } + + public void reconfigure() { + SimpleLoggerConfiguration config = MvndSimpleLogger.CONFIG_PARAMS; + config.init(); + loggerMap.values().forEach(l -> { + if (l instanceof MvndSimpleLogger) { + ((MvndSimpleLogger) l).configure(config.defaultLogLevel); + } + }); + } +} diff --git a/logging/src/main/java/org/slf4j/impl/MvndSimpleLogger.java b/logging/src/main/java/org/slf4j/impl/MvndSimpleLogger.java new file mode 100644 index 000000000..f2041a53f --- /dev/null +++ b/logging/src/main/java/org/slf4j/impl/MvndSimpleLogger.java @@ -0,0 +1,236 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.slf4j.impl; + +import java.util.Date; +import java.util.function.Consumer; + +import org.apache.maven.shared.utils.logging.MessageBuilder; +import org.apache.maven.shared.utils.logging.MessageUtils; + +import static org.apache.maven.shared.utils.logging.MessageUtils.level; + +/** + * Logger for Maven, that support colorization of levels and stacktraces. This class implements 2 methods introduced in + * slf4j-simple provider local copy. + * + * @since 3.5.0 + */ +public class MvndSimpleLogger extends MvndBaseLogger { + + static final String TID_PREFIX = "tid="; + + static long START_TIME = System.currentTimeMillis(); + + static boolean INITIALIZED = false; + static final SimpleLoggerConfiguration CONFIG_PARAMS = new SimpleLoggerConfiguration(); + + static void lazyInit() { + if (INITIALIZED) { + return; + } + INITIALIZED = true; + init(); + } + + // external software might be invoking this method directly. Do not rename + // or change its semantics. + static void init() { + CONFIG_PARAMS.init(); + } + + static Consumer LOG_SINK; + + public static void setLogSink(Consumer logSink) { + LOG_SINK = logSink; + } + + /** The short name of this simple log instance */ + private transient String shortLogName = null; + + MvndSimpleLogger(String name) { + super(name); + configure(CONFIG_PARAMS.defaultLogLevel); + } + + String recursivelyComputeLevelString() { + String tempName = name; + String levelString = null; + int indexOfLastDot = tempName.length(); + while ((levelString == null) && (indexOfLastDot > -1)) { + tempName = tempName.substring(0, indexOfLastDot); + levelString = CONFIG_PARAMS.getStringProperty(SimpleLogger.LOG_KEY_PREFIX + tempName, null); + indexOfLastDot = tempName.lastIndexOf("."); + } + return levelString; + } + + @Override + protected void doLog(int level, String message, Throwable t) { + StringBuilder buf = new StringBuilder(32); + + // Append date-time if so configured + if (CONFIG_PARAMS.showDateTime) { + if (CONFIG_PARAMS.dateFormatter != null) { + buf.append(getFormattedDate()); + buf.append(' '); + } else { + buf.append(System.currentTimeMillis() - START_TIME); + buf.append(' '); + } + } + + // Append current thread name if so configured + if (CONFIG_PARAMS.showThreadName) { + buf.append('['); + buf.append(Thread.currentThread().getName()); + buf.append("] "); + } + + if (CONFIG_PARAMS.showThreadId) { + buf.append(TID_PREFIX); + buf.append(Thread.currentThread().getId()); + buf.append(' '); + } + + if (CONFIG_PARAMS.levelInBrackets) buf.append('['); + + // Append a readable representation of the log level + String levelStr = renderLevel(level); + buf.append(levelStr); + if (CONFIG_PARAMS.levelInBrackets) buf.append(']'); + buf.append(' '); + + // Append the name of the log instance if so configured + if (CONFIG_PARAMS.showShortLogName) { + if (shortLogName == null) shortLogName = computeShortName(); + buf.append(String.valueOf(shortLogName)).append(" - "); + } else if (CONFIG_PARAMS.showLogName) { + buf.append(String.valueOf(name)).append(" - "); + } + + // Append the message + buf.append(message); + + writeThrowable(t, buf); + + Consumer sink = LOG_SINK; + if (sink != null) { + sink.accept(buf.toString()); + } else { + CONFIG_PARAMS.outputChoice.getTargetPrintStream().println(buf.toString()); + } + } + + protected String getFormattedDate() { + Date now = new Date(); + return CONFIG_PARAMS.dateFormatter.format(now); + } + + private String computeShortName() { + return name.substring(name.lastIndexOf(".") + 1); + } + + protected String renderLevel(int level) { + switch (level) { + case LOG_LEVEL_TRACE: + return level().debug("TRACE").toString(); + case LOG_LEVEL_DEBUG: + return level().debug("DEBUG").toString(); + case LOG_LEVEL_INFO: + return level().info("INFO").toString(); + case LOG_LEVEL_WARN: + return level().warning("WARNING").toString(); + case LOG_LEVEL_ERROR: + default: + return level().error("ERROR").toString(); + } + } + + protected void writeThrowable(Throwable t, StringBuilder sb) { + if (t == null) { + return; + } + MessageBuilder builder = MessageUtils.buffer(sb); + builder.failure(t.getClass().getName()); + if (t.getMessage() != null) { + builder.a(": "); + builder.failure(t.getMessage()); + } + builder.newline(); + + printStackTrace(t, builder, ""); + } + + private void printStackTrace(Throwable t, MessageBuilder builder, String prefix) { + for (StackTraceElement e : t.getStackTrace()) { + builder.a(prefix); + builder.a(" "); + builder.strong("at"); + builder.a(" " + e.getClassName() + "." + e.getMethodName()); + builder.a(" (").strong(getLocation(e)).a(")"); + builder.newline(); + } + for (Throwable se : t.getSuppressed()) { + writeThrowable(se, builder, "Suppressed", prefix + " "); + } + Throwable cause = t.getCause(); + if (cause != null) { + writeThrowable(cause, builder, "Caused by", prefix); + } + } + + private void writeThrowable(Throwable t, MessageBuilder builder, String caption, String prefix) { + builder.a(prefix).strong(caption).a(": ").a(t.getClass().getName()); + if (t.getMessage() != null) { + builder.a(": "); + builder.failure(t.getMessage()); + } + builder.newline(); + + printStackTrace(t, builder, prefix); + } + + protected String getLocation(final StackTraceElement e) { + assert e != null; + + if (e.isNativeMethod()) { + return "Native Method"; + } else if (e.getFileName() == null) { + return "Unknown Source"; + } else if (e.getLineNumber() >= 0) { + return String.format("%s:%s", e.getFileName(), e.getLineNumber()); + } else { + return e.getFileName(); + } + } + + public void configure(int defaultLogLevel) { + String levelString = recursivelyComputeLevelString(); + if (levelString != null) { + this.currentLogLevel = SimpleLoggerConfiguration.stringToLevel(levelString); + } else { + this.currentLogLevel = defaultLogLevel; + } + } + + public void setLogLevel(int logLevel) { + this.currentLogLevel = logLevel; + } +} diff --git a/logging/src/main/java/org/slf4j/impl/StaticLoggerBinder.java b/logging/src/main/java/org/slf4j/impl/StaticLoggerBinder.java new file mode 100644 index 000000000..2ebf87ba2 --- /dev/null +++ b/logging/src/main/java/org/slf4j/impl/StaticLoggerBinder.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.slf4j.impl; + +import org.slf4j.ILoggerFactory; +import org.slf4j.spi.LoggerFactoryBinder; + +/** + * SLF4J LoggerFactoryBinder implementation using MavenSimpleLogger. + * This class is part of the required classes used to specify an + * SLF4J logger provider implementation. + * + * @since 3.5.1 + */ +public final class StaticLoggerBinder implements LoggerFactoryBinder { + /** + * Declare the version of the SLF4J API this implementation is compiled + * against. The value of this field is usually modified with each release. + */ + // to avoid constant folding by the compiler, this field must *not* be final + @SuppressWarnings({"checkstyle:staticvariablename", "checkstyle:visibilitymodifier"}) + public static String REQUESTED_API_VERSION = "1.7.25"; // !final + + private static final String LOGGER_FACTORY_CLASS_STR = MvndLoggerFactory.class.getName(); + + /** + * The unique instance of this class. + */ + private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder(); + + /** + * The ILoggerFactory instance returned by the {@link #getLoggerFactory} + * method should always be the same object + */ + private final ILoggerFactory loggerFactory; + + /** + * Private constructor to prevent instantiation + */ + private StaticLoggerBinder() { + loggerFactory = new MvndLoggerFactory(); + } + + /** + * Returns the singleton of this class. + */ + public static StaticLoggerBinder getSingleton() { + return SINGLETON; + } + + /** + * Returns the factory. + */ + @Override + public ILoggerFactory getLoggerFactory() { + return loggerFactory; + } + + /** + * Returns the class name. + */ + @Override + public String getLoggerFactoryClassStr() { + return LOGGER_FACTORY_CLASS_STR; + } +} diff --git a/logging/src/main/java/org/slf4j/impl/StaticMDCBinder.java b/logging/src/main/java/org/slf4j/impl/StaticMDCBinder.java new file mode 100644 index 000000000..c264b1d1b --- /dev/null +++ b/logging/src/main/java/org/slf4j/impl/StaticMDCBinder.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.slf4j.impl; + +import org.slf4j.helpers.BasicMDCAdapter; +import org.slf4j.spi.MDCAdapter; + +/** + * This implementation is bound to {@link BasicMDCAdapter}. + */ +public class StaticMDCBinder { + + /** + * The unique instance of this class. + */ + public static final StaticMDCBinder SINGLETON = new StaticMDCBinder(); + + private StaticMDCBinder() {} + + /** + * Return the singleton of this class. + * + * @return the StaticMDCBinder singleton + * @since 1.7.14 + */ + public static final StaticMDCBinder getSingleton() { + return SINGLETON; + } + + /** + * Currently this method always returns an instance of + * {@link StaticMDCBinder}. + */ + public MDCAdapter getMDCA() { + return new BasicMDCAdapter(); + } + + public String getMDCAdapterClassStr() { + return BasicMDCAdapter.class.getName(); + } +} diff --git a/logging/src/main/resources/META-INF/maven/slf4j-configuration.properties b/logging/src/main/resources/META-INF/maven/slf4j-configuration.properties new file mode 100644 index 000000000..ee6529b86 --- /dev/null +++ b/logging/src/main/resources/META-INF/maven/slf4j-configuration.properties @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. + +# key = Slf4j effective logger factory implementation +# value = corresponding o.a.m.cli.logging.Slf4jConfiguration class +org.slf4j.impl.MvndLoggerFactory org.slf4j.impl.MvndConfiguration diff --git a/pom.xml b/pom.xml index 03456330a..ae3a09382 100644 --- a/pom.xml +++ b/pom.xml @@ -87,7 +87,6 @@ 2.4.0 3.23.0 5.9.2 - 1.2.11 4.0.0-alpha-7 3.9.3 ${maven.version} @@ -122,16 +121,6 @@ - - ch.qos.logback - logback-classic - ${logback.version} - - - ch.qos.logback - logback-core - ${logback.version} - org.slf4j slf4j-api