PEAR_ErrorStackを使ったエラーログの記録方法
PEARには高機能なエラー処理機構をもつPEAR_ErrorStackパッケージがありますが、実践的な使いかたの情報がとにかく少ないです。 今回は、そんな貴重なPEAR_ErrorStackパッケージを使ったエラーログの記録方法について書いてみます。
インストールは不要
PEAR_ErrorStackはPEARをインストールすると標準で付いてくるので、コマンドでいちいちパッケージをインストールする必要がありません。 すぐに利用できるのも便利なところですね。
エラーメッセージだけなら簡単
まず標準的な使い方をば。 以下の方法でエラーメッセージをログに記録することができます。 この時に「/path/to/error_log.txt」ファイルにログが記録されます。
この例ではログをテキストファイルに記録するために「PEAR::Log」パッケージを利用しています。 ですので、テストする前にPEAR::Logパッケージを「pear install Log」コマンドでインストールしておきましょう。
/** * エラー記録用グローバルエラーオブジェクトの生成と準備 */ require_once('Log.php'); require_once('PEAR/ErrorStack.php'); $logger = &Log::singleton('file', '/path/to/error_log.txt'); $error_stack = &PEAR_ErrorStack::singleton('myWebApp'); $error_stack->setLogger($logger); /** * メールチェックで失敗した例 */ define('ERROR_CODE_EMAIL', -100); if (!$email) { $errParam = array('email' => $email); $errMsg = 'メールアドレスを入力してください。'; $error_stack->push(ERROR_CODE_EMAIL, 'error', $errParam, $errMsg); }
これで、error_log.txt ファイルに以下のようなエラーログが記録されます。
Dec 15 00:24:57 [error] メールアドレスを入力してください。
これだけでも、一応エラーログとしての役割は果たしてくれます。
さらに詳しいデータを記録するには?
さて、先ほどはシンプルなエラーメッセージを記録するだけでしたが、これだけ記録しても正直原因がよく分かりません。 そう、エラーの元となったパラメーターやエラーの発生場所が記録されていないのです。
詳しい情報を記録するにはコールバック関数を定義
PEAR_ErrorStackパッケージには、エラーを格納する際に発生させるコールバック関数を定義することができます。 ちょうどログファイルにエラーを記録する前に割り込みを発生させるようなイメージですね。
PEAR_ErrorStackパッケージでは、そのコールバック関数の中で詳しい情報を得ることができたり、別の処理を行ったりできるようになっているのです。 あら便利!
このしくみを応用すると、エラーログが記録された瞬間にサーバー管理者に警告メールを送信できたりもします。 エラーレベルによって処理も分けられます。
さて、コールバック関数の定義方法は通常の関数と同じですが、1つだけエラー配列を格納させる引数を用意しておいてください。
/** * ErrorStack::push()時に呼ばれるコールバック関数 * * @param array $err エラー情報配列 */ function doAfterPush($err) { ...(処理内容)... }
そして、この関数をPEAR_ErrorStackインスタンスのpushCallback関数を使ってコールバック関数として割り当てます。
$error_stack->pushCallback('doAfterPush');
$errの内容は?
コールバック関数に入ってくるエラー情報配列は以下のような情報が入っています。
$err[‘code’] | エラーコード番号。 $error_stack->push()の1つめのパラメーターですね。 |
---|---|
$err[‘level’] | ログレベル。 $error_stack->push()の2つめのパラメーターですね。 今回の例でいうと「error」にあたります。 |
$err[‘params’] | エラーの元となったパラメーター格納配列。 $error_stack->push()の3つめのパラメーターですね。 エラーメッセージとは別に、エラーの元となった、ユーザーが入力したデータなどを入力フォームのname属性とセットで入れておく際などに利用できます。 |
$err[‘message’] | エラーメッセージ。 $error_stack->push()の4つめのパラメーターです。 今回だと「メールアドレスを入力してください。」というデータになります。 |
$err[‘context’] | 以下の3つのキーを持つハッシュ配列です。 ・file => エラーが発生したファイル名。 ・line => エラーが発生したファイルの行番号。 ・function => エラーが発生した関数名。 |
$err[‘package’] | インスタンスを生成する際に付けたパッケージ名。 今回の例でいうと「myWebApp」ですね。 |
$err[‘time’] | エラーの発生した時間。 |
エラーの元となったパラメーター、対象ファイルなどを記録しよう
さて、これだけ情報がそろえばエラーログもだいぶ詳細に残すことができます。 では、これらを踏まえて、以下の情報をエラーログに記録してみましょう。
- エラーの元となったパラメーター。($err[‘params’])
- エラーのコンテキスト($err[‘context’])
/** * エラー格納時のコールバック関数 */ function doAfterPush($err) { if ($err['level'] == 'error') { //エラーのきっかけになったパラメーター $GLOBALS['logger']->log(print_r($err['params'],true), PEAR_LOG_ERR); //エラーの発生したファイル名・行数・関数名 $GLOBALS['logger']->log(print_r($err['context'],true), PEAR_LOG_ERR); } } /** * エラー記録用グローバルエラーオブジェクトの生成と準備 */ require_once('Log.php'); require_once('PEAR/ErrorStack.php'); $logger = &Log::singleton('file', '/path/to/error_log.txt'); $error_stack = &PEAR_ErrorStack::singleton('myWebApp'); $error_stack->setLogger($logger); $error_stack->pushCallback('doAfterPush');
これで定義ができました。 実際に利用する際は通常どおりの処理でOKです。
/** * メールチェックで失敗した例 */ define('ERROR_CODE_EMAIL', -100); if (!$email) { $errParam = array('email' => $email); $errMsg = 'メールアドレスを入力してください。'; $error_stack->push(ERROR_CODE_EMAIL, 'error', $errParam, $errMsg); }
コールバック関数で$GLOBALSを使うのに迷いましたが、$loggerを参照する方法がなかったので使ってみました。 もっと良い方法があったら教えてください。
2009-12-15