PSR-3(Logger Interface)を見ていく
要約ですので、所々省いている箇所あります。
オリジナルはこちら
概要
- ロギングライブラリの共通インターフェースのドキュメント
- ゴールはライブラリが
Psr\Log\LoggerInterface
を受け入れることでログ出力をシンプルかつ共通化を行う - フレームワーク、CMSは必要によってインターフェースを拡張してもよいが、インターフェースを遵守しなければいけない
- こうすることでサードパーティライブラリでもログを集約することができる
仕様
基礎
LoggerInterface
は8個のメソッドを提供し、レベルは8個(debug, info, notice, warning, error, critical, alert, emergency)- 9番目のメソッド
log
は第一引数にログレベルを受け取る。ログレベル定数の一つを受け取ったメソッドの結果は、各レベルごとのメソッドの結果と同じでなければならない - 定義されていないレベルを引数として受け取った場合、
Psr\Log\InvalidArgumentException
をthrowしなければならない - ユーザはカスタムレベルを使うべきではありません
メッセージ
- 各メソッドはメッセージとして
string
か、__toString()
を持つオブジェクトを受け取る。 - 実装者はオブジェクトを何らかハンドリングしてもよいですが、そのケースではない時は、
string
にキャストしなければいけません - メッセージは配列の値から置換できるプレースホルダーを含んでもよい
- プレースホルダーの命名は配列のキーと一致しなければならない
- プレースホルダーは
{}
で囲まないといけない。囲んでいる中にホワイトスペースを入れてはいけない - プレースホルダーは
A-Z, a-z, 0-9, _, .
だけを使うべき。それ以外は今後のプレースホルダー仕様変更用に予約されています - 実装者は、プレースホルダーを表示用にエスケープ、翻訳してもよい。ユーザは事前にプレースホルダーの値をエスケープすべきではない。
プレースホルダーの例
/** * Interpolates context values into the message placeholders. */ function interpolate($message, array $context = array()) { // build a replacement array with braces around the context keys $replace = array(); foreach ($context as $key => $val) { // check that the value can be casted to string if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) { $replace['{' . $key . '}'] = $val; } } // interpolate replacement values into the message and return return strtr($message, $replace); } // a message with brace-delimited placeholder names $message = "User {username} created"; // a context array of placeholder names => replacement values $context = array('username' => 'bolivar'); // echoes "User bolivar created" echo interpolate($message, $context);
Context
- 各メソッドは、配列をコンテキストデータとして受け取る
- これはストリングでは表現できない補足情報を持たせることを意味します
- 実装者はコンテキストデータを出来る限り寛大に扱わなければいけない
コンテキストデータによって、exceptionをthrowしたり、エラー、ワーニング等々を出してはいけない
もしExceptionオブジェクトがコンテキストデータで渡された時、それは
exception
キーの中になければいけない- exceptionのロギングは共通パターンにすることで、実装者はexceptionからスタックトレースを抽出することができます
- 実装者はexceptionキーの値が実際に
Exception
か検証しなければいけません
ヘルパークラスとインターフェース
Psr\Log\AbstractLogger
クラスを継承することで簡単にLoggerInterface
と、汎用のlog
を提供します- 同様に
Psr\Log\LoggerTrait
を使うことで実装がするのは汎用のlog
メソッドだけです - しかしtraitsはインターフェースを実装せきないため、この場合は
LoggerInterface
を実装する必要があります Psr\Log\NullLogger
はインターフェースと共に提供されます。これはユーザによってログがいらない場合にブラックホール用のインターフェースを提供します。しかしコンテキストデータの生成コストがかかる場合は条件付きロギングの方が良いですPsr\Log\LoggerAwareInterface
はsetLogger(LoggerInterface $logger)
メソッドのみ含み、任意のインスタンスをロガーで接続するフレームワークで使用できますPsr\Log\LoggerAwareTrait
トレイトはどのクラスでも簡単に等価なインターフェースを提供します。$this->logger
でアクセスできますPsr\Log\LogLevel
は8個のログレベルを定数として持っています
色々composer経由で各種ライブラリを組み合わせて作るのが主流になっているので、その際個別にログ出力を実装しているとフォーマット、ディレクトリ等々バラけてしまいます。 またログレベルがバラバラだと環境別に出力の設定をしたい時個別にそれぞれしないといけません。
そこのインターフェース揃えれば、共通化できるし、差し替えも可能って感じかと!
PSR-4(Autoloader)へ続く・・・