Linuxのlogrotateを設定して,Apacheのログファイルを定期的に切り替える
logrotateの設定
Apacheのログはほっとくとサイズが膨張する一方なので,
適当なタイミングで別のファイルに切り替えるのがよろし.
うちのLinux(Red Hat 7.1J)では,システム標準でcronによってlogrotateが定期的に動くようになっていたので,
こいつで一緒にやってもらうことにします.
logrotateは,特に設定しなければ
- access_log.1
- access_log.2
- ・・・
という具合で,あとで困ってしまうようなファイル名をつけてしまうため,少し工夫を行って,
- access_log.20030419
- access_log.20030426
- ・・・
という風になるようにしています.(1週間に1回ローテイトさせます.いわゆるweeklyですな)
設定内容
/etc/logrotate.d/mylogrotate
/usr/local/apache2/logs/access_log {
weekly
copytruncate
postrotate
EXT=`date +%Y%m%d`
for f in $1;
do mv $f.1 $f.$EXT;
done
endscript
}
/usr/local/apache2/logs/error_log {
weekly
copytruncate
postrotate
EXT=`date +%Y%m%d`
for f in $1;
do mv $f.1 $f.$EXT;
done
endscript
}
- weekly
- 1週間に1回ローテーションする
- copytruncate
- 対象ファイルの複製を作成して対象ファイルの内容をクリアする,という方法でローテーションする.この方法はログを出力しているプロセス(Apache)を再起動しなくても済むが,後で書いているようにロストが生じる可能性という欠点がある
- postrotate〜endscript
- ローテーションの後にこの範囲内のスクリプトを実行する
ファイル名のmylogrotateに特に意味はない.
/etc/logrotate.d/ 配下に作ってさえいれば,どんな名前でもok.
では,なぜ /etc/logrotate.d/ 配下に作ればよいのか?となると,少し話はややこしい.
面倒なので書きませんが,cronの設定(/etc/crontab)から始まって,芋づる式にファイルをたどって,
- /etc/crontab
- /etc/cron.daily/
- /etc/cron.daily/logrotate
- /etc/logrotate.conf
- /etc/logrotate.d/
という具合で,最終的にたどり着いたのでした.
copytruncate方式の欠点
今回の方式ではcopytruncateを使っているため,ローテーション時には
- 元ファイルのコピーを作り
- 元ファイルの内容をクリアする
という動作によってローテーションを実現している.
なので,ログを出力しているプロセス(Apache)から見れば永遠に同じファイルに出力し続ければよいため,Apacheにファイルの切り替えを認識させるために再起動をかける必要もない.
しかし見てわかるように,1.と2.の間のわずかな時間に発生したログは,
ということになってしまい,結果として消滅してしまう.これがcopytruncate方式の欠点.
もしこのようなロストが許されない場合はcopytruncate方式は使えないので,
- copytruncateを使わずに,かつpostrotateでApacheの再起動を行う
- Apacheでログをパイプに出力するように設定して,パイプの内容をrotatelogs,cronologなどでファイルに仕分けする
などの方法を採る必要があります.
カモランドではそこまで気にしていないので,この方式で運用しています.
logrotateの動作確認時の注意
あと,このファイルを作るためにかなりの試行錯誤を行ったんですが,
logrotateを1日に何回も実行するには,結構面倒な手順が必要でした.
(要は,ハマったということ)
/var/lib/logrotate.status に,ローテイト対象ファイルごとに,前回実行日時が記録されている.
例)
"/var/log/messages" 2003-4-20
このファイルに該当行が存在しない場合,
まず初回logrotate実行時に該当行がその当日日付で作成され(このときローテイトは実行されない!),
2回目から実際のローテイト処理が行われる.
なので,logrotateの設定を試行錯誤するためには,
- /var/lib/logrotate.status を編集して,昨日の日付に変更する
- /etc/crontab を編集して,少し後の時間に /etc/cron.daily が実行されるようにする
- service crond restart
という手順を繰り返すことになる.
1.がポイントで,行を削除してしまうと駄目.行は存在するけど昨日の日付になっている,という状態にすべし.
他に,もっと簡単な方法があるのかも知れませんが...