Symfony2 + Monolog でのロギングについて(その1)
Symfony2 のロギングでデフォルトで使われてる Monolog について調べたので忘れないうちにまとめておく。 何回かに分けて書きます。今回は Monolog イットセルフについて。
Monolog のバージョンは 1.7.0。
Monolog の構造
Monolog は4つのコンポーネントからなります。
ロガー
コントローラで$logger = $this->get('logger')
って取得するおなじみのあいつ。Logger
クラス。 プロセッサとハンドラをいずれも複数登録できます。ハンドラ
メイン処理担当。ロガーからログ情報を受け取って、プロセッサで前処理して、フォーマッタで成形して、出力する。 プロセッサを複数とフォーマッタを1つ、登録できます。 また、以降のハンドラに処理を続行させるかどうかのフラグ (bubble フラグ) も持ちます。 代表的なStreamHandler
はファイルにログを書き込むハンドラです。プロセッサ
ログ情報の前処理を担当。 例えばIntrospectionProcessor
は、ログメソッドの呼ばれた箇所のファイル名、行番号、クラス名、メソッド名を、ログ情報の extra フィールドに付加します。フォーマッタ
ログ情報の成形を担当。 デフォルトのLineFormatter
は、ログ情報を文字通り1行のログに成形します。
プロセッサはロガーとハンドラどっちにも登録出来て、
ロガーに登録すれば、共通の前処理をハンドラに渡す前にさせることができるし、
ハンドラに登録すれば、そのハンドラ専用の前処理をさせられます。
コンポーネント同士の登録関係を図にすると例えばこんな感じ?
ロガー └ プロセッサ1 │ └ ハンドラ1 │ └ プロセッサ1 │ └ プロセッサ2 │ └ フォーマッタ │ └ ハンドラ2(プロセッサなし) └ フォーマッタ
ログ情報 = record
ログ情報は "record" という名前の連想配列でやり取りされます。 record 1つがログ1行に相当します。
こんな形式です。
$record = array( 'message' => "xxxx", // ログメッセージ本文 'level' => 400, // ログレベルを表す数値。DEBUG なら 100, ERROR なら 400 など 'level_name' => "ERROR", // ログレベルを表す文字列 'channel' => "main", // Logger 自身の名前を表す文字列 'datetime' => new \DateTime(), // タイムスタンプ 'context' => array(), // 追加情報その1。ロガーを呼ぶ側から利用出来る。 'extra' => array(), // 追加情報その2。プロセッサなどが使用。 'formatted' => "xxxx", // フォーマッタによる整形済みの文字列 );
「追加情報」が context
と extra
の2つありますけど
- context は、
$logger->debug("ログメッセージ", array(1, 2, 3))
のようにログメソッドの第2引数として外から渡すことのできる情報 - extra は、プロセッサなどが内部的に追加する情報
です。ちなみに LineFormatter
の場合、どちらも単純に json_encode で文字列化して出力してくれます。
おおざっぱな動作
ログメソッドを呼んだ際、各コンポーネントがどんな風に連携して動作するのか、ざくっと解説します。
ハンドラによって動作は微妙に異なるので、ここでは代表的な組み合わせとして StreamHandler
+ LineFormatter
を想定します。
スタート地点は $logger->debug("ログメッセージ")
ですね。
- (Logger) ログメッセージを元に record 連想配列を作る
- (Logger) record をロガーのプロセッサで前処理
- (Logger) ハンドラを順に実行して record を処理していく
- (Handler) record のログレベルを確認、処理対象でなければ何もせず終了
- (Handler) record をハンドラのプロセッサで前処理
- (Handler) record をフォーマッタで文字列に変換
- (Handler) 文字列をファイルに出力
- (Handler) ハンドラの bubble フラグが false なら、これ以降のハンドラでの処理を停止する
今回はここまで。次回は Monolog を Symfony2 で使う際の設定方法について書く予定。