PEAR_ErrorStackを使ったエラーログの記録方法

presented by 役に立つかもしれないBlog

はてなブックマーク - PEAR_ErrorStackを使ったエラーログの記録方法

2009年12月15日 00:33

PEARには高機能なエラー処理機構をもつPEAR::ErrorStackパッケージがありますが、実践的な使いかたの情報がとにかく少ないです。 今回は、そんな貴重なErrorStackパッケージを使ったエラーログの記録方法について書いてみます。

エラーメッセージだけなら簡単

標準的な使い方で、エラーメッセージをログに記録することができます。

/**
 * エラー記録用グローバルエラーオブジェクトの生成と準備
 */
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] メールアドレスを入力してください。

これだけでも、一応エラーログとしての役割は果たしてくれます。

さらに詳しいデータを記録するには?

さて、先ほどはシンプルなエラーメッセージを記録するだけでしたが、これだけ記録しても正直原因がよく分かりません。 そう、エラーの元となったパラメーターやエラーの発生場所が記録されていないのです。

詳しい情報を記録するにはコールバック関数を定義

ErrorStackパッケージには、エラーを格納する際に発生させるコールバック関数を定義することができます。 ちょうどログファイルにエラーを記録する前に割り込みを発生させるようなイメージですね。

ErrorStackパッケージでは、そのコールバック関数の中で詳しい情報を得ることができたり、別の処理を行ったりできるようになっているのです。 あら便利!

このしくみを応用すると、エラーログが記録された瞬間にサーバー管理者に警告メールを送信できたりもします。 エラーレベルによって処理も分けられます。

さて、コールバック関数の定義方法は通常の関数と同じですが、1つだけエラー配列を格納させる引数を用意しておいてください。

/**
 * ErrorStack::push()時に呼ばれるコールバック関数
 *
 * @param array $err エラー情報配列
 */
function doAfterPush($err)
{
    ...(処理内容)...
}

そして、この関数を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'] エラーの発生した時間。

エラーの元となったパラメーター、対象ファイルなどを記録しよう

さて、これだけ情報がそろえばエラーログもだいぶ詳細に残すことができます。 では、これらを踏まえて、以下の情報をエラーログに記録してみましょう。

/**
 * エラー格納時のコールバック関数
 */
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を参照する方法がなかったので使ってみました。 もっと良い方法があったら教えてください。

WebMoney ぷちカンパ  Yahoo!ブックマーク  favicon  はてなブックマーク  livedoorリーダー Buzzurl

関連情報

コメントフォーム