sfLogManager が rotate してくれない

log-rotate でローテーションしてくれない問題。

symfony で log-rotate を使うと、いい感じにログをさばいてくれて便利、という話。
なのだが、不具合発見。

history が満タンになったら、以降のログが履歴に残らないことがある。

history を 10 にしておいたら、10ファイルまでの履歴は正常に取れる。
が11コめ以降のファイルが全く履歴に残らない。

かなりふる~いファイルばっかり履歴に残っていて、必要な最近のログが残らない、という現象が起こる。

調べてみると原因は sfLogManager の rotate に欠陥が。

102行目からのココが問題。

// get all log history files for this application and environment
$new_logs = sfFinder::type('file')->ignore_version_control()->maxdepth(1)->name($logfile.'_*.log')->in($logdir.'/history/');

// if the number of logs in history exceeds history then remove the oldest log
if (count($new_logs) > $history)
{
  unlink($new_logs[0]);
}

sfFinder が返す配列が必ずしもソートされていない。
ウチの環境だと、作ったばかりの新しいログが先頭に来ていた。
なので、すぐに unlink されて新しいログが残らない、という楽しげな振舞いに。

対策は、ソートしてやればオッケーなので、こんな感じに。

// get all log history files for this application and environment
$new_logs = sfFinder::type('file')->ignore_version_control()->maxdepth(1)->name($logfile.'_*.log')->in($logdir.'/history/');
sort($new_logs);

// if the number of logs in history exceeds history then remove the oldest log
while (count($new_logs) > $history)
{
  unlink(array_shift($new_logs));
}

これを myLogManager.class.php にして lib フォルダに保存。

しかしながら、これだけだと log-rotate でダメバージョンが使われてしまう。
なので、アクション経由でこれを呼ぶことにする。

function executeLogRotate()
{
  myLogManager::rotate('frontend', 'prod', 1, 10, true);
  myLogManager::rotate('backend', 'prod', 1, 10, true);
  return $this->renderText('1');
}

こんな感じ。

さらに、自分自身のアプリ&環境でログを rotate しようとしたら、うまくいかない。
自分自身のログを削除できない。
なので、このアクションを呼ぶのは dev 環境にする。

これで、一応、ローテーションはうまくいくが、このままだと dev 環境のログの成長が止まらない。
それは、今後の課題、ということで。

symfony のバージョンは 1.0.11。

2012年11月

        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  

アーカイブ