Spring Bootのログ出力(概要)

Spring Bootのログ出力(概要)について以下の公式を読んだので訳した。
[26. Logging](
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html)
なお、How-toガイドは[Spring Bootのログ出力(How-toガイド)](http://qiita.com/ARS_2000/items/34356c72e8ac0279e1a0)にまとめた。

# 26. ロギング
Spring Bootでは全ての内部ロギングで[Commons Logging](http://commons.apache.org/proper/commons-logging/)を利用しているが、基本となるログ実装部分は開発者に委ねられている。デフォルトではJava Util Logging、Log4J、Log4J2、Logbackが提供されている。つまりこれらが利用可能ということ。また、これらのいずれを利用するにしろ、コンソール出力と任意のファイル出力も可能な状態に予め設定されている。デフォルト設定では、Starter POMを利用する場合はLogbackが採用される。Logback以外を利用したければdependencyを変更するだけでOK。

## 26.1. ログフォーマット
デフォルト設定での(Logbackでの)ログ出力フォーマットは以下のようになる。

```
2014-03-05 10:57:51.112  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52
2014-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2014-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1358 ms
2014-03-05 10:57:51.698  INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2014-03-05 10:57:51.702  INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*
```

出力項目は左から以下のようになる。

* 日時
	* ミリ秒の精度で出力される
* ログレベル
    * ERROR、WARN、INFO、DEBUG、TRACE(LogbackはログレベルFATALを持たないのでERRORにマッピングされる)
* プロセスID
    * プロセスID
* ---
	* 実際のログメッセージの開始を区別するためのセパレータ
* スレッド名
	* コンソール出力のため切り捨てられる可能性があるので括弧で囲まれている
* ロガー名
	* 通常はクラス名となりしばしば略記される
* ログメッセージ

## 26.2. コンソール出力
デフォルトのログ設定はコンソール出力であり、ログレベルERROR、WARN、INFOのログが出力される。ただ、アプリ起動時に以下ように--debugフラグを付けることでDEBUGレベルのもの出力可能となっている。

```
$ java -jar myapp.jar --debug
```

また、application.propertiesにdebug=trueと明記してもDEBUGレベルでのログ出力は可能となっている。DEBUGレベルのログ出力設定を有効にすることで、組み込みコンテナやHibernate、Spring等のコアなモジュールのログもより多くの情報を出力するため設定される。DEBUGモードを有効にしたからといって、アプリケーションの全てのログがDEBUGレベルで出力されるわけではない。

### 26.2.1. ログ出力の色分けについて

ターミナルがANSIをサポートしていれば、ログの可読性を高めるためログに色付けをして出力することが出来る。また、[supported value](http://docs.spring.io/spring-boot/docs/1.3.2.RELEASE/api/org/springframework/boot/ansi/AnsiOutput.Enabled.html)でサポートされた値の自動検出を上書きするため「spring.output.ansi.enabled」と設定することもできる。色付けは%clrを使うことで設定される、例えば以下のような感じ。

```
%clr(%5p)
```

ログレベルと色のマッピングは以下のようになる。

|ログレベル|色|
|:--|:--|
|FATAL|赤|
|ERROR|赤|
|WARN|黄|
|INFO|緑|
|DEBUG|緑|
|TRACE|緑|

また、以下のように任意の色やスタイルに変更することも可能(以下の例は黄色にする例)。

```
%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}
```

なお、サポートされている色は、青、シアン、faint(何色？)、緑、マゼンタ、赤、黄色となっている。

## 26.3. ファイル出力

前述した通り、Spring Bootはデフォルトでコンソール出力のみであり、ファイル出力は行わない。コンソール出力に加えファイル出力も行いたければ、application.propertiesに「logging.file」もしくは「logging.path」プロパティを追加する必要がある。loggin.*プロパティを一緒に使用する方法は以下の表の通り。

|logging.file|logging.path|例|説明|
|:--|:--|:--|:--|
|なし|なし||コンソール出力のみ|
|特定のファイル|なし|my.log|指定したログファイルに出力される。ファイル名はカレントディレクトへの絶対パス、相対パスで表現できる。|
|なし|特定のディレクトリ|/var/log|指定したディレクトリへspring.logという名前で出力される。ファイル名はカレントディレクトへの絶対パス、相対パスで表現できる。|

ログファイルは10MBに達するとローテートし、ERROR、WARN、INFOレベルのログがデフォルトで記録されるのと同様にコンソール出力される。ロギングシステムはアプリケーションのライフサイクルの早い段階で初期化され、[@PropertySource](https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/annotation/PropertySource.html)アノテーションを介してロードされたプロパティファイルの中ではそのようなログのプロパティは見つけられない。ログのプロパティはロギングインフラから独立している、そのため(Logback用の設定ファイル等)特定の設定用のキーは、Spring Bootによって管理はされていない。

## 26.4. ログレベル

Spring Bootでサポートされている全てのロギングシステムは、‘logging.level.*=LEVEL’を使うことでSpring環境内(例えばapplication.properties等)にログレベルを持つことが出来る。
※LEVELはTRACE、DEBUG、INFO、WARN、ERROR、FATAL、OFFから1つを選択、ルートロガーはlogging.level.rootを使用して設定することができる。
※以下はapplication.propertiesの設定例

```
logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR
```


デフォルトでは、Spring BootはThymeleafのINFOレベルのログをDEBUGレベルで出力されるよう再マッピングする。これは、標準的なログ出力のノイズを減らすために役立っている。再マッピングを設定に入れる場合は[LevelRemappingAppender](https://github.com/spring-projects/spring-boot/blob/v1.3.2.RELEASE/spring-boot/src/main/java/org/springframework/boot/logging/logback/LevelRemappingAppender.java)を参照。

## 26.5. ログのカスタム設定

様々なロギングシステムはクラスパス上の適切なライブラリをincludeすることによって有効になる。さらに、クラスパスのルートまたはSpring環境上のlogging.configによって明記された適切な設定ファイルを配置することによりカスタマイズされる。ロギングはApplicationContexが作られる前に初期化されるので、 Springの設定ファイル上のPropertySourceからロギングを制御することは出来ない。システムプロパティと従来のSpring Boot外部構成はうまく作動する。使っているロギングシステムによって、以下のファイルがロードされる。

|ロギングシステム|カスタム化|
|:--|:--|
|Logback|logback-spring.xml, logback-spring.groovy, logback.xml or logback.groovy|
|Log4j|log4j-spring.properties, log4j-spring.xml, log4j.properties or log4j.xml|
|Log4j2|log4j2-spring.xml or log4j2.xml|
|JDK (Java Util Logging)|logging.properties|

可能であれば、ログ設定に-springバリアントを使用することを推奨する(例えばlogback.xmlではなくlogback - spring.xml)。標準構成の場所を利用する場合、Springはログの初期化を完全に制御することは出来ない。Java Util Loggingでは、executable jarから起動する時に問題を引き起こすというクラスローダの問題は知られているため、可能であればそれを避けた方がよい。

他にもいくつかのSpringプロパティはシステムプロパティとして利用出来るためカスタムするのに役に立つ。

|Springプロパティ|システムプロパティ|備考|
|:--|:--|:--|
|logging.exception-conversion-word|LOG_EXCEPTION_CONVERSION_WORD|例外をログに記録する場合に使用される変換語|
|logging.file|LOG_FILE|デフォルトのログ設定が定義されている場合に使われる|
|logging.path|LOG_PATH|デフォルトのログ設定が定義されている場合に使われる|
|logging.pattern.console|CONSOLE_LOG_PATTERN|コンソール出力のログパターン、JDKのロガーはサポートされていない|
|logging.pattern.file|FILE_LOG_PATTERN|ファイル出力のログパターン、JDKのロガーはサポートされていない|
|logging.pattern.level|LOG_LEVEL_PATTERN|この形式はLogbackでのみサポートされている。デフォルトは%5p|
|PID|PID|プロセスID|

設定ファイルを解析する時、サポートされている全てのロギングシステムはシステムプロパティを参照することが出来る。サンプルについてはspring-boot.jarのデフォルト設定を参考にしてほしい。

ロギングシステムでプレースホルダーを使いたい場合、[Spring Boot’s syntax](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-placeholders-in-properties)と基礎となるフレームワークのないシンタックスを使用する必要がある。
Logbackを使っている場合、プロパティ名のデフォルト値のデリミタとして「：」を利用する必要がある。

## 26.6. Logbackの拡張

Spring Bootは、より進んだ構成にするためのLogbackに多くの拡張を含んでいて、これらの拡張をlogback-spring.xml構成ファイルの中で利用することが出来る。
※基本のlogback.xml構成ファイルでは、読み込みが早すぎるためそれらの拡張を利用することが出来ないので、logback-spring.xmlを使用するか、logging.configのプロパティを定義する必要がある。

## 26.6.1. プロファイル固有の設定

`<springProfile>`タグは、有効なSpringプロファイルに基づいた構成を任意で含んだり排除したりできる。Profileセクションは`<configuration>`要素の範囲内でどこでもサポートされる。各プロファイルを識別するためname属性が使用され、複数のプロファイルはカンマ区切りで設定出来る。以下は設定例。

```
<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev, staging">
    <!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
    <!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>
```

## 26.6.2. 環境プロパティ

`<springProperty>`タグはLogback内で使用することでSpring環境からプロパティを表面化できる。logbackの設定の中でapplication.propertiesから値にアクセスしたい場合、これは役立ち、直接値を明記するというより、Logbackの基本の`<property>`タグと同じ方法で動く。local scopeで他のどこかにプロパティを保存する必要があるならばscope属性を使用できる。

```
<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
	<remoteHost>${fluentHost}</remoteHost>
	...
</appender>
```