Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to dump the logs to an output file #1472

Merged
merged 4 commits into from
May 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion doc/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
- Using <external> properties in image configuration disables Docker cache during build ([1455](https://github.com/fabric8io/docker-maven-plugin/issues/1455))
- Update documentation to clearly state that `docker.cacheFrom.idx` is a _list_ property and should always be used with a `idx` suffix. With this change, `docker.cacheFrom` (without _idx_) is not considered anymore.
- A placeholder in docker.image.tag isn't replaced by the final result when used during docker:build ([1468](https://github.com/fabric8io/docker-maven-plugin/issues/1468))

- Add a property(`outputFile`) to dump the output of Docker commands to file ([1472]https://github.com/fabric8io/docker-maven-plugin/pull/1472)

* **0.35.0** (2021-04-04)
- Building 'spring-boot-with-jib' sample fails with NoSuchMethodError ([1384](https://github.com/fabric8io/docker-maven-plugin/issues/1384))
- Loading Image tarball into docker daemon fails in JIB mode ([1385](https://github.com/fabric8io/docker-maven-plugin/issues/1385))
Expand Down
4 changes: 4 additions & 0 deletions src/main/asciidoc/inc/_global-configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ If set to `true` this plugin won't remove any tags with `{plugin}:remove`. +
| Whether to use colored log output. By default this is switched on when running on a console, off otherwise.
| `docker.useColor`

| *outputFile*
| If specified, this parameter will cause the logs to be written to the path specified, instead of writing to the console.
| `outputFile`

| *verbose*
| String attribute for switching on verbose output on standard output (stdout). It takes a comma separated list of string values to switch on various verbosity groups.

Expand Down
20 changes: 18 additions & 2 deletions src/main/java/io/fabric8/maven/docker/AbstractDockerMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ public abstract class AbstractDockerMojo extends AbstractMojo implements Context
@Component
protected DockerAccessFactory dockerAccessFactory;

// Redirect the plugin output to a file
@Parameter(property = "outputFile")
private String outputFile;

@Parameter(property = "docker.autoPull")
protected String autoPull;

Expand Down Expand Up @@ -222,7 +226,7 @@ public abstract class AbstractDockerMojo extends AbstractMojo implements Context
// Handler dealing with authentication credentials
private AuthConfigFactory authConfigFactory;

protected Logger log;
protected AnsiLogger log;

private String minimalApiVersion;

Expand All @@ -238,7 +242,14 @@ public abstract class AbstractDockerMojo extends AbstractMojo implements Context
public void execute() throws MojoExecutionException, MojoFailureException {
if (!skip) {
boolean ansiRestore = Ansi.isEnabled();
log = new AnsiLogger(getLog(), useColorForLogging(), verbose, !settings.getInteractiveMode(), getLogPrefix());
File output = null;
if (outputFile != null) {
output = new File(outputFile);
if (output.exists()) {
output.delete();
}
rohanKanojia marked this conversation as resolved.
Show resolved Hide resolved
}
log = new AnsiLogger(getLog(), useColorForLogging(), verbose, !settings.getInteractiveMode(), getLogPrefix(), output);

try {
authConfigFactory.setLog(log);
Expand Down Expand Up @@ -271,6 +282,11 @@ public void execute() throws MojoExecutionException, MojoFailureException {
}
} finally {
Ansi.setEnabled(ansiRestore);
try {
log.close();
} catch (IOException exp) {
logException(exp);
}
}
}
}
Expand Down
79 changes: 70 additions & 9 deletions src/main/java/io/fabric8/maven/docker/util/AnsiLogger.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package io.fabric8.maven.docker.util;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Predicate;

import org.apache.maven.plugin.logging.Log;
import org.codehaus.plexus.util.StringUtils;
Expand All @@ -22,7 +25,7 @@
* @author roland
* @since 31.03.14
*/
public class AnsiLogger implements Logger {
public class AnsiLogger implements Logger, Closeable {

// prefix used for console output
public static final String DEFAULT_LOG_PREFIX = "DOCKER> ";
Expand All @@ -31,9 +34,11 @@ public class AnsiLogger implements Logger {
private final Log log;
private final String prefix;
private final boolean batchMode;
private final File outputFile;

private boolean isVerbose = false;
private List<LogVerboseCategory> verboseModes = null;
private PrintWriter pw;

// ANSI escapes for various colors (or empty strings if no coloring is used)
static Ansi.Color
Expand All @@ -59,44 +64,78 @@ public AnsiLogger(Log log, boolean useColor, String verbose) {
}

public AnsiLogger(Log log, boolean useColor, String verbose, boolean batchMode) {
this(log, useColor, verbose, batchMode, DEFAULT_LOG_PREFIX);
this(log, useColor, verbose, batchMode, DEFAULT_LOG_PREFIX, null);
}

public AnsiLogger(Log log, boolean useColor, String verbose, boolean batchMode, String prefix) {
this(log, useColor, verbose, batchMode, prefix, null);
}

public AnsiLogger(Log log, boolean useColor, String verbose, boolean batchMode, String prefix, File outpufFile) {
this.log = log;
this.prefix = prefix;
this.batchMode = batchMode;
this.outputFile = outpufFile;
if (this.outputFile == null) {
this.batchMode = batchMode;
} else {
this.batchMode = true;
}
checkVerboseLoggingEnabled(verbose);
initializeColor(useColor);
try {
initializePrintWriter();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

/** {@inheritDoc} */
public void debug(String message, Object ... params) {
if (isDebugEnabled()) {
log.debug(prefix + format(message, params));
logOrPrintToFile(
log -> true,
log -> log.debug(prefix + format(message, params)),
message,
params);
}
}

/** {@inheritDoc} */
public void info(String message, Object ... params) {
log.info(colored(message, COLOR_INFO, true, params));
logOrPrintToFile(
log -> log.isInfoEnabled(),
log -> log.info(colored(message, COLOR_INFO, true, params)),
message,
params);
}

/** {@inheritDoc} */
public void verbose(LogVerboseCategory logVerboseCategory, String message, Object ... params) {
if (isVerbose && verboseModes != null && verboseModes.contains(logVerboseCategory)) {
log.info(ansi().fgBright(BLACK).a(prefix).a(format(message, params)).reset().toString());
logOrPrintToFile(
log -> true,
log -> log.info(ansi().fgBright(BLACK).a(prefix).a(format(message, params)).reset().toString()),
message,
params);
}
}

/** {@inheritDoc} */
public void warn(String format, Object ... params) {
log.warn(colored(format, COLOR_WARNING, true, params));
public void warn(String message, Object ... params) {
logOrPrintToFile(
log -> log.isWarnEnabled(),
log -> log.warn(colored(message, COLOR_WARNING, true, params)),
message,
params);
}

/** {@inheritDoc} */
public void error(String message, Object ... params) {
log.error(colored(message, COLOR_ERROR, true, params));
logOrPrintToFile(
log -> log.isErrorEnabled(),
log -> log.error(colored(message, COLOR_ERROR, true, params)),
message,
params);
}

@Override
Expand Down Expand Up @@ -214,6 +253,12 @@ private void initializeColor(boolean useColor) {
}
}

private void initializePrintWriter() throws FileNotFoundException {
if (outputFile != null) {
this.pw = new PrintWriter(outputFile);
}
}

private void println(String txt) {
System.out.println(txt);
}
Expand Down Expand Up @@ -343,4 +388,20 @@ private List<LogVerboseCategory> getVerboseModesFromString(String groups) {
}
return ret;
}

private void logOrPrintToFile(Predicate<Log> logPredicate, Consumer<Log> logConsumer, String message, Object ... params) {
if (outputFile != null && logPredicate.test(log)) {
pw.println(format(message, params));
} else {
logConsumer.accept(log);
}
}

@Override
public void close() throws IOException {
if (pw != null) {
pw.flush();
pw.close();
}
}
}
2 changes: 1 addition & 1 deletion src/test/java/io/fabric8/maven/docker/BaseMojoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class BaseMojoTest {
public TemporaryFolder temporaryFolder = new TemporaryFolder();

@Injectable
protected Logger log;
protected AnsiLogger log;

@Mocked
protected ServiceHub serviceHub;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.fabric8.maven.docker.access.DockerAccessException;
import io.fabric8.maven.docker.service.ServiceHub;
import io.fabric8.maven.docker.util.AnsiLogger;
import io.fabric8.maven.docker.util.Logger;
import mockit.Injectable;
import mockit.Mocked;
Expand All @@ -13,7 +14,7 @@
public class VolumeCreateMojoTest {

@Injectable
Logger log;
AnsiLogger log;

@Tested(fullyInitialized = false)
private VolumeCreateMojo volumeCreateMojo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.fabric8.maven.docker.access.DockerAccessException;
import io.fabric8.maven.docker.service.ServiceHub;
import io.fabric8.maven.docker.util.AnsiLogger;
import io.fabric8.maven.docker.util.Logger;
import mockit.Injectable;
import mockit.Mocked;
Expand All @@ -13,7 +14,7 @@
public class VolumeRemoveMojoTest {

@Injectable
Logger log;
AnsiLogger log;

@Tested(fullyInitialized = false)
private VolumeRemoveMojo volumeRemoveMojo;
Expand Down