「なんとなく」の設定が、半年後に悲劇を生む。
こんにちは!「LINUX工房」管理人の「リナックス先生」です。
前回は、logrotateが動く基本的な仕組みと、最初の設定ファイルの作り方を学びました。
しかし、実際の運用現場では「毎日回す」だけでは対応できないケースが多々あります。
「アクセスが急増して1日でログが10GBを超えてしまった!」「監査のためにログをファイル名で日付管理したい」「3年前のログが必要になったが消えていた…」
こうしたトラブルは、設定ファイルの書き方一つで防げるものです。
先生、質問です!
上司から「ログは100MBを超えないように分割して、かつファイル名を見ればいつのか分かるようにして、最低1年は保存しろ」って言われたんです。
これって daily とか rotate だけでできるんですか?
なんか計算が合わない気がして…。
いい質問ね。
標準的な daily 設定だと、1日1回しかチャンスがないから、突発的なログ増大には対応できないわ。
でも、logrotateには「サイズ指定」や「日付付与(dateext)」といった強力なオプションがあるの。
これらを組み合わせれば、どんなワガママな要件も満たせる「完璧な設定ファイル」が作れるわよ!
本記事では、AlmaLinux 9 をベースに、logrotateの設定オプション(ディレクティブ)を深掘りし、期間・サイズ・保存世代数を自在に操るテクニックを解説します。
🔄 logrotate完全攻略講座(バックナンバー)
現在地:【第2回】設定ファイルの魔術書!ローテーション周期・サイズ・保存期間の完全制御
- 【第1回】サーバーの「時限爆弾」を解除せよ!ログローテーションの基礎と仕組み完全図解
- 【第2回】設定ファイルの魔術書!ローテーション周期・サイズ・保存期間の完全制御
- 【第3回】「ログが消えた!?」を防ぐ。copytruncateとcreateの決定的な違いとiノードの秘密
- 【第4回】ディスク容量を極限まで節約!圧縮設定と日付付与のテクニック
- 【第5回】再起動を自動化せよ!postrotateスクリプトによるプロセス制御
- 【第6回】権限トラブルを回避する!ユーザー指定とACL、出力先ディレクトリの管理
- 【第7回】動かない時の処方箋。デバッグモード活用とSELinux/ステータスファイルの罠
- 【第8回】最強のバックアップ構築。S3への自動転送と一元管理への応用
第1章:トリガー条件の制御(いつ回すか)
ログローテーションを実行する「きっかけ(トリガー)」は、大きく分けて「期間」と「サイズ」の2種類があります。
1. 期間による指定
最も基本的な設定です。指定した期間が経過するとローテーションされます。
| ディレクティブ | 意味 | 用途例 |
|---|---|---|
| daily | 毎日 | アクセスログ、システムログなど標準的な用途。 |
| weekly | 毎週 | 更新頻度の低いエラーログや、yum/dnfのログなど。 |
| monthly | 毎月 | 長期的な統計用データなど。 |
| yearly | 毎年 | ほとんど更新されないアーカイブ用ログ。 |
2. サイズによる指定
ログファイルの大きさが指定値を超えた場合にローテーションします。
期間指定よりも優先度が高く、突発的なログ増加に対応できます。
| ディレクティブ | 意味 |
|---|---|
| size 100M | 100MBを超えたらローテーションする。期間に関係なく実行される。 |
| minsize 10M | 期間(dailyなど)が経過し、かつ 10MBを超えていたらローテーションする。 |
| maxsize 1G | 期間(dailyなど)が経過していなくても、1GBを超えたらローテーションする。 |
単位は k (キロバイト)、M (メガバイト)、G (ギガバイト) が使えます。
⚠️ 重要:cronの実行頻度に注意
「size 100M」と設定しても、logrotate自体がcronで「1日1回」しか動いていなければ、チェックも1日1回です。
朝の時点で99MBだったログが、昼に500MBになっても、翌朝のチェックまではローテーションされません。
サイズベースで厳密に管理したい場合は、/etc/cron.hourly/ にlogrotateのスクリプトをコピーするなどして、実行頻度を上げる必要があります。
期間とサイズの複合技
よくある勘違いが「daily と size を両方書いたらどうなるの?」という点です。
daily maxsize 100M
この場合、「1日が経過するか、または 100MBを超えたら」ローテーションされます。
つまり、普段は毎日回りますが、ログが爆発して1日で100MBを超えた場合は、その時点で(次回のcron実行時に)回ります。
第2章:保存世代の管理(いつ消すか)
ローテーションした古いログを「どれだけ残すか」の設定です。
ディスク容量を守るための生命線です。
1. 回数による指定 (rotate)
最も一般的な方法です。「何回分」残すかを指定します。
daily rotate 7
この場合、「毎日回して、7世代(7日分)残す」となります。
8日目になると、一番古いログが削除されます。
計算例:
daily + rotate 365 = 1年分
weekly + rotate 4 = 約1ヶ月分
2. 日数による指定 (maxage)
回数ではなく「日数」で寿命を決めます。
maxage 30
「ローテーションされたログのうち、30日以上経過したものを削除する」という設定です。rotate と併用した場合、どちらかの条件を満たした時点で削除されます。
例えば rotate 100 maxage 10 と設定した場合、ログが100個溜まっていなくても、10日過ぎたログは消されます。
3. メールで送信する (mail)
削除される代わりに、指定したメールアドレスにログを送信する設定もあります。
mail admin@example.com mailfirst # 最新のローテートログを送る # または maillast # 削除される直前のログを送る(デフォルト)
ただ、最近はログが巨大化しており、メールサーバーを圧迫するため、あまり使われません。
第8回で紹介する「S3への転送」などのほうが現代的です。
第3章:ファイル名のカスタマイズ(dateext)
デフォルト設定では、ログファイルは access.log.1, access.log.2 … という連番になります。
しかし、これには大きな欠点があります。
- 中身がわからない:
.1が昨日のログなのか、一昨日のログなのか、パッと見で判別できない。 - リネーム負荷: ローテーションのたびに、
.1を.2に、.2を.3に…とすべてのファイル名を変更する処理が走る。
日付を付与する (dateext)
この問題を解決するのが dateext オプションです。
ファイル名に日付が入るようになります。
dateext
結果: access.log-20260120
これなら、「いつのログか」が一目瞭然ですし、過去のファイル名を変更する必要がないため、ディスクI/Oへの負荷も下がります。
日付フォーマットの変更 (dateformat)
デフォルトの日付形式は -%Y%m%d(ハイフン+年月日)ですが、自由に変更できます。
dateformat .%Y-%m-%d
結果: access.log.2026-01-20
%Y (年), %m (月), %d (日), %s (UNIX時間) などが使えます。
※ただし、dateformat を使うと、logrotateが「これはログファイルだ」と認識できなくなる場合があるため、設定には注意が必要です。
第4章:圧縮オプション(compress)
テキストデータであるログは、圧縮するとサイズが1/10以下になることも珍しくありません。
ディスク容量節約のために、圧縮設定は必須です。
基本の圧縮
compress
デフォルトでは gzip 形式(.gz)で圧縮されます。
遅延圧縮 (delaycompress)
これが非常に重要です。compress とセットで delaycompress を指定すると、「1つ前の世代は圧縮せず、2つ前の世代から圧縮する」ようになります。
なぜ必要か?
ログローテーション直後、Webサーバーなどのプログラムがまだ「古いログファイル」を掴んで書き込み続けている可能性があります。
その状態でいきなり gzip してしまうと、書き込みエラーが発生したり、ログが破損したりします。delaycompress を使えば、1世代分(1日分)はそのままのテキストファイルで残るため、安全に切り替わることができます。
compress delaycompress
結果:
access.log (現在)
access.log.1 (昨日・非圧縮)
access.log.2.gz (一昨日・圧縮)
access.log.3.gz …
第5章:空ファイルとエラーの扱い
細かい挙動を制御するオプションです。
ファイルがない時の挙動 (missingok)
指定したログファイルが存在しない場合、デフォルトではエラーが出てlogrotateが止まります。missingok を書くと、ファイルがなくても無視して次に進みます。
ファイルが空の時の挙動 (notifempty / ifempty)
- notifempty: ログの中身が空(0バイト)なら、ローテーションしません。無駄な空ファイル(access.log.1.gzなど)が増えるのを防げます。
- ifempty: 空でも強制的にローテーションします(デフォルト)。「毎日必ずファイルを作成したい」場合に便利です。
第6章:実践レシピ集
ここまで学んだ知識を組み合わせて、よくある要件に対応する設定例を作ってみましょう。
ケース1:アクセスが多いWebサーバー
要件:
・基本は毎日ローテート。
・ただし、100MBを超えたらすぐ回したい。
・30日分保存。
・圧縮して容量節約。
/var/log/httpd/*log {
daily
maxsize 100M
rotate 30
missingok
notifempty
compress
delaycompress
dateext
create 644 root root
sharedscripts
postrotate
/bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
endscript
}
ケース2:コンプライアンス重視の長期保存
要件:
・監査のため、ログは消さずに3年間(1095日)保存。
・ファイル名に日付を入れて管理しやすくする。
・古いログは圧縮。
/var/log/audit/audit.log {
daily
rotate 1095
dateext
compress
delaycompress
missingok
# 監査ログなどは copytruncate が安全な場合が多い(第3回で詳説)
copytruncate
}
まとめ:設定ファイルは「サーバーの健康診断書」
お疲れ様でした!
これで、logrotateの設定オプションを一通り使いこなせるようになりました。
今回の重要ポイント:
sizeとdailyを組み合わせれば、容量溢れを防げる。rotateで保存期間を決め、compressで容量を節約する。dateextを使うと、いつのログか一目で分かるようになる。delaycompressはプログラムの書き込みエラーを防ぐために必須。
しかし、設定ファイルを書いただけでは安心できません。
実は、ログローテートには「設定通りに書いたのに、ログが消えてしまった」「新しいログに書き込まれない」という恐ろしい落とし穴が存在します。
その原因の9割は、次回のテーマである「ファイルの切り替え方式」にあります。
次回、第3回は「『ログが消えた!?』を防ぐ。copytruncateとcreateの決定的な違いとiノードの秘密」です。
Linuxのファイルシステムの裏側にある「iノード」を理解し、アプリケーションに合わせた正しいローテーション方式を選ぶ方法を解説します。
これを知らないと、本番環境でログを消失させる事故を起こしますよ。お楽しみに!
▼ サーバー管理の実践力を高める ▼
ログ設定を試すなら
「VPS」で自分専用環境
運用保守スキルを年収に
「ITエンジニア転職」

コメント