From 74b2ffccf4b32b3924e7644f732896008e9e8f61 Mon Sep 17 00:00:00 2001 From: Guillaume Nodet Date: Thu, 10 Oct 2024 07:29:23 +0200 Subject: [PATCH] Improve log and leverage the new infrastructure in Maven --- .../mvndaemon/mvnd/client/DefaultClient.java | 5 - .../mvnd/client/DaemonConnector.java | 4 +- .../mvndaemon/mvnd/common/Environment.java | 4 - .../org/mvndaemon/mvnd/common/Message.java | 4 +- .../cli/CommonsCliDaemonMavenOptions.java | 11 - .../java/org/apache/maven/cli/DaemonCli.java | 11 +- .../apache/maven/cli/DaemonMavenCling.java | 64 +-- .../apache/maven/cli/DaemonMavenInvoker.java | 89 ++-- .../apache/maven/cli/DaemonMavenOptions.java | 5 - .../DaemonPlexusContainerCapsuleFactory.java | 8 - .../mvnd/daemon/ClientDispatcher.java | 4 +- .../org/mvndaemon/mvnd/daemon/Server.java | 24 +- .../mvnd/interactivity/DaemonPrompter.java | 2 +- .../transfer/DaemonMavenTransferListener.java | 72 --- .../main/distro/bin/mvnd-bash-completion.bash | 4 +- dist/src/main/provisio/maven-distro.xml | 2 +- integration-tests/pom.xml | 2 +- .../mvndaemon/mvnd/it/MaxHeapNativeIT.java | 10 +- logging/pom.xml | 4 + .../mvnd/logging/internal/Slf4jLogger.java | 144 ------ .../logging/internal/Slf4jLoggerManager.java | 99 ---- .../mvnd/logging/slf4j/MvndBaseLogger.java | 466 ------------------ .../mvnd/logging/slf4j/MvndConfiguration.java | 52 -- .../mvnd/logging/slf4j/MvndDaemonLogger.java | 28 +- .../slf4j/MvndFailOnSeverityLogger.java | 129 ----- .../mvnd/logging/slf4j/MvndLoggerFactory.java | 53 +- .../logging/slf4j/MvndServiceProvider.java | 65 --- .../mvnd/logging/slf4j/MvndSimpleLogger.java | 171 ------- .../mvnd/logging/slf4j/OutputChoice.java | 75 --- .../slf4j/SimpleLoggerConfiguration.java | 207 -------- .../logging/smart/BuildEventListener.java | 79 --- .../smart/LoggingExecutionListener.java | 195 -------- .../logging/smart/LoggingOutputStream.java | 97 ---- .../smart/ProjectBuildLogAppender.java | 88 ---- .../maven/slf4j-configuration.properties | 2 +- .../org.apache.maven.slf4j.MavenLoggerFactory | 1 + .../org.slf4j.spi.SLF4JServiceProvider | 1 - pom.xml | 17 +- 38 files changed, 134 insertions(+), 2164 deletions(-) delete mode 100644 daemon/src/main/java/org/mvndaemon/mvnd/transfer/DaemonMavenTransferListener.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/internal/Slf4jLogger.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/internal/Slf4jLoggerManager.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndBaseLogger.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndConfiguration.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndFailOnSeverityLogger.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndServiceProvider.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndSimpleLogger.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/OutputChoice.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/SimpleLoggerConfiguration.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/smart/BuildEventListener.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/smart/LoggingExecutionListener.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/smart/LoggingOutputStream.java delete mode 100644 logging/src/main/java/org/mvndaemon/mvnd/logging/smart/ProjectBuildLogAppender.java create mode 100644 logging/src/main/resources/META-INF/services/org.apache.maven.slf4j.MavenLoggerFactory delete mode 100644 logging/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider 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 5bd230557..7d9a2faa7 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 @@ -323,11 +323,6 @@ public ExecutionResult execute(ClientOutput output, List argv) { return DefaultResult.success(argv); } - // Raw streams - if (Environment.MVND_RAW_STREAMS.removeCommandLineOption(args) != null) { - args.add("-D" + Environment.MVND_RAW_STREAMS.getProperty()); - } - Optional threads = Optional.ofNullable(Environment.MVND_THREADS.removeCommandLineOption(args)); Environment.MVND_THREADS.addCommandLineOption(args, threads.orElseGet(parameters::threads)); 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 8367f06c0..946f70f87 100644 --- a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonConnector.java +++ b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonConnector.java @@ -42,6 +42,7 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +import org.apache.maven.slf4j.MavenSimpleLogger; import org.mvndaemon.mvnd.common.DaemonCompatibilitySpec; import org.mvndaemon.mvnd.common.DaemonCompatibilitySpec.Result; import org.mvndaemon.mvnd.common.DaemonConnection; @@ -55,7 +56,6 @@ import org.mvndaemon.mvnd.common.Os; import org.mvndaemon.mvnd.common.SocketFamily; import org.mvndaemon.mvnd.common.logging.ClientOutput; -import org.mvndaemon.mvnd.logging.slf4j.MvndBaseLogger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -434,7 +434,7 @@ 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" + MvndBaseLogger.LOG_FILE_KEY + "=" + args.add("-D" + MavenSimpleLogger.LOG_FILE_KEY + "=" + parameters.daemonStorage().resolve("daemon-" + daemonId + ".log")); Environment.MVND_JAVA_HOME.addSystemProperty( 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 3132006f0..8378f4d57 100644 --- a/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java +++ b/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java @@ -296,10 +296,6 @@ public enum Environment { * start with 'glob:**/' to support any location of the local repository. */ MVND_PLUGIN_REALM_EVICT_PATTERN("mvnd.pluginRealmEvictPattern", null, "", OptionType.STRING, Flags.OPTIONAL), - /** - * Whether or not decorate output and error streams - **/ - MVND_RAW_STREAMS("mvnd.rawStreams", null, Boolean.FALSE, OptionType.VOID, Flags.OPTIONAL, "mvnd:--raw-streams"), /** * Overall timeout to connect to a daemon. */ diff --git a/common/src/main/java/org/mvndaemon/mvnd/common/Message.java b/common/src/main/java/org/mvndaemon/mvnd/common/Message.java index 8b4897bf4..89af9b75d 100644 --- a/common/src/main/java/org/mvndaemon/mvnd/common/Message.java +++ b/common/src/main/java/org/mvndaemon/mvnd/common/Message.java @@ -986,8 +986,8 @@ public String toString() { + repositoryUrl + '\'' + ", resourceName='" + resourceName + '\'' + ", contentLength=" + contentLength + ", transferredBytes=" - + transferredBytes + ", exception='" - + exception + '\'' + '}'; + + transferredBytes + + (exception != null ? ", exception='" + exception + '\'' : "") + '}'; } private String mnemonic() { diff --git a/daemon/src/main/java/org/apache/maven/cli/CommonsCliDaemonMavenOptions.java b/daemon/src/main/java/org/apache/maven/cli/CommonsCliDaemonMavenOptions.java index b4ae08868..b66ad5e01 100644 --- a/daemon/src/main/java/org/apache/maven/cli/CommonsCliDaemonMavenOptions.java +++ b/daemon/src/main/java/org/apache/maven/cli/CommonsCliDaemonMavenOptions.java @@ -22,7 +22,6 @@ import java.util.List; import java.util.ListIterator; import java.util.Map; -import java.util.Optional; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; @@ -31,7 +30,6 @@ import org.apache.maven.cling.invoker.mvn.CommonsCliMavenOptions; import org.codehaus.plexus.interpolation.BasicInterpolator; import org.codehaus.plexus.interpolation.InterpolationException; -import org.mvndaemon.mvnd.common.Environment; import static org.apache.maven.cling.invoker.Utils.createInterpolator; @@ -49,15 +47,6 @@ public org.apache.commons.cli.Options getOptions() { return this.cliManager.getOptions(); } - @Override - public Optional rawStreams() { - if (commandLine.hasOption(CLIManager.RAW_STREAMS) - || Environment.MVND_RAW_STREAMS.asOptional().isPresent()) { - return Optional.of(Boolean.TRUE); - } - return Optional.empty(); - } - private static CommonsCliDaemonMavenOptions interpolate( CommonsCliDaemonMavenOptions options, Collection> properties) { try { diff --git a/daemon/src/main/java/org/apache/maven/cli/DaemonCli.java b/daemon/src/main/java/org/apache/maven/cli/DaemonCli.java index b474e1dab..0486ff34d 100644 --- a/daemon/src/main/java/org/apache/maven/cli/DaemonCli.java +++ b/daemon/src/main/java/org/apache/maven/cli/DaemonCli.java @@ -18,20 +18,25 @@ */ package org.apache.maven.cli; +import java.io.InputStream; +import java.io.OutputStream; import java.util.List; import java.util.Map; -import org.mvndaemon.mvnd.logging.smart.BuildEventListener; +import org.apache.maven.logging.BuildEventListener; /** * Simple interface to bridge maven 3.9.x and 4.0.x CLI */ -public interface DaemonCli extends AutoCloseable { +public interface DaemonCli { int main( List args, String workingDir, String projectDir, Map env, - BuildEventListener buildEventListener) + BuildEventListener buildEventListener, + InputStream in, + OutputStream out, + OutputStream err) throws Exception; } diff --git a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCling.java b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCling.java index 835275667..aded3ca44 100644 --- a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCling.java +++ b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenCling.java @@ -18,9 +18,8 @@ */ package org.apache.maven.cli; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.nio.charset.StandardCharsets; +import java.io.InputStream; +import java.io.OutputStream; import java.nio.file.Paths; import java.util.List; import java.util.Map; @@ -29,30 +28,12 @@ import org.apache.maven.api.cli.ParserRequest; import org.apache.maven.cling.invoker.ProtoLogger; import org.apache.maven.cling.invoker.ProtoLookup; -import org.apache.maven.jline.MessageUtils; +import org.apache.maven.logging.BuildEventListener; import org.codehaus.plexus.classworlds.ClassWorld; import org.codehaus.plexus.classworlds.realm.ClassRealm; -import org.jline.terminal.Terminal; -import org.jline.terminal.impl.ExternalTerminal; import org.mvndaemon.mvnd.cli.EnvHelper; -import org.mvndaemon.mvnd.logging.smart.BuildEventListener; public class DaemonMavenCling implements DaemonCli { - private final DaemonMavenParser parser; - private final DaemonMavenInvoker invoker; - - public DaemonMavenCling() { - this.parser = new DaemonMavenParser(); - this.invoker = new DaemonMavenInvoker(ProtoLookup.builder() - .addMapping( - ClassWorld.class, ((ClassRealm) Thread.currentThread().getContextClassLoader()).getWorld()) - .build()); - } - - @Override - public void close() throws Exception { - invoker.close(); - } @Override public int main( @@ -60,25 +41,32 @@ public int main( String workingDir, String projectDir, Map env, - BuildEventListener buildEventListener) + BuildEventListener buildEventListener, + InputStream in, + OutputStream out, + OutputStream err) throws Exception { - Terminal terminal = new ExternalTerminal( - "Maven", - "ansi", - new ByteArrayInputStream(new byte[0]), - new ByteArrayOutputStream(), - StandardCharsets.UTF_8); - MessageUtils.systemInstall(terminal); EnvHelper.environment(workingDir, env); System.setProperty("maven.multiModuleProjectDirectory", projectDir); - return invoker.invoke(parser.parse(ParserRequest.builder( - "mvnd", "Maven Daemon", args, new ProtoLogger(), new DaemonMessageBuilderFactory()) - .cwd(Paths.get(workingDir)) - .lookup(ProtoLookup.builder() - .addMapping(Environment.class, () -> env) - .addMapping(BuildEventListener.class, buildEventListener) - .build()) - .build())); + + try (DaemonMavenInvoker invoker = new DaemonMavenInvoker(ProtoLookup.builder() + .addMapping( + ClassWorld.class, ((ClassRealm) Thread.currentThread().getContextClassLoader()).getWorld()) + .addMapping(BuildEventListener.class, buildEventListener) + .build())) { + DaemonMavenParser parser = new DaemonMavenParser(); + return invoker.invoke(parser.parse(ParserRequest.builder( + "mvnd", "Maven Daemon", args, new ProtoLogger(), new DaemonMessageBuilderFactory()) + .cwd(Paths.get(workingDir)) + .in(in) + .out(out) + .err(err) + .lookup(ProtoLookup.builder() + .addMapping(Environment.class, () -> env) + .addMapping(BuildEventListener.class, buildEventListener) + .build()) + .build())); + } } /** diff --git a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenInvoker.java b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenInvoker.java index a34f4f205..7afe41de2 100644 --- a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenInvoker.java +++ b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenInvoker.java @@ -18,23 +18,24 @@ */ package org.apache.maven.cli; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; + import org.apache.maven.api.cli.Options; import org.apache.maven.api.cli.mvn.MavenInvokerRequest; import org.apache.maven.api.cli.mvn.MavenOptions; -import org.apache.maven.cli.event.ExecutionEventLogger; +import org.apache.maven.api.services.MavenException; import org.apache.maven.cling.invoker.ContainerCapsuleFactory; import org.apache.maven.cling.invoker.ProtoLookup; import org.apache.maven.cling.invoker.mvn.resident.DefaultResidentMavenInvoker; -import org.apache.maven.execution.ExecutionListener; import org.apache.maven.jline.MessageUtils; -import org.eclipse.aether.transfer.TransferListener; +import org.apache.maven.logging.BuildEventListener; +import org.apache.maven.logging.LoggingOutputStream; +import org.jline.terminal.Terminal; +import org.jline.terminal.impl.ExternalTerminal; import org.mvndaemon.mvnd.common.Environment; -import org.mvndaemon.mvnd.logging.slf4j.MvndSimpleLogger; -import org.mvndaemon.mvnd.logging.smart.BuildEventListener; -import org.mvndaemon.mvnd.logging.smart.LoggingExecutionListener; -import org.mvndaemon.mvnd.logging.smart.LoggingOutputStream; -import org.mvndaemon.mvnd.transfer.DaemonMavenTransferListener; -import org.slf4j.spi.LocationAwareLogger; public class DaemonMavenInvoker extends DefaultResidentMavenInvoker { public DaemonMavenInvoker(ProtoLookup protoLookup) { @@ -44,25 +45,54 @@ public DaemonMavenInvoker(ProtoLookup protoLookup) { @Override protected void configureLogging(LocalContext context) throws Exception { super.configureLogging(context); + } + + @Override + protected Terminal createTerminal(LocalContext context) { + try { + Terminal terminal = new ExternalTerminal( + "Maven", + "ansi", + context.invokerRequest.in().get(), + context.invokerRequest.out().get(), + StandardCharsets.UTF_8); + doConfigureWithTerminal(context, terminal); + // If raw-streams options has been set, we need to decorate to push back to the client + if (context.invokerRequest.options().rawStreams().orElse(false)) { + BuildEventListener bel = determineBuildEventListener(context); + OutputStream out = context.invokerRequest.out().orElse(null); + System.setOut(out != null ? printStream(out) : new LoggingOutputStream(bel::log).printStream()); + OutputStream err = context.invokerRequest.err().orElse(null); + System.setErr(err != null ? printStream(err) : new LoggingOutputStream(bel::log).printStream()); + } + return terminal; + } catch (IOException e) { + throw new MavenException("Error creating terminal", e); + } + } - DaemonMavenOptions options = (DaemonMavenOptions) context.invokerRequest.options(); - if (options.logFile().isEmpty() && !options.rawStreams().orElse(false)) { - MvndSimpleLogger stdout = (MvndSimpleLogger) context.loggerFactory.getLogger("stdout"); - MvndSimpleLogger stderr = (MvndSimpleLogger) context.loggerFactory.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()); + private PrintStream printStream(OutputStream outputStream) { + if (outputStream instanceof LoggingOutputStream los) { + return los.printStream(); + } else if (outputStream instanceof PrintStream ps) { + return ps; + } else { + return new PrintStream(outputStream); } } + @Override + protected org.apache.maven.logging.BuildEventListener doDetermineBuildEventListener(LocalContext context) { + return protoLookup.lookup(BuildEventListener.class); + } + @Override protected void helpOrVersionAndMayExit(LocalContext context) throws Exception { MavenInvokerRequest invokerRequest = context.invokerRequest; BuildEventListener buildEventListener = context.invokerRequest.parserRequest().lookup().lookup(BuildEventListener.class); if (invokerRequest.options().help().isPresent()) { - // TODO: ugly, clenup + // TODO: ugly, cleanup buildEventListener.log( MvndHelpFormatter.displayHelp((CommonsCliDaemonMavenOptions) context.invokerRequest.options())); throw new ExitException(0); @@ -95,29 +125,6 @@ protected void preCommands(LocalContext context) throws Exception { return new DaemonPlexusContainerCapsuleFactory(); } - @Override - protected ExecutionListener determineExecutionListener(LocalContext context) { - if (context.lookup != null) { - LoggingExecutionListener listener = context.lookup.lookup(LoggingExecutionListener.class); - ExecutionEventLogger executionEventLogger = - new ExecutionEventLogger(context.invokerRequest.messageBuilderFactory()); - listener.init( - context.eventSpyDispatcher.chainListener(executionEventLogger), - context.invokerRequest.parserRequest().lookup().lookup(BuildEventListener.class)); - return listener; - } else { - // this branch happens in "early" step of container capsule to load extensions - return super.determineExecutionListener(context); - } - } - - @Override - protected TransferListener determineTransferListener(LocalContext context, boolean noTransferProgress) { - return new DaemonMavenTransferListener( - context.invokerRequest.parserRequest().lookup().lookup(BuildEventListener.class), - super.determineTransferListener(context, noTransferProgress)); - } - @Override protected int doExecute(LocalContext context) throws Exception { context.logger.info(MessageUtils.builder() diff --git a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenOptions.java b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenOptions.java index 9199de678..969bf8d24 100644 --- a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenOptions.java +++ b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenOptions.java @@ -20,15 +20,10 @@ import java.util.Collection; import java.util.Map; -import java.util.Optional; import org.apache.maven.api.cli.mvn.MavenOptions; public interface DaemonMavenOptions extends MavenOptions { - /** - * Should use raw-streams to communicate with daemon. - */ - Optional rawStreams(); @Override DaemonMavenOptions interpolate(Collection> properties); diff --git a/daemon/src/main/java/org/apache/maven/cli/DaemonPlexusContainerCapsuleFactory.java b/daemon/src/main/java/org/apache/maven/cli/DaemonPlexusContainerCapsuleFactory.java index bda70778e..3c213e083 100644 --- a/daemon/src/main/java/org/apache/maven/cli/DaemonPlexusContainerCapsuleFactory.java +++ b/daemon/src/main/java/org/apache/maven/cli/DaemonPlexusContainerCapsuleFactory.java @@ -27,19 +27,11 @@ import org.apache.maven.api.cli.mvn.MavenOptions; import org.apache.maven.cling.invoker.PlexusContainerCapsuleFactory; import org.apache.maven.cling.invoker.mvn.resident.DefaultResidentMavenInvoker; -import org.codehaus.plexus.logging.LoggerManager; import org.mvndaemon.mvnd.common.Environment; -import org.mvndaemon.mvnd.logging.internal.Slf4jLoggerManager; public class DaemonPlexusContainerCapsuleFactory extends PlexusContainerCapsuleFactory< MavenOptions, MavenInvokerRequest, DefaultResidentMavenInvoker.LocalContext> { - private final Slf4jLoggerManager slf4jLoggerManager = new Slf4jLoggerManager(); - - @Override - protected LoggerManager createLoggerManager() { - return slf4jLoggerManager; - } @Override protected List parseExtClasspath(DefaultResidentMavenInvoker.LocalContext context) throws Exception { diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/daemon/ClientDispatcher.java b/daemon/src/main/java/org/mvndaemon/mvnd/daemon/ClientDispatcher.java index f9bb805c1..e262d1ec9 100644 --- a/daemon/src/main/java/org/mvndaemon/mvnd/daemon/ClientDispatcher.java +++ b/daemon/src/main/java/org/mvndaemon/mvnd/daemon/ClientDispatcher.java @@ -29,6 +29,7 @@ import io.takari.maven.builder.smart.DependencyGraph; import org.apache.maven.execution.ExecutionEvent; import org.apache.maven.execution.MavenSession; +import org.apache.maven.logging.BuildEventListener; import org.apache.maven.plugin.MojoExecution; import org.apache.maven.project.MavenProject; import org.eclipse.aether.transfer.TransferEvent; @@ -37,12 +38,11 @@ import org.mvndaemon.mvnd.common.Message; import org.mvndaemon.mvnd.common.Message.BuildException; import org.mvndaemon.mvnd.common.Message.BuildStarted; -import org.mvndaemon.mvnd.logging.smart.BuildEventListener; /** * Sends events back to the client. */ -public class ClientDispatcher extends BuildEventListener { +public class ClientDispatcher implements BuildEventListener { private final Collection queue; private static final Pattern TRAILING_EOLS_PATTERN = Pattern.compile("[\r\n]+$"); diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/daemon/Server.java b/daemon/src/main/java/org/mvndaemon/mvnd/daemon/Server.java index af3a75377..290ca27af 100644 --- a/daemon/src/main/java/org/mvndaemon/mvnd/daemon/Server.java +++ b/daemon/src/main/java/org/mvndaemon/mvnd/daemon/Server.java @@ -52,6 +52,9 @@ import io.takari.maven.builder.smart.SmartBuilder; import org.apache.maven.cli.DaemonCli; +import org.apache.maven.logging.BuildEventListener; +import org.apache.maven.logging.LoggingOutputStream; +import org.apache.maven.logging.ProjectBuildLogAppender; import org.mvndaemon.mvnd.common.DaemonConnection; import org.mvndaemon.mvnd.common.DaemonException; import org.mvndaemon.mvnd.common.DaemonExpirationStatus; @@ -67,9 +70,6 @@ import org.mvndaemon.mvnd.common.SocketFamily; import org.mvndaemon.mvnd.daemon.DaemonExpiration.DaemonExpirationResult; import org.mvndaemon.mvnd.daemon.DaemonExpiration.DaemonExpirationStrategy; -import org.mvndaemon.mvnd.logging.smart.BuildEventListener; -import org.mvndaemon.mvnd.logging.smart.LoggingOutputStream; -import org.mvndaemon.mvnd.logging.smart.ProjectBuildLogAppender; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -187,11 +187,7 @@ public void close() { try { registry.close(); } finally { - try { - socket.close(); - } finally { - cli.close(); - } + socket.close(); } } } @@ -509,7 +505,7 @@ private void handle(DaemonConnection connection, BuildRequest buildRequest) { final BuildEventListener buildEventListener = new ClientDispatcher(sendQueue); final DaemonInputStream daemonInputStream = new DaemonInputStream(projectId -> sendQueue.add(Message.requestInput(projectId))); - try (ProjectBuildLogAppender logAppender = new ProjectBuildLogAppender(buildEventListener)) { + try { LOGGER.info("Executing request"); @@ -610,15 +606,17 @@ public T request(Message request, Class responseType, Pre } } }); - System.setIn(daemonInputStream); - System.setOut(new LoggingOutputStream(s -> sendQueue.add(Message.out(s))).printStream()); - System.setErr(new LoggingOutputStream(s -> sendQueue.add(Message.err(s))).printStream()); + LoggingOutputStream output = new LoggingOutputStream(s -> sendQueue.add(Message.out(s))); + LoggingOutputStream error = new LoggingOutputStream(s -> sendQueue.add(Message.err(s))); int exitCode = cli.main( buildRequest.getArgs(), buildRequest.getWorkingDir(), buildRequest.getProjectDir(), buildRequest.getEnv(), - buildEventListener); + buildEventListener, + daemonInputStream, + output, + error); LOGGER.info("Build finished, finishing message dispatch"); buildEventListener.finish(exitCode); } catch (Throwable t) { diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/interactivity/DaemonPrompter.java b/daemon/src/main/java/org/mvndaemon/mvnd/interactivity/DaemonPrompter.java index 56ef25d5b..ff26a52c1 100644 --- a/daemon/src/main/java/org/mvndaemon/mvnd/interactivity/DaemonPrompter.java +++ b/daemon/src/main/java/org/mvndaemon/mvnd/interactivity/DaemonPrompter.java @@ -26,6 +26,7 @@ import java.util.Objects; import java.util.UUID; +import org.apache.maven.logging.ProjectBuildLogAppender; import org.codehaus.plexus.components.interactivity.AbstractInputHandler; import org.codehaus.plexus.components.interactivity.InputHandler; import org.codehaus.plexus.components.interactivity.OutputHandler; @@ -35,7 +36,6 @@ import org.eclipse.sisu.Typed; import org.mvndaemon.mvnd.common.Message; import org.mvndaemon.mvnd.daemon.Connection; -import org.mvndaemon.mvnd.logging.smart.ProjectBuildLogAppender; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/transfer/DaemonMavenTransferListener.java b/daemon/src/main/java/org/mvndaemon/mvnd/transfer/DaemonMavenTransferListener.java deleted file mode 100644 index 4f80721d3..000000000 --- a/daemon/src/main/java/org/mvndaemon/mvnd/transfer/DaemonMavenTransferListener.java +++ /dev/null @@ -1,72 +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.transfer; - -import org.eclipse.aether.transfer.TransferCancelledException; -import org.eclipse.aether.transfer.TransferEvent; -import org.eclipse.aether.transfer.TransferListener; -import org.mvndaemon.mvnd.logging.smart.BuildEventListener; -import org.mvndaemon.mvnd.logging.smart.ProjectBuildLogAppender; - -public class DaemonMavenTransferListener implements TransferListener { - - private final BuildEventListener dispatcher; - private final TransferListener delegate; - - public DaemonMavenTransferListener(BuildEventListener dispatcher, TransferListener delegate) { - this.dispatcher = dispatcher; - this.delegate = delegate; - } - - @Override - public void transferInitiated(TransferEvent event) throws TransferCancelledException { - dispatcher.transfer(ProjectBuildLogAppender.getProjectId(), event); - delegate.transferInitiated(event); - } - - @Override - public void transferStarted(TransferEvent event) throws TransferCancelledException { - dispatcher.transfer(ProjectBuildLogAppender.getProjectId(), event); - delegate.transferStarted(event); - } - - @Override - public void transferProgressed(TransferEvent event) throws TransferCancelledException { - dispatcher.transfer(ProjectBuildLogAppender.getProjectId(), event); - delegate.transferProgressed(event); - } - - @Override - public void transferCorrupted(TransferEvent event) throws TransferCancelledException { - dispatcher.transfer(ProjectBuildLogAppender.getProjectId(), event); - delegate.transferCorrupted(event); - } - - @Override - public void transferSucceeded(TransferEvent event) { - dispatcher.transfer(ProjectBuildLogAppender.getProjectId(), event); - delegate.transferSucceeded(event); - } - - @Override - public void transferFailed(TransferEvent event) { - dispatcher.transfer(ProjectBuildLogAppender.getProjectId(), event); - delegate.transferFailed(event); - } -} diff --git a/dist/src/main/distro/bin/mvnd-bash-completion.bash b/dist/src/main/distro/bin/mvnd-bash-completion.bash index 692534a07..281384168 100755 --- a/dist/src/main/distro/bin/mvnd-bash-completion.bash +++ b/dist/src/main/distro/bin/mvnd-bash-completion.bash @@ -217,8 +217,8 @@ _mvnd() _get_comp_words_by_ref -n : cur prev local mvnd_opts="-1" - local mvnd_long_opts="--color|--completion|--diag|--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.coreExtensionsExclude|-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 mvnd_long_opts="--color|--completion|--diag|--purge|--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.coreExtensionsExclude|-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.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/provisio/maven-distro.xml b/dist/src/main/provisio/maven-distro.xml index 22c85f080..3071c82fa 100644 --- a/dist/src/main/provisio/maven-distro.xml +++ b/dist/src/main/provisio/maven-distro.xml @@ -20,7 +20,7 @@ + excludes="lib/plexus-utils-3.*" /> diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index b5c6ae2b8..793031ac7 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -141,7 +141,7 @@ maven-failsafe-plugin - native-39 + native integration-test verify 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 d6defd889..89a096c8d 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 @@ -23,6 +23,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import org.apache.maven.slf4j.MavenSimpleLogger; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -30,7 +31,6 @@ import org.mvndaemon.mvnd.assertj.TestClientOutput; import org.mvndaemon.mvnd.client.Client; import org.mvndaemon.mvnd.junit.MvndNativeTest; -import org.mvndaemon.mvnd.logging.slf4j.MvndSimpleLogger; import org.slf4j.LoggerFactory; import org.slf4j.spi.LocationAwareLogger; @@ -47,15 +47,15 @@ static class BaseTest { @BeforeAll static void setup() { - MvndSimpleLogger logger = - (MvndSimpleLogger) LoggerFactory.getLogger("org.mvndaemon.mvnd.client.DaemonConnector"); + MavenSimpleLogger logger = + (MavenSimpleLogger) LoggerFactory.getLogger("org.mvndaemon.mvnd.client.DaemonConnector"); logger.setLogLevel(LocationAwareLogger.DEBUG_INT); - MvndSimpleLogger.setLogSink(messages::add); + MavenSimpleLogger.setLogSink(messages::add); } @AfterAll static void tearDown() { - MvndSimpleLogger.setLogSink(null); + MavenSimpleLogger.setLogSink(null); } static String getDaemonArgs() { diff --git a/logging/pom.xml b/logging/pom.xml index d64153a4f..a104c5a9f 100644 --- a/logging/pom.xml +++ b/logging/pom.xml @@ -39,6 +39,10 @@ org.apache.maven maven-jline + + org.apache.maven + maven-logging + org.eclipse.sisu org.eclipse.sisu.inject diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/Slf4jLogger.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/Slf4jLogger.java deleted file mode 100644 index f3fe62541..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/Slf4jLogger.java +++ /dev/null @@ -1,144 +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 org.codehaus.plexus.logging.Logger; -import org.mvndaemon.mvnd.logging.smart.ProjectBuildLogAppender; - -/** - * Adapt an SLF4J logger to a Plexus logger, ignoring Plexus logger API parts that are not classical and - * probably not really used. - * - *

