第18章 ロギング

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 defines 6 log levels, as shown in 表18.1「ログレベルLog levels. There are two Gradle-specific log levels, in addition to the ones you might normally see. Those levels are QUIET and LIFECYCLE. The latter is the default, and is used to report build progress.

ログは、ビルドツールのユーザーインターフェースとも言えるものです。あまりにくどいと本当に重要な警告や問題が埋もれてしまいますが、何かおかしくなったとき、その原因を突き止めるための情報はとてもありがたいものです。Gradleでは、6つのログレベル(表18.1「ログレベルLog levels)を規定しています。だいたいはどこか見たことのあるログレベルだと思いますが、QUIETLIFECYCLEの2つはGradle特有のものです。LIFECYCLEはデフォルトのログレベルで、ビルドプロセスの進行状況をレポートするために使われます。

表18.1 ログレベルLog levels

レベルLevel 用途Used for
ERROR エラーメッセージError messages
QUIET 重要な情報メッセージImportant information messages
WARNING 警告メッセージWarning messages
LIFECYCLE 進行状況を示す情報メッセージProgress information messages
INFO 情報メッセージInformation messages
DEBUG デバッグメッセージDebug messages

18.1. ログレベルの選択Choosing a log level

You can use the command line switches shown in 表18.2「ログレベルに関するコマンドラインオプションLog level command-line options to choose different log levels. In 表18.3「スタックトレースに関するコマンドラインオプションStacktrace command-line options you find the command line switches which affect stacktrace logging.

表示させるログレベルは、コマンドラインオプション(表18.2「ログレベルに関するコマンドラインオプションLog level command-line options)で変更できます。表18.3「スタックトレースに関するコマンドラインオプションStacktrace command-line optionsには、スタックトレースログをどうするか指定する方法を載せています。

表18.2 ログレベルに関するコマンドラインオプションLog level command-line options

オプションOption 出力ログレベルOutputs Log Levels
ロギングオプション未指定no logging options LIFECYCLE以上LIFECYCLE and higher
-q または --quiet QUIET以上QUIET and higher
-i または --info INFO以上INFO and higher
-d または --debug DEBUG以上(要するに全部)DEBUG and higher (that is, all log messages)

表18.3 スタックトレースに関するコマンドラインオプションStacktrace command-line options

オプションOption 意味Meaning
スタックトレースオプション未指定No stacktrace options ビルドエラー(コンパイルエラーとか)のスタックトレースはコンソールに表示されず、内部からの例外のみスタックトレースが表示される。ただし、ログレベルオプションで-dが指定されている場合、切り詰められたスタックトレースが常に表示される。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 DEBUG log level is chosen, truncated stacktraces are always printed.
-s または --stacktrace 切り詰められたスタックトレースが表示される。Groovyのフルスタックトレースはあまりに冗長(動的言語としての呼び出しメカニズムが色々出力され、自分のコードのどこがダメなのか有用な情報がでてこない)ので、こちらの切り詰め済みスタックトレースを推奨します。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.)
-S または --full-stacktrace フルスタックトレースを表示する。The full stacktraces are printed out.

18.2. ログメッセージを書くWriting your own log messages

A simple option for logging in your build file is to write messages to standard output. Gradle redirects anything written to standard output to it's logging system at the QUIET log level.

ログメッセージを書く簡単な方法は、標準出力に書き込むことです。Gradleは、標準出力に書かれたすべてのメッセージを、GradleのロギングシステムにQUIETレベルでリダイレクトします。

例18.1 ログに標準出力を使う

build.gradle

println 'A message which is logged at QUIET level'

Gradle also provides a logger property to a build script, which is an instance of Logger. This interface extends the SLF4J Logger interface and adds a few Gradle specific methods to it. Below is an example of how this is used in the build script:

また、ビルドスクリプト内ではloggerプロパティも使えます。このプロパティには、Logger(SLF4JのLoggerインターフェースにGradle特有のメソッドを少し追加したもの)のインスタンスがセットされています。使い方は以下の例をご覧ください。

例18.2 自分でログメッセージを書く

build.gradle

logger.quiet('An info log message which is always logged.')
logger.error('An error log message.')
logger.warn('A warning log message.')
logger.lifecycle('A lifecycle info log message.')
logger.info('An info log message.')
logger.debug('A debug log message.')
logger.trace('A trace log message.')

You can also hook into Gradle's logging system from within other classes used in the build (classes from the buildSrc directory for example). Simply use an SLF4J logger. You can use this logger the same way as you use the provided logger in the build script.

さらに、ビルドで使っている別のクラス(たとえばbuildSrcディレクトリのクラス)の中から、Gradleのロギングシステムへログを出力することもできます。やり方も、ただSLF4Jのロガーを使えばいいだけです。このロガーは、ビルドスクリプトで使えるロガーと全く同じように使うことができます。

