log4phpでプロセスを終了しないとファイル名が変わらない件について


log4jのPHP移植版で、phpのloggerとして有名なlog4phpがあります。ログファイルの形式としても利用者が多いであろう日付形式のファイルでのログの記録。もちろん、log4phpでも利用可能です。その際に利用するAppenderがLoggerAppenderDailyFileになります。

このLoggerAppenderDailyFileですが、日付のフォーマット(デフォルトはYmd)を指定することができ、ログファイルにYmd.logなどの形式で記録することが出来ます。ただ、1つ注意する必要があり、ファイル名の決定が初期化時にしか行われないということで、バッチなど、1つのプロセスで日付をまたいで実行されるようなプログラムでは、常に同じファイルに書き込まれるということになります。

で、コレを解消するためには、Logger::resetConfigurationを実行し、再度Logger::configureメソッドを実行する必要があります。ただ、このLogger::resetConfigurationですが、1万回実行した結果、呼ばなかった場合と比べ、かなり遅くなりました。(一番下にベンチマークの結果を載せています)

そこで、LoggerAppenderRollingFileを参考にLoggerAppenderRollingDailyFileというのを作成しました。やっている事は簡単で、ログを書き出す前に現在書き込んでいるファイルの日付と現在日付を比較して異なっていれば書込対象のファイルを更新するというものです。

ただ、apacheなどのように標準のlogrotate機構が使えるようなプログラムについてはそちらで行ったほうが楽かつ安全かと思います。

一つの実装として下記のようなものを作成してみました。

広告

log4php/appenders/LoggerAppenderRollingDailyFile.php

< ?php
class LoggerAppenderRollingDailyFile extends LoggerAppenderDailyFile {
        protected $_logFilePath = false;
        protected $_nowDate = false;
 
        public function setFile() {
                $numargs = func_num_args();
                $args = func_get_args();
 
                if (!$this->_logFilePath && is_string($args[0])) {
                        $this->_logFilePath = $args[0];
                }
 
                if($numargs == 1 and is_string($args[0])) {
                        parent::setFile( $args[0] );
                } else if ($numargs == 2 and is_string($args[0]) and is_bool($args[1])) {
                        parent::setFile( $args[0], $args[1] );
                }
        }
 
        private function updateFile() {
                $_now = date($this->datePattern);
                if ($_now != $this->_nowDate) {
                        $this->_nowDate = $_now;
                        $this->setFile($this->_logFilePath);
                        $this->close();
                        $this->activateOptions();
                }
        }
 
        /**
         * @param LoggerLoggingEvent $event
         */
        public function append(LoggerLoggingEvent $event) {
                $this->updateFile();
                parent::append($event);
        }
}

log4php/Logger.php

新たに追加したAppenderを有効にするために、クラス一覧に追加します。

@@ -77,6 +77,7 @@
 		'LoggerAppenderMailEvent' => '/appenders/LoggerAppenderMailEvent.php',
 		'LoggerAppenderNull' => '/appenders/LoggerAppenderNull.php',
 		'LoggerAppenderPhp' => '/appenders/LoggerAppenderPhp.php',
+		'LoggerAppenderRollingDailyFile' => '/appenders/LoggerAppenderRollingDailyFile.php',
 		'LoggerAppenderRollingFile' => '/appenders/LoggerAppenderRollingFile.php',
 		'LoggerAppenderSocket' => '/appenders/LoggerAppenderSocket.php',
 		'LoggerAppenderSyslog' => '/appenders/LoggerAppenderSyslog.php',

これらを使い、再度ベンチマークを計測してみたところ、下記のようになりました。

グラフの詳細はこちらから。

関連記事