- * Adapted from - * https://github.com/apache/maven/blob/maven-3.6.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jLogger.java - * The main change is that the MDC property for redirecting the log to the correct maven project is set - * when the logger is instantiated (usually when injected into a mojo). - * - * @author Jason van Zyl - */ -public class Slf4jLogger implements Logger { - - private org.slf4j.Logger logger; - private String projectId; - - public Slf4jLogger(org.slf4j.Logger logger) { - this.logger = logger; - this.projectId = ProjectBuildLogAppender.getProjectId(); - } - - public void debug(String message) { - setMdc(); - logger.debug(message); - } - - public void debug(String message, Throwable throwable) { - setMdc(); - logger.debug(message, throwable); - } - - public boolean isDebugEnabled() { - return logger.isDebugEnabled(); - } - - public void info(String message) { - setMdc(); - logger.info(message); - } - - public void info(String message, Throwable throwable) { - setMdc(); - logger.info(message, throwable); - } - - public boolean isInfoEnabled() { - return logger.isInfoEnabled(); - } - - public void warn(String message) { - setMdc(); - logger.warn(message); - } - - public void warn(String message, Throwable throwable) { - setMdc(); - logger.warn(message, throwable); - } - - public boolean isWarnEnabled() { - return logger.isWarnEnabled(); - } - - public void error(String message) { - setMdc(); - logger.error(message); - } - - public void error(String message, Throwable throwable) { - setMdc(); - logger.error(message, throwable); - } - - public boolean isErrorEnabled() { - return logger.isErrorEnabled(); - } - - public void fatalError(String message) { - setMdc(); - logger.error(message); - } - - public void fatalError(String message, Throwable throwable) { - setMdc(); - logger.error(message, throwable); - } - - public boolean isFatalErrorEnabled() { - return logger.isErrorEnabled(); - } - - /** - * Warning: ignored (always return 0 == Logger.LEVEL_DEBUG). - */ - public int getThreshold() { - return 0; - } - - /** - * Warning: ignored. - */ - public void setThreshold(int threshold) {} - - /** - * Warning: ignored (always return null). - */ - public Logger getChildLogger(String name) { - return null; - } - - public String getName() { - return logger.getName(); - } - - private void setMdc() { - if (projectId != null && ProjectBuildLogAppender.getProjectId() == null) { - ProjectBuildLogAppender.setProjectId(projectId); - } - } -} diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/Slf4jLoggerManager.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/Slf4jLoggerManager.java deleted file mode 100644 index 06159a2b6..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/internal/Slf4jLoggerManager.java +++ /dev/null @@ -1,99 +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 org.codehaus.plexus.logging.Logger; -import org.codehaus.plexus.logging.LoggerManager; -import org.slf4j.ILoggerFactory; -import org.slf4j.LoggerFactory; - -/** - * Use an SLF4J {@link ILoggerFactory} as a backing for a Plexus - * {@link LoggerManager}, - * ignoring Plexus logger API parts that are not classical and probably not really used. - * - *