例18.3 SLF4Jでログを出力する

build.gradle

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

Logger slf4jLogger = LoggerFactory.getLogger('some-logger')
slf4jLogger.info('An info log message logged using SLF4j')

18.3. 外部ツールやライブラリからのログについてLogging from external tools and libraries

Internally, Gradle uses Ant and Ivy. Both have their own logging system. Gradle redirects their 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 log level, which is mapped to Gradle DEBUG log level. This means the default Gradle log level will not show any Ant/Ivy output unless it is an error or a warning.

内部的には、GradleはAntとIvyを使っています。どちらも、自身で独自のロギングシステムを持っています。Gradleはそれらのログ出力をGradleのロギングシステムにリダイレクトしているのです。Ant、Ivyのログレベルは、基本的にGradleのログレベルと1対1で対応しています(TRACEだけはGradleのDEBUGに対応)。つまり、Gradleのデフォルトログレベルだと、Ant、Ivyのメッセージはエラーやワーニングでないと出力されないと言うことです。

There are many tools out there which still use standard output for logging. By default, Gradle redirects standard output to the QUIET log level and standard error to the ERROR level. This behavior is configurable. The project object provides a LoggingManager, which allows you to change the log levels that standard out or error are redirected to when your build script is evaluated.

ログに標準出力を使っているツールは、いまだにたくさんあります。デフォルトでは、Gradleは標準出力をQUIETレベルログに、標準エラーをERRORレベルログにリダイレクトします。また、この動作は設定で変更可能です。プロジェクトオブジェクトのLoggingManagerを使えば、ビルドスクリプト実行時の標準出力、標準エラーをどのログレベルにリダイレクトするか変更できるようになっています。

例18.4 標準出力のキャプチャ設定

build.gradle

logging.captureStandardOutput LogLevel.INFO
println 'A message which is logged at INFO level'

To change the log level for standard out or error during task execution, tasks also provide a LoggingManager.

さらに、タスク実行時のログリダイレクト設定も変更できるよう、タスクにもLoggingManagerがあります。

例18.5 タスク実行時の標準出力キャプチャ設定

build.gradle

task logInfo {
    logging.captureStandardOutput LogLevel.INFO
    doFirst {
        println 'A task message which is logged at INFO level'
    }
}

Gradle also provides integration with the Java Util Logging, Jakarta Commons Logging and Log4j logging toolkits. Any log messages which your build classes write using these logging toolkits will be redirected to Gradle's logging system.

Gradleは、Java標準のロギング実装や、Jakarta CommonsのCommons Logging、Log4jも統合しています。ビルドで使っているクラスが、これらのツールキットでログメッセージを出力すれば、すべてGradleのロギングシステムにリダイレクトされるでしょう。

18.4. Gradleがロギングするものを変更するChanging what Gradle logs

You can replace much of Gradle's logging UI with your own. You might do this, for example, if you want to customize the UI in some way - to log more or less information, or to change the formatting. You replace the logging using the Gradle.useLogger() method. This is accessible from a build script, or an init script, or via the embedding API. Note that this completely disables Gradle's default output. Below is an example init script which changes how task execution and build completion is logged.

GradleのロギングUIを、独自のものに差し替えることができます。もっと多くの情報を出したい場合、また、逆に出力される情報を減らしたい場合、さらにログフォーマットを変えたいときなどに検討してください。ロギングを差し替えるには、ビルドスクリプトや初期化スクリプト、組み込みAPIからアクセスできるGradle.useLogger()メソッドを使います。次の例では、初期化スクリプトを使って、タスク実行、ビルドの完了をロギングする方法を変更しています。

例18.6 Gradleがロギングするものを変更する

init.gradle

useLogger(new CustomEventLogger())

class CustomEventLogger extends BuildAdapter implements TaskExecutionListener {

    public void beforeExecute(Task task) {
        println "[$task.name]"
    }

    public void afterExecute(Task task, TaskState state) {
        println()
    }
    
    public void buildFinished(BuildResult result) {
        println 'build completed'
        if (result.failure != null) {
            result.failure.printStackTrace()
        }
    }
}

gradle -I init.gradle build の出力

> gradle -I init.gradle build
[compile]
compiling source

[testCompile]
compiling test source

[test]
running unit tests

[build]

build completed

Your logger can implement any of the listener interfaces listed below. When you register a logger, only the logging for the interfaces that it implements is replaced. Logging for the other interfaces is left untouched. You can find out more about the listener interfaces in 「ライフサイクルからの通知に応答するResponding to the lifecycle in the build script. 独自ロガーは、以下にリストしたリスナーインターフェースを実装できます。登録したロガーのインターフェースに対応したロギングのみ差し替えられ、その他のロギングは変更されません。リスナーインターフェースの詳細については「ライフサイクルからの通知に応答するResponding to the lifecycle in the build scriptをご参照ください。