【PHP】ログローテート対応のログ出力関数を実装する
PHPではerror_logやsyslog等の汎用ログ出力関数が用意されており、
logrotate等と組み合わせることでログローテートを実現可能ですが、
ここでは自前でログローテート対応のログ出力関数を実装してみます。
処理の概要は下記のように非常にシンプルなもの。
・指定のログ出力先にログを出力
・ログが指定容量を超えたらローテートする(日付ではローテートしない)
・管理する世代数を超えたログは削除する
ソースはこのような感じ。
const LOG_DIRECTORY = '/var/log/logdir/'; // ログディレクトリ const LOG_FILENAME = 'logfname.log'; // ログファイル名 const LOG_FILEPATH = LOG_DIRECTORY.LOG_FILENAME; // ログのファイルパス const MAX_LOTATES = 3; // ログファイルを残す世代数 const MAX_LOGSIZE = 1024*1024; // 1ファイルの最大ログサイズ(バイト) function WriteLog($strlog){ // 保存先ディレクトリを作成 if(!file_exists(LOG_DIRECTORY)){ mkdir(LOG_DIRECTORY); } // ログのローテート if(@filesize(LOG_FILEPATH) > MAX_LOGSIZE){ // 最古のログを削除 @unlink(LOG_FILEPATH.strval(MAX_LOTATES)); // ログをリネーム .log → .log_01 for ($i = MAX_LOTATES - 1; $i >= 0; $i--) { $bufilename = ($i == 0) ? LOG_FILEPATH : LOG_FILEPATH.strval($i); @rename($bufilename, LOG_FILEPATH.strval($i+1)); } } // ログ出力 file_put_contents(LOG_FILEPATH, date('y-m/d-H:i:s ').$strlog."\n", FILE_APPEND | LOCK_EX); }
※ローテート処理で関数名の頭に@が付いている箇所がありますが、
ローテート対象ファイルがない場合に表示されるWarningを抑制するためです。
詳しくは、PHPリファレンスのエラー制御演算子を参照
この関数を呼び出すと、次のようにログ出力されます
WriteLog("ログの出力てすと");
$ cat login.log 18-02/24-16:26:57 ログの出力てすと
上記ソースでは各ファイルの最大サイズが1MiB、残すログは3世代分に設定されているため、logfname.logの容量が1MiBを越えるとログがローテートされます
logfname.log → logfname.log_1 → logfname.log_2 → logfname.log_3 → 削除
(拡張子に世代数を記載しない方が望ましいですが)