問題と解決方法
リダイレクトで追記されているファイルのログローテートの注意点です。
logrotateの設定で copytruncate を指定しますが、リダイレクトの仕方によっては、ローテート実施後でもファイルサイズはそのままで、ファイルの内容が0で埋められたものになります。
その後、そのファイルへ追記されていくことになります。
この問題が起きないようにするには、次のようにリダイレクトで >> を使用してください。
program >> test.log
詳細
次のように、programの出力をリダイレクトで追記されているファイル test.log があり、test.logをログローテートしたいとします。
program > test.log
その場合、logrotateの設定で、copytruncate を指定します。copytruncate 指定によって、ログローテート時にファイルtest.logのコピーが作成された後、元のファイル test.logは空になります。
/var/log/test.log {
missingok
notifempty
copytruncate
}
ここで、ログローテート後の test.log へ、program > test.log のリダイレクトによる出力がされたとします。
test.log の内容を less で確認しようとすると、バイナリファイルとして次のような表示になります。
$ less /var/log/test.log
"/var/log/test.log" may be a binary file. See it anyway?
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@
この時、test.log のサイズはローテート前のサイズ+追記されたサイズとなっていて、その内容は追記部分より前は0バイトの値で埋められています。
これは、下記のようにリダイレクトで追記されているファイルなのに、ログローテート後の元のファイル test.log への追記位置が先頭にリセットされないためです。
program > test.log
ログローテート後にファイルへの書き出し位置が先頭になるようにするには、リダイレクトで > ではなく、>> を使用します。
program >> test.log
参考
logrotateでcopytruncateしてもサイズが大きいまま – K blog
【日本語man】logrotateの全オプション解説 – Hacker’s High
コメント