Top > PHP > CakePHP > CakePHPのログをLog4phpに切り替える

RIGHT:&tag(CakePHP);
#contentsx

* CakePHPのログをLog4phpに切り替える [#lf1889ce]
ロギング処理をLog4JのPHP版であるLog4phpに切り替えます。
CakePHPのログはファイルに出力する単純な機能しかないので、ローテーションの設定などが本番運用時に必要と思われるので、Log4phpを導入することにします。
-Log4jについては、下記のページを参照してください。
--[[Log4J徹底解説〜目次:http://www.nurs.or.jp/~sug/soft/log4j/index.htm]]
--[[Log4Jの基本Log4J-TECHSCORE-:http://www.techscore.com/tech/ApacheJakarta/Log4J/1.html]]
--[[Log4j Q&A:http://www.okisoft.co.jp/esc/log4j/index.html]]
** Log4phpのインストール [#x30c4452]
-[[Do You PHP? - log4php - PHP版log4j:http://www.doyouphp.jp/tips/tips_log4php.shtml]]
を参考にしました。
-[[log4php - log4j ported to PHP! - Download Page:http://www.vxr.it/log4php/download.html]]
から最新のlog4php-0.9.zipをダウンロードします。
-展開したファイル一式を下記のフォルダにコピーします。
log4php-0.9\src\log4php
を
%%cake/libs/log4php%%
vendors/log4php
にコピーする。
&color(Red){※cakeフォルダではなく、vendorsフォルダに入れるほうがよさそうなので、そちらにしました。};

** CakePHP標準のロギング処理を修正 [#i13e923a]
-下記のファイルにロギング処理が書かれているので修正します。
cake/libs/cake_log.php
 <?php
 
   if (!class_exists('File')) {
      uses('file');
   }
 
 /*** log4phpのプロパティファイルの設定とインクルードを行うように追加 ***/
 if (!defined('LOG4PHP_CONFIGURATION')) {
   if (!defined('APP_DIR')) {
     define('LOG4PHP_CONFIGURATION', dirname(dirname(__FILE__)) . DS .'config' .DS .'log4php.properties');
   } else {
     define('LOG4PHP_CONFIGURATION', ROOT . DS . APP_DIR . DS .'config' .DS .'log4php.properties');
   }
 }
 require_once(VENDORS.'log4php/LoggerManager.php');
 /*** ここまで ***/
 
 class CakeLog{
 
   /*** デストラクタをObjectクラスの真似をして用意する ***/
   function CakeLog() {
     $args = func_get_args();
     if (method_exists($this, '__destruct')) {
       register_shutdown_function (array(&$this, '__destruct'));
     }
   }
   
   function __destruct() {
     // log4phpのLoggerをシャットダウンする
     LoggerManager::shutdown();
   }
   /*** ここまで ***/
  
   function write($type, $msg) {
     
     /*** Log4phpを使用する場合のみ ***/
     if (defined('LOG4PHP_ENABLE') && LOG4PHP_ENABLE == 1) {
       $logger =& LoggerManager::getLogger(basename($_SERVER['SCRIPT_NAME']));
       $output = sprintf('[%s] %s', session_id(), $msg);
       switch ($type) {
         case 'debug':
           $logger->debug($msg);
           $logger->debug($output);
           break;
         case 'error':
           $logger->error($msg);
           $logger->error($output);
           break;
       }
       return true;
     }
     /*** ここまで ***/
     
     $filename = LOGS . $type . '.log';
     $output = date('Y-m-d H:i:s') . ' ' . ucfirst($type) . ': ' . $msg . "\n";
     $log = new File($filename);
     return $log->append($output);
   }
   
 }
 ?>
&color(Red){※log4phpの本体をvendorsフォルダに移動したため、そこからインクルードするようにした。};
&color(Red){※log4phpのLoggerをシャットダウンしないといけないようなので、デストラクタを作って対応した。};
&color(Red){※セッションIDもログメッセージに付加するようにした。};
** Log4phpのエラー対策 [#ue3ebb6a]
-そのままだと、Log4phpでエラーになります。
画面に下記のようなメッセージが表示される。
 Notice: Only variable references should be returned by reference in
 C:\eclipse_pdt\workspace\cakeshop\cake\libs\log4php\LoggerAppender.php on line 73
-もしかしたら、php4の場合だけかもしれませんが、同じような現象が、下記のスレッドに書かれていたので、対応します。
[[[s2container-php5:53] Re: [質問]S2DaoのMetaDataクラスとログ出力について:http://ml.seasar.org/archives/s2container-php5/2006-September/000051.html]]
-log4php\LoggerAppender.phpの60行目
 function &singleton($name, $class = '')
 ↓
 function singleton($name, $class = '')
-log4php\LoggerPropertyConfigurator.phpの509行目
 function &parseCategory($props, &$logger, $optionKey, $loggerName, $value)
 ↓
 function &parseCategory($props, &$logger, $optionKey, $loggerName, $value)
-log4php\LoggerPropertyConfigurator.phpの574行目
 $appender =& LoggerAppender::singleton($appenderName);
 ↓
 $appender = LoggerAppender::singleton($appenderName);
-log4php\LoggerPropertyConfigurator.phpの587行目
 $appender =& LoggerAppender::singleton($appenderName, $appenderClass);
 ↓
 $appender = LoggerAppender::singleton($appenderName, $appenderClass);

** アプリケーション毎の設定 [#mae606a3]

*** グローバル定数 [#k7eabb53]
-Log4phpを使用するかをアプリケーション毎に設定します。
app/config/core.phpに下記を追加
 /**
  * Set Log4php here:
  * - 0: Log4phpを使用しない
  * - 1: Log4phpを使用する
  */
 define('LOG4PHP_ENABLE', 1);

*** Log4phpの設定 [#lb32fd5d]
-Log4phpの設定は、propertiesファイルとして作成します。
日付毎にファイルを切り替えるようにする設定
app/config/log4php.properties
 #---------------------------------
 # @rotete daily
 # @logfile ./log/error_log_%s.txt
 # @pattern %d [%t] %-5p %c - %m%n
 #---------------------------------
 log4php.rootLogger=DEBUG, R
 log4php.appender.R=LoggerAppenderDailyFile
 log4php.appender.R.file=../tmp/logs/error_log_%s.txt
 log4php.appender.R.layout=LoggerPatternLayout
 log4php.appender.R.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
設定方法は、Log4Jと同じです。
ログの出力ファイルは、とりあえず
app/tmp/logs/error_log_日付.txt
にしています。
-ファイルサイズによってローリングする設定
 log4php.rootLogger=DEBUG, R
 log4php.appender.R=LoggerAppenderRollingFile
 log4php.appender.R.file=../tmp/logs/error_log.txt
 log4php.appender.R.layout=LoggerPatternLayout
 log4php.appender.R.layout.ConversionPattern=%d [%t] %-5p %c - %m%n
 log4php.appender.R.MaxFileSize=10240
 log4php.appender.R.MaxBackupIndex=3
この場合は、error_log.txt.1、error_log.txt.2とファイル名の後ろに数字が付加されてバックアップが3つまで残る設定です。
** ログの出力方法 [#rbad35c2]
-CakePHPのログ出力方法と同じです。
 // デバッグ用のログ
 $this->log('ログメッセージ', LOG_DEBUG);
 // エラーログ
 $this->log('ログメッセージ');

-出力すると、ログファイルに下記のような内容で書き込まれます。
 2007-02-07 00:39:33,705 [192] DEBUG ログメッセージ
 2007-02-07 00:39:33,705 [192] ERROR ログメッセージ

** SQLのログもlog4phpでファイルに出力する [#u372962b]
-SQLのログは、DEBUGを2にしておくと画面に表示されますが、ログの内容をファイルに保存したいと思います。
-クエリーでエラーが発生した場合は、errorで出力し、その他は、debugで出力するようにします。
-下記のソースを修正します。
cake/libs/model/datasources/dbo_source.php
   function logQuery($sql) {
     $this->_queriesCnt++;
     $this->_queriesTime += $this->took;
     $this->_queriesLog[] = array('query' => $sql,
           'error'    => $this->error,
           'affected'  => $this->affected,
           'numRows'  => $this->numRows,
           'took'    => $this->took
     );
     // SQLのクエリーログを出力する
     $logMessage = 'queryLog = '.print_r($this->_queriesLog[count($this->_queriesLog) - 1], true);
     if ($this->error) {
       $this->log($logMessage, LOG_ERROR);
     } else {
       $this->log($logMessage, LOG_DEBUG);
     }
     // ここまで
     if (count($this->_queriesLog) > $this->_queriesLogMax) {
       array_pop($this->_queriesLog);
     }
     if ($this->error) {
       return false;
     }
   }
これで、何かSQLの異常が発生した場合に、ログファイルで確認できるようになります。

** 通常のロギング処理でのエラー対策 [#i29ca196]
-log4phpを使わない場合のロギングでエラーになります。
[[Webプログラミングに関するメモ: CakePHPの$this->log()、php4.4.4でエラー:http://asaton.seesaa.net/article/32237074.html]]
に書かれていました。
-log4phpを使うのであれば、修正しなくても良いかもしれませんが、念のために修正しておきます。
cake/libs/file.php
 if (file_exists($dir) && is_dir($dir) && is_writable($dir) && !$this->exists()) {
   if (!touch($this->getFullPath())) {
     print ("[File] Could not create {$this->name}!");
     return false;
   } else {
     return true;
   }
 } else {
   print ("[File] Could not create {$this->name}!");
   return false;
 }

** ログファイルの監視ソフト [#id54164d]
-Windowsでログファイルを監視するには、Tailsというソフトが便利です。
http://www.vector.co.jp/soft/dl/winnt/util/se352598.html
※UTFにも対応しています。

** 関連ページ [#ydc9abc6]
#lsx

#newpage_subdir()

** コメント [#l0a3d34e]
#comment

    ホーム 一覧 単語検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS