logrotate はログファイルをローテーション、圧縮、および古いログファイルを削除するためのもので、ほとんどの Linux ディストリビューションにはデフォルトでインストールされており、自動的に毎日実行されます。
logrotate の設定ファイル#
/etc/logrotate.d/app
というファイルを作成して編集します。通常、/etc/logrotate.conf
にはinclude /etc/logrotate.d
という設定があり、これにより/etc/logrotate.d
ディレクトリの設定ファイルが自動的に読み込まれます。
/root/app/log/app.log {
daily # 毎日ローテーション
missingok # ログファイルが存在しなくてもエラーを表示しない
rotate 100 # 100個のログファイルを保持
compress # 古いログファイルを圧縮する
delaycompress # 次のローテーションまで圧縮を遅延する
notifempty # ログファイルが空でない場合にのみローテーションする
dateext # 現在の日付をログファイルの拡張子として使用する
dateformat -%Y%m%d # 日付の形式を設定する
olddir /root/app/log/old # 古いログファイルの保存ディレクトリを設定する。このディレクトリは事前に作成しておく必要があります
sharedscripts # スクリプトはすべてのログのローテーション後に一度だけ実行されます
postrotate # ローテーション後に実行されるスクリプト
/usr/bin/docker restart app
endscript # スクリプトの終了
}
注意: サービスを再起動すると、ネットワークが切断される可能性がありますので、注意が必要です。次のような方法でテストを行うことができます。再起動のプロセス中にネットワークが切断されるかどうかをテストします。
for i in {1..1000}; do { curl -I https://example.com/; sleep 0.3; } ; done
テスト#
ここでは、logrotate コマンドを直接使用してテストします。-d はデバッグモードを表し、-f は強制実行を表し、-v は詳細モードを表します。実際の実行はデバッグモードではなく、実行のプロセスが表示されます。デバッグモードはテストに使用できます。
logrotate -dfv /etc/logrotate.d/app
デバッグモードを解除した後の結果は次のようになります。
$ tree
.
├── app.log
└── old
├── app.log-20231116.gz
└── app.log-old
1 directory, 3 files
問題が残っている可能性#
- 権限: 私は現在 root ユーザーを使用しているため、権限の問題には遭遇していませんが、他のユーザーの場合は権限の問題が発生する可能性がありますので、注意が必要です。
- 再起動: postrotate のスクリプトはログのローテーション後に実行されるため、サービスの再起動の場合、ネットワークが切断される可能性がありますので、注意が必要です。
- ファイルサイズに基づくローテーション: ファイルサイズに基づいてローテーションする場合、ログファイルが切り詰められる可能性がありますので、注意が必要です。私はこの問題に遭遇していないため、ファイルサイズに基づいてローテーションしていません。
参考資料#
- Linux ログローテーションツール logrotate の原理と設定の詳細 - logrotate の原理について詳しく説明されている素晴らしい記事です。
- logrotate(8) - Linux man page - logrotate の公式ドキュメントで、logrotate の詳細な設定を確認するために使用できます。