Chapter 13. Logging

The log is the main 'UI' of a build tool. If it is too verbose, real warnings and problems are easily hidden by this. On the other hand you need the relevant information for figuring out if things have gone wrong. Gradle has added to log-levels to the ones normally used. Those levels are QUIET and LIFECYCLE. The latter is the default and is telling you just what task is getting executed or skipped.

13.1. Choosing a log level

You can use command line switches to choose different log levels (see Table 13.1, “Log Level Command-Line Options”). The WARN and ERROR levels are included in all the other levels, except QUIET, where only ERROR is included. In Table 13.2, “Stacktrace Command-Line Options” you find the command line switches for stacktrace logging.

Table 13.1. Log Level Command-Line Options

Option Meaning
no logging options LIFECYCLE
-q QUIET
-i INFO
-d DEBUG

Table 13.2. Stacktrace Command-Line Options

Option Meaning
No stacktrace options No stacktraces are printed to the console in case of a build error (e.g. a compile error). Only in case of internal exceptions will stacktraces be printed. If the loglevel option -d is chosen, truncated stacktraces are always printed.
-s Truncated stacktraces are printed. We recommend this over full stacktraces. Groovy full stacktraces are extremely verbose (Due to the underlying dynamic invocation mechanisms. Yet they usually do not contain relevant information for what has gone wrong in your code.)
-f The full stacktraces are printed out.

13.2. External Tools and Standard Output

Gradle uses internally Ant and Ivy a lot. Both have their own logging system. Gradle injects an adapter into there logging system to redirect there logging output into the Gradle logging system. There is a 1:1 mapping from the Ant/Ivy log levels to the Gradle log levels, except the Ant/Ivy trace level, which is mapped to Gradle debug. This means the default Gradle log level does not show any Ant/Ivy output unless it is an error or a warning.

There are many tools out there which still use standard output for logging. Gradle redirects by default standard out to the QUIET level and standard err to the ERROR level. This behavior is configurable. Gradle provides a couple of switches for this. To change the log level, standard out is redirected to, when your build script gets evaluated, the project object offers a method called Project.captureStandardOutput() . To change the log level for standard out during task execution, tasks offer a method also with the name Task.captureStandardOutput() . Tasks and projects also offer a method disableStandardOutputCapture which causes the standard out to be send to the default standard out. If you need more fine grained control on how standard out is redirected you can use the class StandardOutputLogging .

13.3. Sending your own log messages

Gradle provides a logger property to a build script, which is an instance of a slf4j logger. Here is the code of the logging integration test, which shows you how to use the logger, as well as working with standard out redirection.

Example 13.1.  build.gradle

logger.info(Logging.QUIET, prefix + "quietLog")
logger.info(Logging.LIFECYCLE, prefix + "lifecycleLog")
logger.info(prefix + "infoLog")
logger.debug(prefix + "debugLog")
logger.warn(prefix + "warnLog")
logger.error(prefix + "errorLog")
println(prefix + 'quietOut')
captureStandardOutput(LogLevel.INFO)
println(prefix + 'infoOut')

createTask('logLifecycle') {
    println(prefix + 'lifecycleTaskOut')
}.captureStandardOutput(LogLevel.LIFECYCLE)

createTask('logInfo') {
    println(prefix + 'infoTaskOut')
}.captureStandardOutput(LogLevel.INFO)

createTask('log', dependsOn: [logInfo, logLifecycle]) {
    println(prefix + 'quietTaskOut')
}

Strictly speaking, QUIET and LIFECYCLE are no log levels, but they are markers. But logically Gradle treats them as log levels. In a future version of Gradle we want to provide a logger which provides additional log methods quiet and lifecycle.

You can also hook into Gradle's logging system from within other classes (classes from the buildSrc directory for example). Simply use a slf4j logger.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;    

public class MyClass {
    private static Logger logger = LoggerFactory.getLogger(MyClass.class);
    ...

You can use this logger the same way as you use the provided logger in the build script.