第2章 アーキテクチャ
本物の分類学とは、系統学のことなのだ。
—CHARLES DARWIN, The Origin of Species
文字で書かれたものを読むだけで、得られた情報を具体的な問題に適用し、読んだことを自分のものとして考えること無しには、問題そのものを学ぶことは、不可能ではないが困難だ。さらに、私たちは自ら発見した時にこそ最も良い学びを得るのだ。
—DONALD KNUTH, The Art of Computer Programming
Logbackのアーキテクチャ
logback の基本的なアーキテクチャは、さまざまな状況に対応できるよう、十分に汎用的になっています。今のところ、logbackは三つのモジュールに分割されています(logback-core、logback-classic、logback-access)。
coreモジュールは、他の二つのモジュールの足回りとして使用されています。classicモジュールは、 coreを拡張するものです。classic モジュールは、著しく改善されたバージョンのlog4jとも考えられます。logback-classic は SLF4J API を直接実装しているので、log4j や java.util.logging(JUL)などの他のロギング実装と切り替えることができます。三つ目のaccessと呼ばれるモジュールは、HTTPのアクセスログ機能を提供するため、サーブレットコンテナと統合しています。access モジュールについては別のドキュメントに記載されています。
このドキュメントの残りの部分では、logback-classicモジュールのことを "logback" と表記しています。
ロガー、アペンダー、レイアウト
logback は三つの主要なクラス(Logger
、 0}Appender、Layout
)で成り立っています。これらの三つのコンポーネントが協調することで、開発者はメッセージを適切な種類、レベルでロギングできるようになっています。また、書式化や出力先を実行中に変更できるようにもなっています。
Logger
クラスは、logback-classicモジュールに含まれています。一方、 Appender
とLayout
インタフェイスは、logback-coreモジュールに含まれています。logback-core モジュールは共通モジュールなので、logger の責務を含まないのです。
ロガーコンテキスト
どんなロギングAPIであっても単純なSystem.out.println
に勝る第一の、そして最大の利点があります。それは、特定のロギング式を無効にしつつ、他のロギング式には一切影響を与えない機能です。この機能は、ロギング空間、すなわち、すべてのロギング式からなる空間が、開発者の選択した基準に基いて分類されていることを前提としています。logback-classic モジュールにおいて、この分類は logger に固有のものです。全てのロガーは LoggerContext
に接続します。LoggerContext
には、接続してきたロガーを階層的な木構造として配置する責務があります。
ロガーは名前を持ったエンティティです。名前は大文字と小文字が区別され、階層的な命名規則に従うようになっています。
あるロガーの名前が、他のロガーの名前の中で「.」(ドット)で区切られた前置詞となっているとき、それぞれが先祖と子孫となります。自分自身や、自分の子にも祖先がいない場合、そのロガーは親になります。
たとえば、"com.foo"
という名前のロガーは、"com.foo.Bar"
というロガーの親になります。同様に、 "java"
は"java.util"
の親であると同時に、"java.util.Vector"
の祖先になります。この命名スキームは、ほとんどの開発者がきちんと理解しなければならないものです。
ルートロガーは、ロガー階層の最上位に存在するものです。複数の階層構造すべてに含まれるという意味で、例外的な存在です。他のロガーと同じように、名前で取得することができます。こんな風に。
Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
他のロガーも、org.slf4j.LoggerFactory