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