スポンサード リンク
Top > PHP > CakePHP > CakePHPのログをLog4phpに切り替える
スポンサード リンク

Tag: CakePHP

CakePHPのログをLog4phpに切り替える Edit

ロギング処理をLog4JのPHP版であるLog4phpに切り替えます。
CakePHPのログはファイルに出力する単純な機能しかないので、ローテーションの設定などが本番運用時に必要と思われるので、Log4phpを導入することにします。

Log4phpのインストール Edit

  • Do You PHP? - log4php - PHP版log4j
    を参考にしました。
  • log4php - log4j ported to PHP! - Download Page
    から最新のlog4php-0.9.zipをダウンロードします。
  • 展開したファイル一式を下記のフォルダにコピーします。
    log4php-0.9\src\log4php

    cake/libs/log4php
    vendors/log4php
    にコピーする。
    ※cakeフォルダではなく、vendorsフォルダに入れるほうがよさそうなので、そちらにしました。

CakePHP標準のロギング処理を修正 Edit

  • 下記のファイルにロギング処理が書かれているので修正します。
    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($output);
              break;
            case 'error':
              $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);
      }
      
    }
    ?>
    ※log4phpの本体をvendorsフォルダに移動したため、そこからインクルードするようにした。
    ※log4phpのLoggerをシャットダウンしないといけないようなので、デストラクタを作って対応した。
    ※セッションIDもログメッセージに付加するようにした。

Log4phpのエラー対策 Edit

  • そのままだと、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クラスとログ出力について
  • 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);

アプリケーション毎の設定 Edit

グローバル定数 Edit

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

Log4phpの設定 Edit

  • 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つまで残る設定です。

ログの出力方法 Edit

  • 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でファイルに出力する Edit

  • 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の異常が発生した場合に、ログファイルで確認できるようになります。

通常のロギング処理でのエラー対策 Edit

  • log4phpを使わない場合のロギングでエラーになります。
    Webプログラミングに関するメモ: CakePHPの$this->log()、php4.4.4でエラー
    に書かれていました。
  • 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;
    }

ログファイルの監視ソフト Edit

関連ページ Edit

ページ新規作成:

コメント Edit


URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

スポンサード リンク

リロード   新規 編集 凍結 差分 添付 複製 名前変更   ホーム 一覧 単語検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: 2007-02-08 (木) 17:27:56 (4208d)