- * Adapted from - * https://github.com/apache/maven/blob/maven-3.6.3/maven-embedder/src/main/java/org/apache/maven/cli/logging/Slf4jLoggerManager.java - * This class has no differences with the above beyond formatting. Its purpose is simply to be able to call the - * Slf4Logger. - * - * @author Jason van Zyl - */ -public class Slf4jLoggerManager implements LoggerManager { - - private ILoggerFactory loggerFactory; - - public Slf4jLoggerManager() { - loggerFactory = LoggerFactory.getILoggerFactory(); - } - - public Logger getLoggerForComponent(String role) { - return new Slf4jLogger(loggerFactory.getLogger(role)); - } - - /** - * The logger name for a component with a non-null hint is role.hint. - * Warning: this does not conform to logger name as class name convention. - * (and what about null and default hint equivalence?) - */ - public Logger getLoggerForComponent(String role, String hint) { - return (null == hint - ? getLoggerForComponent(role) - : new Slf4jLogger(loggerFactory.getLogger(role + '.' + hint))); - } - - // - // Trying to give loggers back is a bad idea. Ceki said so :-) - // notice to self: what was this method supposed to do? - // - /** - * Warning: ignored. - */ - public void returnComponentLogger(String role) {} - - /** - * Warning: ignored. - */ - public void returnComponentLogger(String role, String hint) {} - - /** - * Warning: ignored (always return 0). - */ - public int getThreshold() { - return 0; - } - - /** - * Warning: ignored. - */ - public void setThreshold(int threshold) {} - - /** - * Warning: ignored. - */ - public void setThresholds(int threshold) {} - - /** - * Warning: ignored (always return 0). - */ - public int getActiveLoggerCount() { - return 0; - } -} diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndBaseLogger.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndBaseLogger.java deleted file mode 100644 index 18b4e5c14..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndBaseLogger.java +++ /dev/null @@ -1,466 +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.slf4j; - -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.Marker; -import org.slf4j.event.Level; -import org.slf4j.event.LoggingEvent; -import org.slf4j.helpers.LegacyAbstractLogger; -import org.slf4j.helpers.MessageFormatter; -import org.slf4j.helpers.NormalizedParameters; -import org.slf4j.spi.LocationAwareLogger; - -/** - *

