logrotateでログをローテーションする

linux

logrusがローテーションする仕組みを持っていなかったので、 READMEに書いてあったlogrotateを使う。/etc/logrotate.dの中に設定ファイルを入れて、cronで回して使う。

FROM ubuntu:14.04

ADD logrotate /etc/logrotate.d/app
RUN echo "/usr/sbin/logrotate /etc/logrotate.conf" > /etc/cron.daily/logrotate

設定ファイルはこんな感じ。

/var/log/*.log {
  daily
  rotate 4
  missingok
  delaycompress
  dateext
  copytruncate
  sharedscripts
  postrotate
      echo "hi"
  endscript
}

daily で1日に1回、rotate 4 で過去4日分残し、 missingok でファイルがなくてもエラーにせず、delaycompress で圧縮するのをローテーションした次の回にして、 dateext でローテーションしたファイルの末尾を数字ではなく日付にする。 postrotate はローテーション後に実行されるスクリプトで、sharedscripts によって各ログごとではなくまとめて一回実行される。

copytruncate は rotate 時にファイルの中身を消して再利用することで inode が変わらないようにする。 これによりアプリケーション側が rotate 前のファイルに書き込み続けることを回避できるが中身を消す際に一部のログが欠損することがある。 代替案としては postrotate で SIGHUP などを飛ばしてアプリケーション側でファイルを開き直すといったものがある。

logrotate を実行すると、/var/lib/logrotate/status に過去に見た時間が入る。

$ echo "aaaaa" > /var/log/app.log
$ logrotate /etc/logrotate.conf
$ cat /var/lib/logrotate/status
logrotate state -- version 2
...
"/var/log/app.log" 2016-11-9-11:0:0
...

強制的にローテーションさせてみる。

$ echo "aaaa" > /var/log/app.log
$ logrotate -f /etc/logrotate.conf
$ ls /var/log | grep app
app.log
app.log-20161109

$ cat /var/log/app.log-20161109
aaaaa