logbackの雑なメモ

[logback](https://logback.qos.ch/) のドキュメントとソースを読んだメモ

調べたバージョンは `1.2.11` で `logback-classic` のメモです

## 設定ファイル クラスの読み込み

マニュアルの[Configuration in logback](https://logback.qos.ch/manual/configuration.html#auto_configuration) によると

1. クラスパスから `logback-test.xml` を探す
1. なければクラスパスから `logback.xml` を探す
1. なければサービスプロバイダーの仕組みを使って `com.qos.logback.classic.spi.Configurator` の実装クラスがあればそれを使う
1. なければ `BasicConfigurator` を使う

となっています。

これらの実装をしているのは [ContextInitializer](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java) です。

### ContextInitializer について

設定をしているクラスです。

`org.slf4j.LoggerFactory#getLogger` が最初に呼ばれたときに [autoConfig](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java#L130) メソッドが呼ばれます。

まず [findURLOfDefaultConfigurationFile](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java#L107) を呼びだしており、ここでxmlファイルを探しています。

[findConfigFileURLFromSystemProperties](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java#L76) ではシステムプロパティの `logback.configurationFile` で指定したxmlファイルを探します。

実装を見ればわかりますがURL, クラスパスのリソース, ファイルパスなどが対応している事がここをみればわかります。

xmlファイルが見つからなかった場合は `Configurator`の実装クラスがサービスプロバイダーで指定されているかをさがします。 [ここ](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java#L136)
あればそれを使い、みつからなければ [BasicConfigurator](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java/ch/qos/logback/classic/BasicConfigurator.java) を使います。

中身をみればわかりますが ここではコンソールに出力を行い レイアウトは`TTLLLayout` というものを使っているようです。

（「どんな方法で設定読み込んでるんだっけ？」ってなった時は このクラスを見てみるのもよいかも）

## 設定ファイルのタグとか
どんなものが設定できたっけ って思ったときはこの辺りのクラス名で調べるとよさそう

- [JoranConfiguratorBase](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-core/src/main/java/ch/qos/logback/core/joran/JoranConfiguratorBase.java)
- [JoranConfigurator](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java/ch/qos/logback/classic/joran/JoranConfigurator.java)

## パターンレイアウトで指定できる内容
マニュアルの[PatternLayout](https://logback.qos.ch/manual/layouts.html#ClassicPatternLayout) を見たほうが早いかもしれないですが

- [PatternLayout](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java) classicの場合
- [PatternLayout](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-access/src/main/java/ch/qos/logback/access/PatternLayout.java) accessの場合

のクラスをみるとどのようなものが用意されているかわかります。
ここからそれぞれの `Converter` クラスに飛ぶことでどのように値が取得されるか確認することができる。

自前の `Converter` を作りたい場合は [Creating a custom conversion specifier](https://logback.qos.ch/manual/layouts.html#customConversionSpecifier)
 を参照

## PostCompileProcessorについて
[PatternLayoutBase#start](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-core/src/main/java/ch/qos/logback/core/pattern/PatternLayoutBase.java#L86) で呼ばれており パターンのコンパイルが終わった後に実行されている。

`logback-classic` だと[PatternLayoutのコンストラクタ](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java/ch/qos/logback/classic/PatternLayout.java#L154)で [EnsureExceptionHandling](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java/ch/qos/logback/classic/pattern/EnsureExceptionHandling.java) がセットされている。

### EnsureExceptionHandling について
パターンの指定の中で 例外のスタックトレースの指定が漏れていた場合(`%ex`, `%xEx`, `%nopex`, `%rootException`) 例外の情報が出力されなくなるのを防ぐためのものっぽい

もし 例外の指定が漏れていた場合は、最後に例外メッセージの出力を追加している。

## Filter
ログの出力をフィルタリングするもの。 アペンダー毎に設定でき、また複数設定できる。

継承はしているが 各アペンダーの基底クラスである [AppenderBase](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-core/src/main/java/ch/qos/logback/core/AppenderBase.java#L47), [UnsynchronizedAppenderBase](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-core/src/main/java/ch/qos/logback/core/UnsynchronizedAppenderBase.java) は [FilterAttachableImpl](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-core/src/main/java/ch/qos/logback/core/spi/FilterAttachableImpl.java) に処理を委譲しており `doAppend` が呼ばれたときにフィルタリングがされている。

## TurboFilter
ログの出力をフィルタリングするもの。 コンテキスト毎に設定でき、また複数設定できる。

アペンダーと違って、`debug`, `info` などのメソッドを実行して すぐのあたりで実行されている。
またコンテキストに紐づいているので、全てのアペンダーが影響を受ける

[このあたり](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java/ch/qos/logback/classic/Logger.java#L373) などで呼ばれている

いずれも[TurboFilterList#getTurboFilterChainDecision](https://github.com/qos-ch/logback/blob/v_1.2.11/logback-classic/src/main/java/ch/qos/logback/classic/spi/TurboFilterList.java) にたどりつき、ここでフィルタリングをしている。

パラメータは違うが `Filter` と仕組みは似たようなもの