例えば、次のようなコードを試してみてください。
for ($i = 0; $i < 5; $i++) {
l("my message.");
sleep(2);
}
ログファイルの内容をtailコマンドなどで監視すると、アプリケーションの処理が全て終わった後に全てのメッセージが一斉にファイルに出力されることが分かります。そう、メッセージは2秒おきに出力されるわけではありません。
リアルタイムに、l()関数を呼び出す度に書き出して欲しい場合は、下記のコードを追加してください。
Sabel_Logger::create()->realtime(true);
for ($i = 0; $i < 5; $i++) {
...
}
なお、realtime()メソッドにtrueが渡された場合、その時点まででバッファされていたメッセージは一斉に出力されます。
カスタムロガーの登録
独自のログ出力クラスをロガーに登録することが可能です。例えば、クリティカルな箇所で発生したエラーに関するメッセージをロガーに渡し、それをカスタムロガーで捕捉し開発者にメールで通知するなどに使用できます。
例えば重要なロジックで、下記のようにメッセージをロガーに送ります。
try {
...
} catch (MyException $e) {
l("ERROR: " . $e->getMessage(), SBL_LOG_ERR, "critical");
return false;
}
※このメッセージはデフォルトのロガーにも渡されるため、
logs/critical.log にも出力されます。
次に、上記のログメッセージを捕捉するためのクラスを作成します。addLogger()するインスタンスは
Sabel_Logger_Interface を実装していなくてはなりません。
class MyLogger implements Sabel_Logger_Interface
{
public function output($logs)
{
}
public function write($identifier, $message)
{
}
}
output()メソッド には全てのログが渡されます。渡される引数は配列で、以下のような構造となっています。識別子が配列のキーになっています。
array(2) {
["default"]=>
array(4) {
[0]=>
array(3) {
["time"]=>
string(19) "2009-01-01 00:00:00"
["level"]=>
int(1)
["message"]=>
string(14) "my message."
}
[1]=>
array(3) {
["time"]=>
string(19) "2009-01-01 00:00:01"
["level"]=>
int(1)
["message"]=>
string(14) "my message."
}
}
["critical"]=>
array(1) {
[0]=>
array(3) {
["time"]=>
string(19) "2009-01-01 00:00:02"
["level"]=>
int(8)
["message"]=>
string(11) "my message."
}
}
}
write()メソッド の第1引数には識別子が、第2引数にはメッセージが渡されます。メッセージとは
time, level, message のキーを持った配列です。なお、このwrite()メソッド はリアルタイム出力時にのみ呼び出されるものです。
output() にはメッセージの配列が、write() にはメッセージの一つ一つが渡されるため、下記のようにすれば write()メソッドに処理を集約することができます。
public function output($logs)
{
foreach ($logs as $identifier => $messages) {
foreach ($messages as $message) {
$this->write($identifier, $message);
}
}
}
今回作成したロガーは "critical" メッセージだけ捕捉すれば良いので、write()メソッド は次のように実装できます。メールを送信するコードを記述すれば目的としていたカスタムロガーの完成です。
public function write($identifier, $message)
{
if ($identifier === "critical") {
$mail = new Sabel_Mail("ISO-2022-JP");
$mail->setFrom("systemerr@example.com");
$mail->setTo("developer@example.com");
$mail->setSubject("...");
$mail->setBody("...");
$mail->send();
}
}
※メールの送信に関してはメールの章を参照してください。
関連項目