- * Simple implementation of {@link Logger} that sends all enabled log messages, - * for all defined loggers, to the console ({@code System.err}). The following - * system properties are supported to configure the behavior of this logger: - * - * - *

    - *
  • org.slf4j.simpleLogger.logFile - The output target which can - * be the path to a file, or the special values "System.out" and - * "System.err". Default is "System.err".
  • - * - *
  • org.slf4j.simpleLogger.cacheOutputStream - If the output - * target is set to "System.out" or "System.err" (see preceding entry), by - * default, logs will be output to the latest value referenced by - * System.out/err variables. By setting this parameter to true, the - * output stream will be cached, i.e. assigned once at initialization time and - * re-used independently of the current value referenced by - * System.out/err.
  • - * - *
  • org.slf4j.simpleLogger.defaultLogLevel - Default log level - * for all instances of SimpleLogger. Must be one of ("trace", "debug", "info", - * "warn", "error" or "off"). If not specified, defaults to "info".
  • - * - *
  • org.slf4j.simpleLogger.log.a.b.c - Logging detail - * level for a SimpleLogger instance named "a.b.c". Right-side value must be one - * of "trace", "debug", "info", "warn", "error" or "off". When a SimpleLogger - * named "a.b.c" is initialized, its level is assigned from this property. If - * unspecified, the level of nearest parent logger will be used, and if none is - * set, then the value specified by - * org.slf4j.simpleLogger.defaultLogLevel will be used.
  • - * - *
  • org.slf4j.simpleLogger.showDateTime - Set to - * true if you want the current date and time to be included in - * output messages. Default is false
  • - * - *
  • org.slf4j.simpleLogger.dateTimeFormat - The date and time - * format to be used in the output messages. The pattern describing the date and - * time format is defined by - * SimpleDateFormat. If the format is not specified or is - * invalid, the number of milliseconds since start up will be output.
  • - * - *
  • org.slf4j.simpleLogger.showThreadName -Set to - * true if you want to output the current thread name. Defaults to - * true.
  • - * - *
  • (since version 1.7.33 and 2.0.0-alpha6) org.slf4j.simpleLogger.showThreadId - - * If you would like to output the current thread id, then set to - * true. Defaults to false.
  • - * - *
  • org.slf4j.simpleLogger.showLogName - Set to - * true if you want the Logger instance name to be included in - * output messages. Defaults to true.
  • - * - *
  • org.slf4j.simpleLogger.showShortLogName - Set to - * true if you want the last component of the name to be included - * in output messages. Defaults to false.
  • - * - *
  • org.slf4j.simpleLogger.levelInBrackets - Should the level - * string be output in brackets? Defaults to false.
  • - * - *
  • org.slf4j.simpleLogger.warnLevelString - The string value - * output for the warn level. Defaults to WARN.
  • - * - *
- * - *

- * In addition to looking for system properties with the names specified above, - * this implementation also checks for a class loader resource named - * "simplelogger.properties", and includes any matching definitions - * from this resource (if it exists). - * - * - *

- * With no configuration, the default output includes the relative time in - * milliseconds, thread name, the level, logger name, and the message followed - * by the line separator for the host. In log4j terms it amounts to the "%r [%t] - * %level %logger - %m%n" pattern. - * - *

- * Sample output follows. - * - * - *

