【logrotate講座 第2回】設定ファイルの魔術書!ローテーション周期・サイズ・保存期間の完全制御

「なんとなく」の設定が、半年後に悲劇を生む。

こんにちは!「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の設定オプションを一通り使いこなせるようになりました。

今回の重要ポイント:

  • sizedaily を組み合わせれば、容量溢れを防げる。
  • rotate で保存期間を決め、compress で容量を節約する。
  • dateext を使うと、いつのログか一目で分かるようになる。
  • delaycompress はプログラムの書き込みエラーを防ぐために必須。

しかし、設定ファイルを書いただけでは安心できません。
実は、ログローテートには「設定通りに書いたのに、ログが消えてしまった」「新しいログに書き込まれない」という恐ろしい落とし穴が存在します。
その原因の9割は、次回のテーマである「ファイルの切り替え方式」にあります。

次回、第3回は「『ログが消えた!?』を防ぐ。copytruncateとcreateの決定的な違いとiノードの秘密」です。
Linuxのファイルシステムの裏側にある「iノード」を理解し、アプリケーションに合わせた正しいローテーション方式を選ぶ方法を解説します。
これを知らないと、本番環境でログを消失させる事故を起こしますよ。お楽しみに!

▼ サーバー管理の実践力を高める ▼

ログ設定を試すなら
「VPS」で自分専用環境

おすすめVPSを見る

運用保守スキルを年収に
「ITエンジニア転職」

転職エージェントを見る

コメント