ログローテーション — 古いページを破り捨てる、自動の日記帳
サーバーのアプリは、動いているあいだずっとログ(何が起きたかの記録)をファイルに書き続けます。放っておけばファイルは大きくなり続け、いつかディスクを使い切ります。そうなると、ログどころかアプリの保存処理まで失敗し、サービスが止まります。
これを防ぐのがログローテーションです。たとえるなら古いページを自動で破り捨てる日記帳。決まったタイミングで新しい冊に切り替え、古い冊は圧縮して棚に並べ、決めた冊数を超えたら一番古い冊を捨てる。図1で、切り替えのタイミング・残す冊数・圧縮を変えながら、ディスクのメーターを見てください。
「毎日」か「サイズ」か — 区切り方で守れるものが違う
ローテーションを「しない」のままだと、6日ほどでディスクが満杯になります。「毎日」に切り替えても、7冊を圧縮せずに残すと、2GB×7冊でやはり入りきりません。ディスクに置かれるログの量は、おおよそ1冊の大きさ×残す冊数で決まるからです。圧縮をオンにすると、古い冊が1/10に縮み、使用量が一定のところで落ち着きます。
次に「📈 アクセス急増」を押してみてください。「毎日」は時間でしか区切らないので、1日のログが6倍になると、切り替える前に1冊がディスクを埋めてしまいます。「2GBごと」なら1冊の大きさに上限があるので、急増しても溢れません。そのかわり冊が4時間で埋まるので、7冊残してもさかのぼれる期間は1日ほどに縮みます。実際の運用では「毎日、ただし一定サイズを超えたらその時点でも」のように、両方を組み合わせることがよくあります。
名前を変えても、ペンは同じノートに書き続ける
ローテーションには、もう1つ有名な落とし穴があります。切り替えは「app.log の名前を app.log.1 に変えて、新しい app.log を作る」ことで行います。ところがアプリは、起動時に開いたファイルを名前ではなく、ノートそのものとして握っているのです。図2で、1手ずつ確かめてください。
合図を送り忘れると、アプリはapp.log.1 に書き続けます。新しい app.log は空のまま、やがて app.log.1 が圧縮されたり捨てられたりすると、ログは行方不明になります。しかも開いたまま削除されたファイルは、ディスクの空きが戻りません。ノートを棚から捨てても、アプリがペンで握っている限り、中身は残り続けるからです。「消したのにディスクが空かない」ときは、まずこれを疑います。
- ログローテーション
- ログファイルを一定のタイミングで切り替え、古いものを圧縮・削除して、ディスクの使用量に上限をつくる仕組み。
- 世代(rotate)
- 残しておく古いファイルの数。app.log.1、app.log.2 … と番号が古さを表す。
- logrotate
- Linuxでよく使われる、ログローテーションを自動で行うツール。設定ファイルに頻度・世代数・圧縮などを書く。
- ファイルディスクリプタ
- アプリがファイルを開いたときに受け取る「開いたファイル」への札。名前が変わっても同じファイルを指し続ける。
- copytruncate
- 中身をコピーしてから元のファイルを空にする切り替え方。アプリに合図を送れないときに使うが、その間に書かれた行が消えることがある。
まとめ
ログは書いた分だけ増えるので、自動で切り替えて、古いものから捨てる仕組みが欠かせません。ディスクに置かれる量は1冊の大きさ×残す冊数で決まり、圧縮で縮め、サイズでも区切れば急増にも耐えられます。そして切り替えたら、アプリに新しいノートへペンを持ち替えさせるところまでがローテーションです。