- * 176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse order.
- * 225 [main] INFO examples.SortAlgo - Entered the sort method.
- * 304 [main] INFO examples.SortAlgo - Dump of integer array:
- * 317 [main] INFO examples.SortAlgo - Element [0] = 0
- * 331 [main] INFO examples.SortAlgo - Element [1] = 1
- * 343 [main] INFO examples.Sort - The next log statement should be an error message.
- * 346 [main] ERROR examples.SortAlgo - Tried to dump an uninitialized array.
- *   at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58)
- *   at org.log4j.examples.Sort.main(Sort.java:64)
- * 467 [main] INFO  examples.Sort - Exiting main method.
- * 
- * - *

- * This implementation is heavily inspired by - * Apache Commons Logging's - * SimpleLog. - * - * - * @author Ceki Gülcü - * @author Scott Sanders - * @author Rod Waldhoff - * @author Robert Burrell Donkin - * @author Cédrik LIME - */ -public class MvndBaseLogger extends LegacyAbstractLogger { - - private static final long serialVersionUID = -632788891211436180L; - - private static final long START_TIME = System.currentTimeMillis(); - - 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; - - static char SP = ' '; - static final String TID_PREFIX = "tid="; - - // The OFF level can only be used in configuration files to disable logging. - // It has - // no printing method associated with it in o.s.Logger interface. - protected static final int LOG_LEVEL_OFF = LOG_LEVEL_ERROR + 10; - - private 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(); - } - - /** The current log level */ - protected int currentLogLevel = LOG_LEVEL_INFO; - /** The short name of this simple log instance */ - private transient String shortLogName = null; - - /** - * All system properties used by SimpleLogger start with this - * prefix - */ - public static final String SYSTEM_PREFIX = "org.slf4j.simpleLogger."; - - public static final String LOG_KEY_PREFIX = MvndBaseLogger.SYSTEM_PREFIX + "log."; - - public static final String CACHE_OUTPUT_STREAM_STRING_KEY = MvndBaseLogger.SYSTEM_PREFIX + "cacheOutputStream"; - - public static final String WARN_LEVEL_STRING_KEY = MvndBaseLogger.SYSTEM_PREFIX + "warnLevelString"; - - public static final String LEVEL_IN_BRACKETS_KEY = MvndBaseLogger.SYSTEM_PREFIX + "levelInBrackets"; - - public static final String LOG_FILE_KEY = MvndBaseLogger.SYSTEM_PREFIX + "logFile"; - - public static final String SHOW_SHORT_LOG_NAME_KEY = MvndBaseLogger.SYSTEM_PREFIX + "showShortLogName"; - - public static final String SHOW_LOG_NAME_KEY = MvndBaseLogger.SYSTEM_PREFIX + "showLogName"; - - public static final String SHOW_THREAD_NAME_KEY = MvndBaseLogger.SYSTEM_PREFIX + "showThreadName"; - - public static final String SHOW_THREAD_ID_KEY = MvndBaseLogger.SYSTEM_PREFIX + "showThreadId"; - - public static final String DATE_TIME_FORMAT_KEY = MvndBaseLogger.SYSTEM_PREFIX + "dateTimeFormat"; - - public static final String SHOW_DATE_TIME_KEY = MvndBaseLogger.SYSTEM_PREFIX + "showDateTime"; - - public static final String DEFAULT_LOG_LEVEL_KEY = MvndBaseLogger.SYSTEM_PREFIX + "defaultLogLevel"; - - /** - * Protected access allows only {@link MvndLoggerFactory} and also derived classes to instantiate - * MvndBaseLogger instances. - */ - protected MvndBaseLogger(String name) { - this.name = name; - - String levelString = recursivelyComputeLevelString(); - if (levelString != null) { - this.currentLogLevel = SimpleLoggerConfiguration.stringToLevel(levelString); - } else { - this.currentLogLevel = 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(MvndBaseLogger.LOG_KEY_PREFIX + tempName, null); - indexOfLastDot = String.valueOf(tempName).lastIndexOf("."); - } - return levelString; - } - - /** - * To avoid intermingling of log messages and associated stack traces, the two - * operations are done in a synchronized block. - * - * @param buf - * @param t - */ - void write(StringBuilder buf, Throwable t) { - PrintStream targetStream = CONFIG_PARAMS.outputChoice.getTargetPrintStream(); - - synchronized (CONFIG_PARAMS) { - targetStream.println(buf.toString()); - writeThrowable(t, targetStream); - targetStream.flush(); - } - } - - protected void writeThrowable(Throwable t, PrintStream targetStream) { - if (t != null) { - t.printStackTrace(targetStream); - } - } - - private String getFormattedDate() { - Date now = new Date(); - String dateText; - synchronized (CONFIG_PARAMS.dateFormatter) { - dateText = CONFIG_PARAMS.dateFormatter.format(now); - } - return dateText; - } - - private String computeShortName() { - return name.substring(name.lastIndexOf(".") + 1); - } - - // /** - // * For formatted messages, first substitute arguments and then log. - // * - // * @param level - // * @param format - // * @param arg1 - // * @param arg2 - // */ - // private 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()); - // } - - // /** - // * For formatted messages, first substitute arguments and then log. - // * - // * @param level - // * @param format - // * @param arguments - // * a list of 3 ore more arguments - // */ - // private void formatAndLog(int level, String format, Object... arguments) { - // if (!isLevelEnabled(level)) { - // return; - // } - // FormattingTuple tp = MessageFormatter.arrayFormat(format, arguments); - // log(level, tp.getMessage(), tp.getThrowable()); - // } - - /** - * Is the given log level currently enabled? - * - * @param logLevel is this level enabled? - * @return whether the logger is enabled for the given level - */ - 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); - } - - /** Are {@code debug} messages currently enabled? */ - public boolean isDebugEnabled() { - return isLevelEnabled(LOG_LEVEL_DEBUG); - } - - /** Are {@code info} messages currently enabled? */ - public boolean isInfoEnabled() { - return isLevelEnabled(LOG_LEVEL_INFO); - } - - /** Are {@code warn} messages currently enabled? */ - public boolean isWarnEnabled() { - return isLevelEnabled(LOG_LEVEL_WARN); - } - - /** Are {@code error} messages currently enabled? */ - public boolean isErrorEnabled() { - return isLevelEnabled(LOG_LEVEL_ERROR); - } - - /** - * SimpleLogger's implementation of - * {@link org.slf4j.helpers.AbstractLogger#handleNormalizedLoggingCall(Level, Marker, String, Object[], Throwable) AbstractLogger#handleNormalizedLoggingCall} - * } - * - * @param level the SLF4J level for this event - * @param marker The marker to be used for this event, may be null. - * @param messagePattern The message pattern which will be parsed and formatted - * @param arguments the array of arguments to be formatted, may be null - * @param throwable The exception whose stack trace should be logged, may be null - */ - @Override - protected void handleNormalizedLoggingCall( - Level level, Marker marker, String messagePattern, Object[] arguments, Throwable throwable) { - - List markers = null; - - if (marker != null) { - markers = new ArrayList<>(); - markers.add(marker); - } - - innerHandleNormalizedLoggingCall(level, markers, messagePattern, arguments, throwable); - } - - private void innerHandleNormalizedLoggingCall( - Level level, List markers, String messagePattern, Object[] arguments, 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(SP); - } else { - buf.append(System.currentTimeMillis() - START_TIME); - buf.append(SP); - } - } - - // 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(SP); - } - - if (CONFIG_PARAMS.levelInBrackets) buf.append('['); - - // Append a readable representation of the log level - String levelStr = renderLevel(level.toInt()); - buf.append(levelStr); - if (CONFIG_PARAMS.levelInBrackets) buf.append(']'); - buf.append(SP); - - // 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(" - "); - } - - if (markers != null) { - buf.append(SP); - for (Marker marker : markers) { - buf.append(marker.getName()).append(SP); - } - } - - String formattedMessage = MessageFormatter.basicArrayFormat(messagePattern, arguments); - - // Append the message - buf.append(formattedMessage); - - write(buf, t); - } - - protected String renderLevel(int levelInt) { - switch (levelInt) { - case LOG_LEVEL_TRACE: - return "TRACE"; - case LOG_LEVEL_DEBUG: - return ("DEBUG"); - case LOG_LEVEL_INFO: - return "INFO"; - case LOG_LEVEL_WARN: - return "WARN"; - case LOG_LEVEL_ERROR: - return "ERROR"; - } - throw new IllegalStateException("Unrecognized level [" + levelInt + "]"); - } - - public void log(LoggingEvent event) { - int levelInt = event.getLevel().toInt(); - - if (!isLevelEnabled(levelInt)) { - return; - } - - NormalizedParameters np = NormalizedParameters.normalize(event); - - innerHandleNormalizedLoggingCall( - event.getLevel(), event.getMarkers(), np.getMessage(), np.getArguments(), event.getThrowable()); - } - - @Override - protected String getFullyQualifiedCallerName() { - return null; - } -} diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndConfiguration.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndConfiguration.java deleted file mode 100644 index 1da3cc840..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndConfiguration.java +++ /dev/null @@ -1,52 +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.slf4j; - -import org.apache.maven.cli.logging.Slf4jConfiguration; -import org.slf4j.ILoggerFactory; -import org.slf4j.LoggerFactory; - -public class MvndConfiguration implements Slf4jConfiguration { - @Override - public void setRootLoggerLevel(Level level) { - String value; - switch (level) { - case DEBUG: - value = "debug"; - break; - - case INFO: - value = "info"; - break; - - default: - value = "error"; - break; - } - System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", value); - } - - @Override - public void activate() { - ILoggerFactory lf = LoggerFactory.getILoggerFactory(); - if (lf instanceof MvndLoggerFactory) { - ((MvndLoggerFactory) lf).reconfigure(); - } - } -} diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndDaemonLogger.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndDaemonLogger.java index e4c1d6e63..f8fe14a69 100644 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndDaemonLogger.java +++ b/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndDaemonLogger.java @@ -18,24 +18,20 @@ */ package org.mvndaemon.mvnd.logging.slf4j; -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; +import org.apache.maven.slf4j.MavenBaseLogger; import org.slf4j.Marker; import org.slf4j.event.Level; import org.slf4j.helpers.MessageFormatter; -public class MvndDaemonLogger extends MvndBaseLogger { +public class MvndDaemonLogger extends MavenBaseLogger { final DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder().appendPattern("HH:mm:ss.SSS").toFormatter(); - PrintStream printStream; - public MvndDaemonLogger(String name) { super(name); } @@ -60,19 +56,13 @@ protected String renderLevel(int levelInt) { @Override protected void handleNormalizedLoggingCall( Level level, Marker marker, String messagePattern, Object[] arguments, Throwable throwable) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - pw.append(dateTimeFormatter.format(LocalTime.now())); - pw.append(" "); - pw.append(renderLevel(level.toInt())); - pw.append(" "); + StringBuilder buf = new StringBuilder(32); + buf.append(dateTimeFormatter.format(LocalTime.now())); + buf.append(" "); + buf.append(renderLevel(level.toInt())); + buf.append(" "); String message = MessageFormatter.basicArrayFormat(messagePattern, arguments); - pw.append(message); - if (throwable != null) { - throwable.printStackTrace(pw); - } - PrintStream printStream = MvndSimpleLogger.CONFIG_PARAMS.outputChoice.getTargetPrintStream(); - printStream.println(sw); - printStream.flush(); + buf.append(message); + write(buf, throwable); } } diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndFailOnSeverityLogger.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndFailOnSeverityLogger.java deleted file mode 100644 index 8d0704d30..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndFailOnSeverityLogger.java +++ /dev/null @@ -1,129 +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.slf4j; - -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/mvndaemon/mvnd/logging/slf4j/MvndLoggerFactory.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndLoggerFactory.java index 0767d68df..db0fb1499 100644 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndLoggerFactory.java +++ b/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndLoggerFactory.java @@ -18,64 +18,21 @@ */ package org.mvndaemon.mvnd.logging.slf4j; -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.apache.maven.slf4j.MavenLoggerFactory; 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); - } +public class MvndLoggerFactory extends MavenLoggerFactory { - /** - * Return an appropriate {@link Logger} instance by name. - */ - @Override - public Logger getLogger(String name) { - return loggerMap.computeIfAbsent(name, this::getNewLoggingInstance); - } + public MvndLoggerFactory() {} - private Logger getNewLoggingInstance(String name) { + protected 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); + return super.getNewLoggingInstance(name); } } - - 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/mvndaemon/mvnd/logging/slf4j/MvndServiceProvider.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndServiceProvider.java deleted file mode 100644 index 7bcfeeca6..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndServiceProvider.java +++ /dev/null @@ -1,65 +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.slf4j; - -import org.slf4j.ILoggerFactory; -import org.slf4j.IMarkerFactory; -import org.slf4j.helpers.BasicMDCAdapter; -import org.slf4j.helpers.BasicMarkerFactory; -import org.slf4j.spi.MDCAdapter; -import org.slf4j.spi.SLF4JServiceProvider; - -public class MvndServiceProvider implements SLF4JServiceProvider { - - /** - * Declare the version of the SLF4J API this implementation is compiled against. - * The value of this field is modified with each major 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 = "2.0.99"; // !final - - private MvndLoggerFactory loggerFactory = new MvndLoggerFactory(); - private IMarkerFactory markerFactory = new BasicMarkerFactory(); - private MDCAdapter mdcAdapter = new BasicMDCAdapter(); - - public ILoggerFactory getLoggerFactory() { - return loggerFactory; - } - - @Override - public IMarkerFactory getMarkerFactory() { - return markerFactory; - } - - @Override - public MDCAdapter getMDCAdapter() { - return mdcAdapter; - } - - @Override - public String getRequestedApiVersion() { - return REQUESTED_API_VERSION; - } - - @Override - public void initialize() { - // already initialized - } -} diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndSimpleLogger.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndSimpleLogger.java deleted file mode 100644 index 448df25a3..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/MvndSimpleLogger.java +++ /dev/null @@ -1,171 +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.slf4j; - -import java.util.function.Consumer; - -import org.apache.maven.api.services.MessageBuilder; -import org.apache.maven.jline.MessageUtils; - -import static org.apache.maven.jline.MessageUtils.builder; - -/** - * 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 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); - } - - @Override - void write(StringBuilder buf, Throwable t) { - writeThrowable(t, buf); - Consumer sink = LOG_SINK; - if (sink != null) { - sink.accept(buf.toString()); - } else { - CONFIG_PARAMS.outputChoice.getTargetPrintStream().println(buf.toString()); - } - } - - protected String renderLevel(int level) { - switch (level) { - case LOG_LEVEL_TRACE: - return builder().trace("TRACE").build(); - case LOG_LEVEL_DEBUG: - return builder().debug("DEBUG").build(); - case LOG_LEVEL_INFO: - return builder().info("INFO").build(); - case LOG_LEVEL_WARN: - return builder().warning("WARNING").build(); - case LOG_LEVEL_ERROR: - default: - return builder().error("ERROR").build(); - } - } - - protected void writeThrowable(Throwable t, StringBuilder sb) { - if (t == null) { - return; - } - MessageBuilder builder = MessageUtils.builder(); - builder.newline(); - builder.failure(t.getClass().getName()); - if (t.getMessage() != null) { - builder.a(": "); - builder.failure(t.getMessage()); - } - builder.newline(); - printStackTrace(t, builder, ""); - sb.append(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/mvndaemon/mvnd/logging/slf4j/OutputChoice.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/OutputChoice.java deleted file mode 100644 index 98a0d9815..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/OutputChoice.java +++ /dev/null @@ -1,75 +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.slf4j; - -import java.io.PrintStream; - -/** - * This class encapsulates the user's choice of output target. - * - * @author Ceki Gülcü - * - */ -class OutputChoice { - - enum OutputChoiceType { - SYS_OUT, - CACHED_SYS_OUT, - SYS_ERR, - CACHED_SYS_ERR, - FILE; - } - - final OutputChoiceType outputChoiceType; - final PrintStream targetPrintStream; - - OutputChoice(OutputChoiceType outputChoiceType) { - if (outputChoiceType == OutputChoiceType.FILE) { - throw new IllegalArgumentException(); - } - this.outputChoiceType = outputChoiceType; - if (outputChoiceType == OutputChoiceType.CACHED_SYS_OUT) { - this.targetPrintStream = System.out; - } else if (outputChoiceType == OutputChoiceType.CACHED_SYS_ERR) { - this.targetPrintStream = System.err; - } else { - this.targetPrintStream = null; - } - } - - OutputChoice(PrintStream printStream) { - this.outputChoiceType = OutputChoiceType.FILE; - this.targetPrintStream = printStream; - } - - PrintStream getTargetPrintStream() { - switch (outputChoiceType) { - case SYS_OUT: - return System.out; - case SYS_ERR: - return System.err; - case CACHED_SYS_ERR: - case CACHED_SYS_OUT: - case FILE: - return targetPrintStream; - default: - throw new IllegalArgumentException(); - } - } -} diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/SimpleLoggerConfiguration.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/SimpleLoggerConfiguration.java deleted file mode 100644 index 0413149fa..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/slf4j/SimpleLoggerConfiguration.java +++ /dev/null @@ -1,207 +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.slf4j; - -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.PrintStream; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Properties; - -import org.mvndaemon.mvnd.logging.slf4j.OutputChoice.OutputChoiceType; -import org.slf4j.helpers.Reporter; - -/** - * This class holds configuration values for {@link MvndBaseLogger}. The - * values are computed at runtime. See {@link MvndBaseLogger} documentation for - * more information. - * - * - * @author Ceki Gülcü - * @author Scott Sanders - * @author Rod Waldhoff - * @author Robert Burrell Donkin - * @author Cédrik LIME - * - * @since 1.7.25 - */ -public class SimpleLoggerConfiguration { - - private static final String CONFIGURATION_FILE = "simplelogger.properties"; - - static int DEFAULT_LOG_LEVEL_DEFAULT = MvndBaseLogger.LOG_LEVEL_INFO; - int defaultLogLevel = DEFAULT_LOG_LEVEL_DEFAULT; - - private static final boolean SHOW_DATE_TIME_DEFAULT = false; - boolean showDateTime = SHOW_DATE_TIME_DEFAULT; - - private static final String DATE_TIME_FORMAT_STR_DEFAULT = null; - private static String dateTimeFormatStr = DATE_TIME_FORMAT_STR_DEFAULT; - - DateFormat dateFormatter = null; - - private static final boolean SHOW_THREAD_NAME_DEFAULT = true; - boolean showThreadName = SHOW_THREAD_NAME_DEFAULT; - - /** - * See https://jira.qos.ch/browse/SLF4J-499 - * @since 1.7.33 and 2.0.0-alpha6 - */ - private static final boolean SHOW_THREAD_ID_DEFAULT = false; - - boolean showThreadId = SHOW_THREAD_ID_DEFAULT; - - static final boolean SHOW_LOG_NAME_DEFAULT = true; - boolean showLogName = SHOW_LOG_NAME_DEFAULT; - - private static final boolean SHOW_SHORT_LOG_NAME_DEFAULT = false; - boolean showShortLogName = SHOW_SHORT_LOG_NAME_DEFAULT; - - private static final boolean LEVEL_IN_BRACKETS_DEFAULT = false; - boolean levelInBrackets = LEVEL_IN_BRACKETS_DEFAULT; - - private static final String LOG_FILE_DEFAULT = "System.err"; - private String logFile = LOG_FILE_DEFAULT; - OutputChoice outputChoice = null; - - private static final boolean CACHE_OUTPUT_STREAM_DEFAULT = false; - private boolean cacheOutputStream = CACHE_OUTPUT_STREAM_DEFAULT; - - private static final String WARN_LEVELS_STRING_DEFAULT = "WARN"; - String warnLevelString = WARN_LEVELS_STRING_DEFAULT; - - private final Properties properties = new Properties(); - - void init() { - loadProperties(); - - String defaultLogLevelString = getStringProperty(MvndBaseLogger.DEFAULT_LOG_LEVEL_KEY, null); - if (defaultLogLevelString != null) defaultLogLevel = stringToLevel(defaultLogLevelString); - - showLogName = - getBooleanProperty(MvndBaseLogger.SHOW_LOG_NAME_KEY, SimpleLoggerConfiguration.SHOW_LOG_NAME_DEFAULT); - showShortLogName = getBooleanProperty(MvndBaseLogger.SHOW_SHORT_LOG_NAME_KEY, SHOW_SHORT_LOG_NAME_DEFAULT); - showDateTime = getBooleanProperty(MvndBaseLogger.SHOW_DATE_TIME_KEY, SHOW_DATE_TIME_DEFAULT); - showThreadName = getBooleanProperty(MvndBaseLogger.SHOW_THREAD_NAME_KEY, SHOW_THREAD_NAME_DEFAULT); - showThreadId = getBooleanProperty(MvndBaseLogger.SHOW_THREAD_ID_KEY, SHOW_THREAD_ID_DEFAULT); - dateTimeFormatStr = getStringProperty(MvndBaseLogger.DATE_TIME_FORMAT_KEY, DATE_TIME_FORMAT_STR_DEFAULT); - levelInBrackets = getBooleanProperty(MvndBaseLogger.LEVEL_IN_BRACKETS_KEY, LEVEL_IN_BRACKETS_DEFAULT); - warnLevelString = getStringProperty(MvndBaseLogger.WARN_LEVEL_STRING_KEY, WARN_LEVELS_STRING_DEFAULT); - - logFile = getStringProperty(MvndBaseLogger.LOG_FILE_KEY, logFile); - - cacheOutputStream = - getBooleanProperty(MvndBaseLogger.CACHE_OUTPUT_STREAM_STRING_KEY, CACHE_OUTPUT_STREAM_DEFAULT); - outputChoice = computeOutputChoice(logFile, cacheOutputStream); - - if (dateTimeFormatStr != null) { - try { - dateFormatter = new SimpleDateFormat(dateTimeFormatStr); - } catch (IllegalArgumentException e) { - Reporter.error("Bad date format in " + CONFIGURATION_FILE + "; will output relative time", e); - } - } - } - - private void loadProperties() { - // Add props from the resource simplelogger.properties - InputStream in = AccessController.doPrivileged((PrivilegedAction) () -> { - ClassLoader threadCL = Thread.currentThread().getContextClassLoader(); - if (threadCL != null) { - return threadCL.getResourceAsStream(CONFIGURATION_FILE); - } else { - return ClassLoader.getSystemResourceAsStream(CONFIGURATION_FILE); - } - }); - if (null != in) { - try { - properties.load(in); - } catch (java.io.IOException e) { - // ignored - } finally { - try { - in.close(); - } catch (java.io.IOException e) { - // ignored - } - } - } - } - - String getStringProperty(String name, String defaultValue) { - String prop = getStringProperty(name); - return (prop == null) ? defaultValue : prop; - } - - boolean getBooleanProperty(String name, boolean defaultValue) { - String prop = getStringProperty(name); - return (prop == null) ? defaultValue : "true".equalsIgnoreCase(prop); - } - - String getStringProperty(String name) { - String prop = null; - try { - prop = System.getProperty(name); - } catch (SecurityException e) { - ; // Ignore - } - return (prop == null) ? properties.getProperty(name) : prop; - } - - static int stringToLevel(String levelStr) { - if ("trace".equalsIgnoreCase(levelStr)) { - return MvndBaseLogger.LOG_LEVEL_TRACE; - } else if ("debug".equalsIgnoreCase(levelStr)) { - return MvndBaseLogger.LOG_LEVEL_DEBUG; - } else if ("info".equalsIgnoreCase(levelStr)) { - return MvndBaseLogger.LOG_LEVEL_INFO; - } else if ("warn".equalsIgnoreCase(levelStr)) { - return MvndBaseLogger.LOG_LEVEL_WARN; - } else if ("error".equalsIgnoreCase(levelStr)) { - return MvndBaseLogger.LOG_LEVEL_ERROR; - } else if ("off".equalsIgnoreCase(levelStr)) { - return MvndBaseLogger.LOG_LEVEL_OFF; - } - // assume INFO by default - return MvndBaseLogger.LOG_LEVEL_INFO; - } - - private static OutputChoice computeOutputChoice(String logFile, boolean cacheOutputStream) { - if ("System.err".equalsIgnoreCase(logFile)) - if (cacheOutputStream) return new OutputChoice(OutputChoiceType.CACHED_SYS_ERR); - else return new OutputChoice(OutputChoiceType.SYS_ERR); - else if ("System.out".equalsIgnoreCase(logFile)) { - if (cacheOutputStream) return new OutputChoice(OutputChoiceType.CACHED_SYS_OUT); - else return new OutputChoice(OutputChoiceType.SYS_OUT); - } else { - try { - FileOutputStream fos = new FileOutputStream(logFile); - PrintStream printStream = new PrintStream(fos); - return new OutputChoice(printStream); - } catch (FileNotFoundException e) { - Reporter.error("Could not open [" + logFile + "]. Defaulting to System.err", e); - return new OutputChoice(OutputChoiceType.SYS_ERR); - } - } - } -} diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/BuildEventListener.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/BuildEventListener.java deleted file mode 100644 index be905d27a..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/BuildEventListener.java +++ /dev/null @@ -1,79 +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.smart; - -import org.apache.maven.execution.ExecutionEvent; -import org.eclipse.aether.transfer.TransferEvent; - -/** - * An abstract build event sink. - */ -public abstract class BuildEventListener { - private static final BuildEventListener DUMMY = new BuildEventListener() { - - public void sessionStarted(ExecutionEvent event) {} - - public void projectStarted(String projectId) {} - - public void projectLogMessage(String projectId, String event) {} - - public void projectFinished(String projectId) {} - - public void executionFailure(String projectId, boolean halted, String exception) {} - - public void mojoStarted(ExecutionEvent event) {} - - public void finish(int exitCode) throws Exception {} - - public void fail(Throwable t) throws Exception {} - - public void log(String msg) {} - - public void transfer(String projectId, TransferEvent e) {} - }; - - /** - * @return a dummy {@link BuildEventListener} that just swallows the messages and does not send them anywhere - */ - public static BuildEventListener dummy() { - return DUMMY; - } - - protected BuildEventListener() {} - - public abstract void sessionStarted(ExecutionEvent event); - - public abstract void projectStarted(String projectId); - - public abstract void projectLogMessage(String projectId, String event); - - public abstract void projectFinished(String projectId); - - public abstract void executionFailure(String projectId, boolean halted, String exception); - - public abstract void mojoStarted(ExecutionEvent event); - - public abstract void finish(int exitCode) throws Exception; - - public abstract void fail(Throwable t) throws Exception; - - public abstract void log(String msg); - - public abstract void transfer(String projectId, TransferEvent e); -} diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/LoggingExecutionListener.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/LoggingExecutionListener.java deleted file mode 100644 index 233796f91..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/LoggingExecutionListener.java +++ /dev/null @@ -1,195 +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.smart; - -import javax.inject.Named; -import javax.inject.Singleton; - -import org.apache.maven.execution.ExecutionEvent; -import org.apache.maven.execution.ExecutionListener; -import org.apache.maven.execution.MavenExecutionRequest; -import org.apache.maven.execution.MavenSession; -import org.apache.maven.execution.ProjectExecutionEvent; -import org.apache.maven.execution.ProjectExecutionListener; -import org.apache.maven.lifecycle.LifecycleExecutionException; -import org.apache.maven.lifecycle.internal.ReactorBuildStatus; - -@Singleton -@Named -public class LoggingExecutionListener implements ExecutionListener, ProjectExecutionListener { - - private ExecutionListener delegate; - private BuildEventListener buildEventListener; - - public void init(ExecutionListener delegate, BuildEventListener buildEventListener) { - this.delegate = delegate; - this.buildEventListener = buildEventListener; - } - - @Override - public void beforeProjectExecution(ProjectExecutionEvent projectExecutionEvent) - throws LifecycleExecutionException {} - - @Override - public void beforeProjectLifecycleExecution(ProjectExecutionEvent projectExecutionEvent) - throws LifecycleExecutionException {} - - @Override - public void afterProjectExecutionSuccess(ProjectExecutionEvent projectExecutionEvent) - throws LifecycleExecutionException {} - - @Override - public void afterProjectExecutionFailure(ProjectExecutionEvent projectExecutionEvent) { - MavenSession session = projectExecutionEvent.getSession(); - boolean halted; - // The ReactorBuildStatus is only available if the SmartBuilder is used - ReactorBuildStatus status = - (ReactorBuildStatus) session.getRepositorySession().getData().get(ReactorBuildStatus.class); - if (status != null) { - halted = status.isHalted(); - } else { - // assume sensible default - Throwable t = projectExecutionEvent.getCause(); - halted = (t instanceof RuntimeException || !(t instanceof Exception)) - || !MavenExecutionRequest.REACTOR_FAIL_NEVER.equals(session.getReactorFailureBehavior()) - && !MavenExecutionRequest.REACTOR_FAIL_AT_END.equals(session.getReactorFailureBehavior()); - } - Throwable cause = projectExecutionEvent.getCause(); - buildEventListener.executionFailure( - projectExecutionEvent.getProject().getArtifactId(), halted, cause != null ? cause.toString() : null); - } - - @Override - public void projectDiscoveryStarted(ExecutionEvent event) { - setMdc(event); - delegate.projectDiscoveryStarted(event); - } - - @Override - public void sessionStarted(ExecutionEvent event) { - setMdc(event); - buildEventListener.sessionStarted(event); - delegate.sessionStarted(event); - } - - @Override - public void sessionEnded(ExecutionEvent event) { - setMdc(event); - delegate.sessionEnded(event); - } - - @Override - public void projectStarted(ExecutionEvent event) { - setMdc(event); - buildEventListener.projectStarted(event.getProject().getArtifactId()); - delegate.projectStarted(event); - } - - @Override - public void projectSucceeded(ExecutionEvent event) { - setMdc(event); - delegate.projectSucceeded(event); - buildEventListener.projectFinished(event.getProject().getArtifactId()); - } - - @Override - public void projectFailed(ExecutionEvent event) { - setMdc(event); - delegate.projectFailed(event); - buildEventListener.projectFinished(event.getProject().getArtifactId()); - } - - @Override - public void projectSkipped(ExecutionEvent event) { - setMdc(event); - buildEventListener.projectStarted(event.getProject().getArtifactId()); - delegate.projectSkipped(event); - buildEventListener.projectFinished(event.getProject().getArtifactId()); - } - - @Override - public void mojoStarted(ExecutionEvent event) { - setMdc(event); - buildEventListener.mojoStarted(event); - delegate.mojoStarted(event); - } - - @Override - public void mojoSucceeded(ExecutionEvent event) { - setMdc(event); - delegate.mojoSucceeded(event); - } - - @Override - public void mojoFailed(ExecutionEvent event) { - setMdc(event); - delegate.mojoFailed(event); - } - - @Override - public void mojoSkipped(ExecutionEvent event) { - setMdc(event); - delegate.mojoSkipped(event); - } - - @Override - public void forkStarted(ExecutionEvent event) { - setMdc(event); - delegate.forkStarted(event); - ProjectBuildLogAppender.setForkingProjectId(event.getProject().getArtifactId()); - } - - @Override - public void forkSucceeded(ExecutionEvent event) { - delegate.forkSucceeded(event); - ProjectBuildLogAppender.setForkingProjectId(null); - } - - @Override - public void forkFailed(ExecutionEvent event) { - delegate.forkFailed(event); - ProjectBuildLogAppender.setForkingProjectId(null); - } - - @Override - public void forkedProjectStarted(ExecutionEvent event) { - setMdc(event); - delegate.forkedProjectStarted(event); - } - - @Override - public void forkedProjectSucceeded(ExecutionEvent event) { - setMdc(event); - delegate.forkedProjectSucceeded(event); - ProjectBuildLogAppender.setProjectId(null); - } - - @Override - public void forkedProjectFailed(ExecutionEvent event) { - setMdc(event); - delegate.forkedProjectFailed(event); - ProjectBuildLogAppender.setProjectId(null); - } - - private void setMdc(ExecutionEvent event) { - if (event.getProject() != null) { - ProjectBuildLogAppender.setProjectId(event.getProject().getArtifactId()); - } - } -} diff --git a/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/LoggingOutputStream.java b/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/LoggingOutputStream.java deleted file mode 100644 index b27c85b2a..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/LoggingOutputStream.java +++ /dev/null @@ -1,97 +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.smart; - -import java.io.ByteArrayOutputStream; -import java.io.FilterOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.util.function.Consumer; - -public class LoggingOutputStream extends FilterOutputStream { - - static final byte[] LINE_SEP = System.lineSeparator().getBytes(); - - final EolBaos buf; - final Consumer consumer; - - public LoggingOutputStream(Consumer consumer) { - this(new EolBaos(), consumer); - } - - LoggingOutputStream(EolBaos out, Consumer consumer) { - super(out); - this.buf = out; - this.consumer = consumer; - } - - public PrintStream printStream() { - return new LoggingPrintStream(this); - } - - @Override - public void write(int b) throws IOException { - super.write(b); - if (buf.isEol()) { - String line = new String(buf.toByteArray(), 0, buf.size() - LINE_SEP.length); - ProjectBuildLogAppender.updateMdc(); - consumer.accept(line); - buf.reset(); - } - } - - public void forceFlush() { - if (buf.size() > 0) { - String line = new String(buf.toByteArray(), 0, buf.size()); - ProjectBuildLogAppender.updateMdc(); - consumer.accept(line); - buf.reset(); - } - } - - static class EolBaos extends ByteArrayOutputStream { - boolean isEol() { - if (count >= LINE_SEP.length) { - for (int i = 0; i < LINE_SEP.length; i++) { - if (buf[count - LINE_SEP.length + i] != LINE_SEP[i]) { - return false; - } - } - return true; - } - return false; - } - } - - public static class LoggingPrintStream extends PrintStream { - public LoggingPrintStream(LoggingOutputStream out) { - super(out, true); - } - - public void forceFlush() { - ((LoggingOutputStream) out).forceFlush(); - } - } - - public static void forceFlush(PrintStream ps) { - if (ps instanceof LoggingPrintStream) { - ((LoggingPrintStream) ps).forceFlush(); - } - } -} 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 deleted file mode 100644 index 4f908e708..000000000 --- a/logging/src/main/java/org/mvndaemon/mvnd/logging/smart/ProjectBuildLogAppender.java +++ /dev/null @@ -1,88 +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.smart; - -import org.mvndaemon.mvnd.logging.slf4j.MvndSimpleLogger; -import org.slf4j.MDC; - -/** - * Forwards log messages to the client. - */ -public class ProjectBuildLogAppender implements AutoCloseable { - - private static final String KEY_PROJECT_ID = "maven.project.id"; - private static final ThreadLocal PROJECT_ID = new InheritableThreadLocal<>(); - private static final ThreadLocal FORKING_PROJECT_ID = new InheritableThreadLocal<>(); - - public static String getProjectId() { - return PROJECT_ID.get(); - } - - public static void setProjectId(String projectId) { - String forkingProjectId = FORKING_PROJECT_ID.get(); - if (forkingProjectId != null) { - if (projectId != null) { - projectId = forkingProjectId + "/" + projectId; - } else { - projectId = forkingProjectId; - } - } - if (projectId != null) { - PROJECT_ID.set(projectId); - MDC.put(KEY_PROJECT_ID, projectId); - } else { - PROJECT_ID.remove(); - MDC.remove(KEY_PROJECT_ID); - } - } - - public static void setForkingProjectId(String forkingProjectId) { - if (forkingProjectId != null) { - FORKING_PROJECT_ID.set(forkingProjectId); - } else { - FORKING_PROJECT_ID.remove(); - } - } - - public static void updateMdc() { - String id = getProjectId(); - if (id != null) { - MDC.put(KEY_PROJECT_ID, id); - } else { - MDC.remove(KEY_PROJECT_ID); - } - } - - private final BuildEventListener buildEventListener; - - public ProjectBuildLogAppender(BuildEventListener buildEventListener) { - this.buildEventListener = buildEventListener; - MvndSimpleLogger.setLogSink(this::accept); - } - - protected void accept(String message) { - String projectId = MDC.get(KEY_PROJECT_ID); - buildEventListener.projectLogMessage(projectId, message); - } - - @Override - public void close() throws Exception { - MvndSimpleLogger.setLogSink(null); - } -} diff --git a/logging/src/main/resources/META-INF/maven/slf4j-configuration.properties b/logging/src/main/resources/META-INF/maven/slf4j-configuration.properties index 5e922b771..6f99f2a1d 100644 --- a/logging/src/main/resources/META-INF/maven/slf4j-configuration.properties +++ b/logging/src/main/resources/META-INF/maven/slf4j-configuration.properties @@ -17,4 +17,4 @@ # key = Slf4j effective logger factory implementation # value = corresponding o.a.m.cli.logging.Slf4jConfiguration class -org.mvndaemon.mvnd.logging.slf4j.MvndLoggerFactory org.mvndaemon.mvnd.logging.slf4j.MvndConfiguration +org.mvndaemon.mvnd.logging.slf4j.MvndLoggerFactory=org.apache.maven.cli.logging.impl.MavenSimpleConfiguration diff --git a/logging/src/main/resources/META-INF/services/org.apache.maven.slf4j.MavenLoggerFactory b/logging/src/main/resources/META-INF/services/org.apache.maven.slf4j.MavenLoggerFactory new file mode 100644 index 000000000..1d675a427 --- /dev/null +++ b/logging/src/main/resources/META-INF/services/org.apache.maven.slf4j.MavenLoggerFactory @@ -0,0 +1 @@ +org.mvndaemon.mvnd.logging.slf4j.MvndLoggerFactory \ No newline at end of file diff --git a/logging/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider b/logging/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider deleted file mode 100644 index 24253555f..000000000 --- a/logging/src/main/resources/META-INF/services/org.slf4j.spi.SLF4JServiceProvider +++ /dev/null @@ -1 +0,0 @@ -org.mvndaemon.mvnd.logging.slf4j.MvndServiceProvider \ No newline at end of file diff --git a/pom.xml b/pom.xml index a7cdd09cc..8d363d7b4 100644 --- a/pom.xml +++ b/pom.xml @@ -161,12 +161,6 @@ org.apache.maven maven-core ${maven.version} - - - org.apache.maven - maven-slf4j-provider - - org.apache.maven @@ -177,12 +171,6 @@ org.apache.maven maven-embedder ${maven.version} - - - org.apache.maven - maven-slf4j-provider - - org.apache.maven @@ -194,6 +182,11 @@ maven-jline ${maven.version} + + org.apache.maven + maven-logging + ${maven.version} + org.apache.maven apache-maven