プログラムの中のどこからでもカスタムログを作成できるようにしたのは前回の話。今回はそのログを例えば3ヶ月ごとにローテーションしてみます。

前回のカスタムログの関数はこちらです。

ローテーションの目的

ログのファイルをローテーションする目的は、いくつかあります。1つのファイルにログを保存していると、ファイルが大きくなるのでオープンするのに時間がかかる、また、ファイルが大きくなるとディスクスペースも取られ、最悪はディスク使用率が100%となるかもしれません。ということで、ファイル名に年月を入れて必要な月数だけのファイルをキープするのがログローテーションです。

具体的な例として、現在ディレクトリに以下のようなログファイルがあるとします。

custom-2023-04.log
custom-2023-05.log
custom-2023-06.log

7/1になりログが保存されると、

custom-2023-05.log
custom-2023-06.log
custom-2023-07.log

4月のファイルが削除されて7月のファイルが作成されます。つまりいつも3ヶ月分のログファイルが存在します。

ローテーションするには

Laravelはログの管理には、phpではとても有名なMonologのパッケージを使っています。Monologはとてもフレキシブルに出来ていていろいろなカスタム化が可能です。今回はMonologのログローテーションのハンドラーを使い、月次のローテーションを設定します。

まず、RotatingFileHandlerのクラスを継承して、ファイルフォーマットの設定を、デフォルトの日次FILE_PER_DAYから、月次のFILE_PER_MONTHに設定します。


namespace App\Logging;

use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;

class MonthlyRotatingHandler extends RotatingFileHandler
{
    /**
     * @param  string  $filename  ログファイル名
     * @param  int  $maxFiles       最高のローテーション数(0ならローテーションなし)
     * @param  string|int  $level   これがコールされる最低のログレベル(デフォルトはDEBUG)
     * @param  bool  $bubble        stackチャンネルが可能か(デフォルトはtrue)
     * @param  int|null  $filePermission ファイルの許可(デフォルトは0644)
     * @param  bool  $useLocking     書き込み中にログファイルをロックするか(デフォルトはfalse)
     */
    public function __construct(string $filename, int $maxFiles = 0, $level = Logger::DEBUG, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false)
    {
        parent::__construct($filename, $maxFiles, $level, $bubble, $filePermission, $useLocking);

        $this->setFilenameFormat('{filename}-{date}', static::FILE_PER_MONTH); // デフォルトの'Y-m-d'から'Y-m'に変える
    }
}

簡単ですね。ちなみに、年次としたいなら、FILE_PER_YEARとしてください。

次に、このハンドラーを使い、前回作成したヘルパーを編集します。

use Illuminate\Support\Facades\Log;

if (! function_exists('custom_log')) {
    function custom_log($prefix, $message)
    {
        Log::build([
            'driver'     => 'monolog',
            'handler'    => App\Logging\MonthlyRotatingHandler::class,
            'with'       => [
                'filename'       => storage_path('logs/'.$prefix.'.log'),
                'filePermission' => 0666, //すべてで読み書き可能とする
                'maxFiles'       => 3, // 3ヶ月でローテーション
            ],
        ])->info($message);
    }
}

これだけです。早速テストしてみると、storage/logsには以下のようにファイルが作成されました。

$ ls -l
-rw-rw-rw- 1 kenji kenji 114 Jun 14 14:20 custom-2023-06.log
-rw-rw-rw- 1 kenji kenji   0 Jun 14 14:19 laravel.log

また、上のfilePermissionで指定したように、ファイルのパーミッションは0666となっています。

By khino