Xserverのエラーログを別の場所に日ごとファイルを分けて保存する

Xserverの仕様で、エラーログは毎朝3時にクリアされてしまうので、毎日チェックしていないとエラーを見逃してしまう可能性があります。

でも、実際に毎日チェックするのは厳しい。

ということで、エラーログを別の場所に書き出し、そのファイルを日ごとにリネームすることで、一週間に一回程度のチェックで済むように設定してみます。

ログを切り替える処理

まずは、ログファイルを切り換える処理から。logrotate.phpというファイル名で、以下の処理を記述します。

<?php
$log_file = '/home/[ユーザーID]/[ドメイン名]/log/php_error.log';
$today = date( 'Ymd' );
if( file_exists( $log_file ) ){
    rename( $log_file, $log_file.'.'.$today );
}

次に、logrotate.phpを以下の場所にFTP等で転送します。

/home/[ユーザーID]/[ドメイン名]/log/

Xserverのサーバパネルにログインし、Cron設定画面で、毎日0時5分に、上記PHPを実行する処理を追加します。0時0分でもいいのですが、念のため5分の余裕を取っておきます。

Cron設定画面

設定項目は上から順に、
分 :5
時間:0
日 :*
月 :*
曜日:*
コマンド:/usr/bin/php8.1 [ドメイン名]/log/logrotate.php
コメント:エラーログファイル切替

最後に、php.iniにエラーログ出力先の設定をします。

php.iniの設定

エラー関係の設定が記述されている7行目あたりに、以下を追記します。

error_log = /home/[ユーザーID]/[ドメイン名]/log/php_error.log

以上でエラーログの出力先が変更され、毎日エラーログに年月日のサフィックスをつけて保管されます。

古いログを自動削除する処理

ただし、このままではエラーログが溜まり続けてしまうので、定期的に古いログファイルを手動で削除する必要があります。

それが面倒なら、例えば15日以上経過したエラーログファイルを削除するような仕組みをlogrotate.phpに追加してもよさそうです。

foreach( glob( $log_file.'.*' ) as $i => $file ){
    if( filemtime( $file ) < time() - ( 15 * 24 * 60 * 60 ) ){
        unlink( $file );
    }
}

こんな感じの処理を、ログをリネームした後あたりに入れれば良いでしょうか。

最終的なlogrotate.phpは、こんな感じ。

<?php
$log_file = '/home/[ユーザーID]/[ドメイン名]/log/php_error.log';
$today = date( 'Ymd' );
if( file_exists( $log_file ) ){
    rename( $log_file, $log_file.'.'.$today );
}
foreach( glob( $log_file.'.*' ) as $i => $file ){
    if( filemtime( $file ) < time() - ( 15 * 24 * 60 * 60 ) ){
        unlink( $file );
    }
}

ユーザーIDとドメイン名は、環境に合わせて設定してくださいね。

さいごに

ということで、Xserverのエラーログを自前の処理で日次保存できるようにしてみました。

今までは、毎日できるだけ遅い時間にエラーログをダウンロードする、という作業が必要でしたが、これで慌てずにタイミングの良いところでエラー確認できるようになりました。

とは言え、エラーは早期発見に越したことはないので、なるべくこまめに確認するか、ファイルサイズに変化があったらアラートが上がるような仕組みを作った方が良いのかもしれません。

さて、一応注意書きですが、上記処理は今回実装した環境では正常に動いている(ように見える)ものの、全ての環境で正常に動く保証はありません。もし上記処理をそのまま使用する場合は、いきなり本番環境で設定せず、必ずテスト環境で十分にテストしてから本番環境に入れるようにしてください。

何か不具合が発生したとしても、自己責任でお願いします。

初稿:2022年8月24日