logrotate の delaycompress

何かのスクリプトで作成した定期バッチのログを logrotate でローテートするようにした場合、バッチが午前4時に起動して10分間実行されると実行中にログローテートされることになります。

バッチスクリプトでログファイルを開きっぱなしにしている場合、ローテートでログファイル名が「hoge.log → hoge.log.1」のように変更されたとしてもinode番号が変わらないのでローテート後の「hoge.log.1」に書き込みが継続します。
ですが logrotate で compress を指定していると、ローテート時にログが圧縮されて元のログファイルは削除されるため、バッチスクリプトでログを開きっぱなしにしているとローテートのタイミングでログの書き込み先を見失って、ローテートの時間以降に発生したログが記録されなくなります。

これを解決するため(にあるわけでは無いと思いますが)、logrotate で delaycompress を設定すると、下記のような感じにローテートの1世代目は圧縮されずにそのままになります。

hoge.log
hoge.log.1
hoge.log.2.gz
hoge.log.3.gz
 :

この場合、ローテートが実行されたときに「hoge.log」を開きっぱなしにしているプロセスがあったとしてもログの書き込みは「hoge.log.1」に継続するため、ログ出力が損なわれることはありません。


logrotate の設定は以下のような感じ。

/path/to/logfile {
	missingok
	daily
	rotate 10
	ifempty
	compress
	delaycompress
}