リダイレクトで追記されているファイルをログローテートする場合

ALL
スポンサーリンク
スポンサーリンク

問題と解決方法

リダイレクトで追記されているファイルのログローテートの注意点です。

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

コメント