12月 262011
どんなアプリケーションを開発するときでも、簡単にログを出力できる仕組みは早いうちに実装しておきたいものだ。Zend Frameworkでログ出力をするときはZend_Logを利用するのが一般的。サンプルコードを見ると、
$writer = new Zend_Log_Writer_Stream('php://output');
$logger = new Zend_Log($writer);
と、ライターのインスタンスを生成してロガーのインスタンスを生成するコードを書くのか?と思わされるが、幸いZend_Application_Resource_Logというリソースプラグインが用意されているので、
resources.log.stream.writerName = "Stream" resources.log.stream.writerParams.stream = "php://output"
のような設定ファイルを作れば、ブートストラップからZend_Logのインスタンスを取得できるようになる。`zf create project`コマンドで作られるデフォルトのエラーコントローラには、ブートストラップを利用してログを出力するコードが含まれている。
class ErrorController extends Zend_Controller_Action
{
public function errorAction()
{
(略)
// Log exception, if logger available
if ($log = $this->getLog()) {
$log->crit($this->view->message, $errors->exception);
}
(略)
}
public function getLog()
{
$bootstrap = $this->getInvokeArg('bootstrap');
if (!$bootstrap->hasResource('Log')) {
return false;
}
$log = $bootstrap->getResource('Log');
return $log;
}
}
エラーコントローラでだけでなく、自前のアクションコントローラでも同じようにログ出力を行いたいと思ったときに、上記のような実装をいちいち書かなければならないのは非常に面倒なので、こういう場合はアクションヘルパーを作ってしまうのが一番。
class My_Action_Helper_Log extends Zend_Controller_Action_Helper_Abstract
{
public function direct()
{
call_user_func_array(array($this, 'info'), func_get_args());
}
public function __call($method, $params)
{
$logger = $this->_getLogger();
if($logger)
{
call_user_func_array(array($logger, $method), $params);
}
}
private function _getLogger()
{
$bootstrap = $this->getActionController()->getInvokeArg('bootstrap');
return $bootstrap->hasResource('Log') ? $bootstrap->getResource('Log') : false;
}
}
マジックメソッド__call()を使うことで、Zend_Logが持っている関数すべてにアクセスできるようにしている。プロキシクラスね。_getLogger()関数は、前述のエラーコントローラーのgetLog()関数の実装をパクった。アクションコントローラなのでdirect()を実装して、ここではとりまZend_Log::INFOでログ出力するようにしたが、アプリケーションの中で最も頻繁に使われるプライオリティを実装しておくといいだろう。
前述のエラーコントローラでのログ出力部分が
// Log exception, if logger available
$this->_helper->log->crit($this->view->message, $errors->exception);
と、呼び出せるようになる。
1 コメント