読者です 読者をやめる 読者になる 読者になる

site.logのローテーションでPHPのWarningが出ている件

eccube

たまーにこんな感じででる。

Warning: copy(/path/to/eccube/data/logs/site.log.3) 
[function.copy]: failed to open stream: そのようなファイルやディレクトリはありません 
in /path/to/eccube/data/class/util/GC_Utils.php on line 200

ファイルのコピーに失敗してる。
Warningが画面に出なくするようにしたらおしまいなんだけど、ちょっとみてみた。

アプリケーションログのローテーションの時にファイルコピーに失敗してるっぽい。

アプリケーションログのローテーションをやってる箇所

/path/to/eccube/data/class/util/GC_Utils.php

GC_Utils::gfLogRotation()
でやってる。

原因

ログディレクトリからローテーション対象となるログファイル名の配列を

array(3) {
  [0]=>
  string(10) "site.log.1"
  [1]=>
  string(10) "site.log.3"
  [2]=>
  string(10) "site.log.2"
}

んなかんじで持ってきてるんだけど、ロジック的には
配列の後ろから順に、1から始まる配列順+1したファイルが存在すればunlinkしてからコピー
というようになってる。

上記配列の場合、

  1. まず、配列の一番最後のsite.log.2(配列順は3)のところで、site.log.4があればsite.log.4を削除。site.log.2をsite.log.4としてコピー。
  2. 配列の後ろから2番目のsite.log.3(配列順は2)のところで、site.log.3があればsite.log.3を削除。site.log.3をsite.log.4としてコピーしようとした時には既にsite.log.3がないからWarning!

ちょこっと修正。

ローテーション対象となるログファイル名の配列を、

array(3) {
  [0]=>
  string(10) "site.log.1"
  [1]=>
  string(10) "site.log.2"
  [2]=>
  string(10) "site.log.3"
}

の順でとれるようにしてあげればよいんだけど、すっきり書くためにglobを使ってみた。
/path/to/eccube/data/class/util/GC_Utils.php
177行目あたり

<?
/*
            if ($dh = opendir($dirname)) {
                while (($file = readdir($dh)) !== false) {
                    // ログローテーションにて作成されたファイルを取得
                    if(ereg("^". $basename . "\." , $file)) {
                        $arrLog[] = $file;
                    }       
                }
*/
            $pattern = $path . '\.*';
            $arrLog = glob( $pattern );

            if ($arrLog !== false) {
?>

同ファイル190行目あたり

<?
//                         unlink($dirname. "/" .array_pop($arrLog));
                        unlink( array_pop( $arrLog ) );
?>


同ファイル200行目あたり

<?
//                    copy("$dirname/" . $arrLog[$i - 1], "$path.$move_number");
                    copy( $arrLog[$i - 1], "$path.$move_number" );
?>

これでオッケー。