CentOSのnginxをいじっていてログファイルの名前を変えたらローテートされていないことに気づきました。CentOSのログのローテートのイメージです。
初め
access.log
error.log
↓
翌日
access.log
access.log-20210102
error.log
error.log-20210102
↓
翌々日
access.log
access.log-20210102.gz
access.log-20210103
error.log
error.log-20210102.gz
error.log-20210103
dailyでローテートするようにしているのですが翌日に確認するとローテートされていません。。logrotateのコンフィグファイルの設定です。
/var/log/nginx/*.log {
daily
missingok
rotate 5
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
error.logがもともとあったファイルでdumy_access.logとdumy_error.logが新しく作成されたログファイルです。以下に今回起きた状況を書くと、、
初め
dumy_access.log
dumy_error.log
error.log
error.log-20210103
↓
翌日
dumy_access.log
dumy_error.log
error.log
error.log-20210103.gz
error.log-20210104
error.logはちゃんとローテートされているのですが、新規ログファイルのdumy_access.logとdumy_error.logがローテートされていないです。dumy_access.logとdumy_error.logがログファイルとして認識されていないんじゃないか?と思い調べてみたところ、原因は別にありました。
logrotateはcronでlogrotateコマンドを実行しているので /etc/cron.daily 配下のlogrotateシェルを見てみます。
#!/bin/sh
/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0
logrotateコマンドのパラメータにlogrotate.statusファイルとlogrotate.confファイルを与えています。このうち、logrotate.statusには前回ログローテートを行った時刻を記載しているとのこと。logrotate.statusを見てみました。
# grep nginx /var/lib/logrotate/logrotate.status "/var/log/nginx/error.log" 2021-1-4-3:44:1 "/var/log/nginx/dumy_error.log" 2021-1-4-3:0:0 "/var/log/nginx/dumy_access.log" 2021-1-4-3:0:0
dumy_error.logとdumy_access.logの記載があるのでログファイルとしては認識してるようです。ではなぜローテートされなかったかというと、新規ログファイルの場合はlogrotate.statusに何も記載がないわけで、初回処理時に新規ログファイルの情報をlogrotate.statusに書き込むようです。初回の処理としてはそれで終わりです。次回(翌日)のlogrotateが動くときにlogrotate.statusに記載のある時刻を元に1日後(daily)、1週間後(weekly)、1ヶ月後(monthly)のローテートを行うようです。なので、明日、もう一度ローテートがされているか確認することにしました。
で、、翌日。。
ちゃんとローテートされてました。こんな感じです。
dumy_access.log
dumy_access.log-20210105
dumy_error.log
dumy_error.log-20210105
error.log
error.log-20210103.gz
error.log-20210104.gz
error.log-20210105
logrotate.statusも更新されていました。ということで、logrotateは初日はローテートをしないということを知りました。
ちなみにですが、logrotateのコンフィグファイルでdaily指定しているものが毎日ローテートされているか見てみると、そうでないものがありました。これはログファイルがゼロバイトのためのようです。ゼロバイトのログファイルもローテート対象にするにはコンフィグファイルにifemptyの指定をすればローテート対象になるようです。
なお、ubuntuの場合はlogrotate.statusではなくstatusという名前のファイルです。参考までにubuntuのlogrotateシェルを載せておきます。
#!/bin/sh
# Clean non existent log file entries from status file
cd /var/lib/logrotate
test -e status || touch status
head -1 status > status.clean
sed 's/"//g' status | while read logfile date
do
[ -e "$logfile" ] && echo "\"$logfile\" $date"
done >> status.clean
mv status.clean status
test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate /etc/logrotate.conf
CentOSとはちょっと違うのですね。。
