こういうやつ。
たとえば
- ファイルポインタ開放忘れて
- クソでかいファイルが生まれてしまった!
- 被害拡大を防ぐため、 copytruncate と delaycompress の組み合わせでログファイルの肥大化を防ぐ
などした場合、それでよしよしとしておくと、翌日圧縮されて CPU 占有されてサービスが落ちる、などとなる。
例
これは Rails のログを logrotate にお任せする場合だけど、例としては以下のようになる。
/var/www/example/current/log/production.log { su ec2-user ec2-user create 644 ec2-user ec2-user daily missingok rotate 90 compress delaycompress dateext notifempty copytruncate }
前述のケースの通り、ローテートがうまくいってなくて、 100GB 近い production.log が生まれてしまった。
これをローテートされて production.log-20250415 などになった場合、ほっとくと delaycompress で圧縮されてしまう。 防ぐためにはログローテートのルールに引っかからないようにファイル名を加工すればよい、
mv production.log-2025-0415 evacuation-production.log-2025-0415
という感じ。 このあとは時間を見計らって gzip などで圧縮しておけばだいたい 1/15 でくらいになる。
実際に運用しているサービスでは以下のようになっている。
-rw-r--r--. 1 ec2-user ec2-user 1.8G Apr 15 20:01 production.log -rw-r--r--. 1 ec2-user ec2-user 330M Apr 11 00:00 production.log-20250411.gz -rw-r--r--. 1 ec2-user ec2-user 252M Apr 12 00:01 production.log-20250412.gz -rw-r--r--. 1 ec2-user ec2-user 248M Apr 13 00:01 production.log-20250413.gz -rw-r--r--. 1 ec2-user ec2-user 204M Apr 14 00:01 production.log-20250414.gz -rw-r--r--. 1 ec2-user ec2-user 2.8G Apr 15 00:01 production.log-20250415
copytruncate はログ欠損するとか色々副作用ある、みたいな話あるけど、プロセスにシグナル送るとか色々めんどうなこと考えなくて良いのでこうしている。
copytruncate でやる場合の注意
ちょっと掲題とはずれるけど注意。
copytruncate は元となるファイルのコピーを作成しきってから、元ファイルの内容を空にする。 なので、前述のケースの場合、 100GB の production.log が存在しているのであれば、 production.log-20250415 という 100GB のファイルが完成してから元ファイルを空にする。
つまり一時的にローテート対象のファイルの二倍の容量が必要になる。
これギリギリで気づいて「オアーッ!! ディスク枯渇する〜!」 と Slack で騒いだりしていた。 みんなも圧縮なりもそうだけど、このあたり注意してくれよな!