【logrotate講座 第4回】ディスク容量を極限まで節約!圧縮設定と日付付与のテクニック完全ガイド

「テキストファイル」は、空気のようなものだ。

こんにちは!「LINUX工房」管理人の「リナックス先生」です。
前回は、logrotateの鬼門である「copytruncateとcreateの違い」について、iノードの仕組みからディープに解説しました。

さて、ログローテーションが正常に動くようになると、次に気になるのが「ディスク容量」です。
Webサーバーのアクセスログや、アプリケーションのデバッグログは、1日で数ギガバイトになることも珍しくありません。
これをそのまま保存していたら、いくらHDDやSSDがあっても足りません。

コウ君

先生、またディスクアラートが鳴りました…。
ログローテートの設定はしたんですけど、過去のログファイル(access.log.1, access.log.2…)が巨大すぎて、結局容量を食ってるんです。
これ、zipとかで圧縮して小さくできないんですか?

リナックス先生

もちろんできるわ!
ログファイルのような「テキストデータ」は、圧縮すると驚くほど小さくなるの。
logrotateには強力な圧縮機能がついているから、設定一行でサイズを10分の1以下にできるわよ。
今回は、ディスク容量を節約する「圧縮テクニック」と、ログを見やすくする「日付管理」について極めましょう!

本記事では、AlmaLinux 9 をベースに、logrotateの圧縮オプションの詳細、トラブルを防ぐ delaycompress の仕組み、さらに高圧縮な xz 形式へのカスタマイズ方法までを徹底解説します。

🔄 logrotate完全攻略講座(バックナンバー)

現在地:【第4回】ディスク容量を極限まで節約!圧縮設定と日付付与のテクニック


第1章:ログ圧縮の基本「compress」

ログファイルの中身は、同じような単語(日付、IPアドレス、URLなど)の繰り返しです。
こうしたデータは圧縮アルゴリズムにとって「ご馳走」であり、劇的にサイズを縮小できます。

基本設定

設定ファイルに compress と書くだけです。

/var/log/myapp/*.log {
    daily
    rotate 7
    compress
}

これにより、ローテーションされた過去のログは自動的に gzip 形式で圧縮され、拡張子 .gz が付与されます。

  • app.log (現在)
  • app.log.1.gz (昨日)
  • app.log.2.gz (一昨日)

圧縮効果の実測

一般的なアクセスログの場合、サイズはどれくらい変わるのでしょうか?

# 元のサイズ: 100MB
ls -lh access.log
-rw-r--r-- 1 root root 100M  1月 20 12:00 access.log

# 圧縮後: 7MB (約93%削減!)
ls -lh access.log.1.gz
-rw-r--r-- 1 root root 7.0M  1月 19 23:59 access.log.1.gz

このように、テキストログは 1/10 〜 1/15 程度まで圧縮できます。
100GB分のログを保存する場合でも、圧縮すれば10GB以下で済む計算です。


第2章:なぜ「delaycompress」が必要なのか?

前回(第3回)の記事で、「create モードを使うときは delaycompress もセットで使うべき」と説明しました。
その理由を、技術的な視点から深掘りします。

圧縮のタイミングとリスク

logrotateが compress オプションで圧縮処理を行うのは、「ファイルのリネーム直後、postrotateスクリプトの実行前(または同時)」です。

もし、ApacheなどのWebサーバーが、リネームされた access.log.1 をまだ掴んで書き込み続けている最中に、logrotateがそれを gzip で圧縮し始めてしまったらどうなるでしょうか?

  1. ログ破損: テキストデータを書き込んでいるファイルが、いきなりバイナリ形式(gzip)に変換されるため、ファイル構造が壊れます。
  2. 書き込みエラー: アプリケーション側が「書き込めない!」とエラーを出して停止する可能性があります。
  3. ログ消失: 切り替えの瞬間のログが圧縮処理に巻き込まれて消える可能性があります。

delaycompress の救済措置

delaycompress を指定すると、「最新の過去ログ(1世代目)は圧縮せず、2世代目になった時に初めて圧縮する」という挙動になります。

    compress
    delaycompress

結果:

  • access.log (現在:書き込み中)
  • access.log.1 (昨日:非圧縮 ← ここが重要!)
  • access.log.2.gz (一昨日:圧縮済み)
  • access.log.3.gz

これにより、access.log.1 への書き込みが完全に終了し、アプリケーションが新しいファイルに移行したことが確実になってから(翌日のローテーション時に)圧縮が行われるため、安全性が担保されるのです。

⚠️ 注意点
delaycompresscompress オプションと一緒に使わないと意味がありません。
また、copytruncate モードの場合はファイルの切り替え方法が異なるため、厳密には必須ではありませんが、安全のために付けておいて損はありません。


第3章:圧縮形式のカスタマイズ(gzip vs xz)

デフォルトの gzip はバランスの良い圧縮形式ですが、さらに高い圧縮率を求めるなら xz 形式を使うことも可能です。

圧縮形式の比較

形式 拡張子 圧縮率 CPU負荷 logrotateデフォルト
gzip .gz 普通 軽い
bzip2 .bz2 高い 重い ×
xz .xz 最強 とても重い ×

xzgzip よりもさらに30%ほどサイズを小さくできますが、圧縮処理に時間がかかります。

logrotateで xz を使う設定

compresscmd オプションを使って、使用するコマンドを指定します。

/var/log/backup/*.log {
    daily
    rotate 30
    compress
    # 圧縮コマンドを指定
    compresscmd /usr/bin/xz
    # 解凍コマンドを指定
    uncompresscmd /usr/bin/unxz
    # 拡張子を指定
    compressext .xz
    # xzのオプション(-9は最大圧縮)
    compressoptions -9
}

あまり頻繁にアクセスしないアーカイブ用のログや、ディスク容量が極端に少ない環境では有効なテクニックです。


第4章:圧縮ログの中身を見る方法(zcat, zgrep)

「圧縮すると中身が見れなくて不便!」と思っていませんか?
Linuxには、圧縮ファイルを解凍せずに中身を確認できる便利なコマンド群があります。

1. zcat / xzcat(中身を表示)

cat の圧縮版です。

# gzipの場合
zcat access.log.2.gz | head -n 5

# xzの場合
xzcat access.log.2.xz | head -n 5

2. zgrep / xzgrep(検索)

grep の圧縮版です。これが最強に便利です。
「先週のエラーログから特定のIPを探したい」といった時に、わざわざ解凍する必要はありません。

# 圧縮ログの中から "error" を検索
zgrep "error" /var/log/httpd/access.log.*.gz

3. zless / xzless(ページャー)

less の圧縮版です。長いログをスクロールして読むのに使います。

zless access.log.2.gz

第5章:日付で管理する「dateext」の真価

第2回でも紹介しましたが、dateext オプションはログ管理の「視認性」を劇的に向上させます。

連番管理(デフォルト)の問題点

access.log.1, access.log.2, access.log.3
これらは、ローテーションのたびに名前が変わります。
「昨日の .1」は、明日には .2 になってしまいます。
これでは、「2026年1月1日のログを調査したい」と思った時に、どれがそのファイルなのか計算しなければなりません。

日付管理 (dateext) のメリット

    dateext
    dateformat -%Y%m%d

このように設定すると、ファイル名は access.log-20260120 のようになります。
これなら一目瞭然ですし、一度付いたファイル名は(削除されるまで)変わりません。
バックアップを取る際も、「ファイル名が変わらない」というのは大きなメリットです。

dateformat のカスタマイズ

デフォルトは -%Y%m%d ですが、好みに合わせて変更できます。

  • dateformat .%Y-%m-%daccess.log.2026-01-20
  • dateformat _%saccess.log_1768876800 (UNIX時間)

※ただし、/ などのディレクトリ区切り文字は使えません。


第6章:トラブルシューティング「dateextの罠」

dateext は便利ですが、独自の落とし穴があります。

現象:1日に複数回ローテーションするとエラーになる

dateext を使っている状態で、手動テスト(-f)を行ったり、サイズ指定(size)で1日に2回以上ローテーションが発生しようとすると、エラーになります。

エラー内容:
destination /var/log/httpd/access.log-20260120 already exists, skipping rotation

原因:
ファイル名に「日付」しか入っていないため、同じ日に2回目を回そうとすると、同じファイル名(access.log-20260120)が既に存在してしまい、上書き防止のためにスキップされるのです。

対策:dateformat に「時・分」を入れる…?

「じゃあ日付に時間まで入れればいいじゃないか」と思うかもしれませんが、実は logrotate の仕様上、dateformat は「日単位」での管理を前提としており、推奨されません。
1日に複数回回る可能性がある(サイズ指定を使う)場合は、素直に dateext を使わない(連番管理にする) のが最も安全な解決策です。


第7章:実践レシピ「最強の節約設定」

これまでの知識を総動員して、「ディスク容量をとにかく節約しつつ、管理もしやすい」最強の設定ファイルを作ってみましょう。

要件

  • ログは毎日ローテーション。
  • 60日分保存。
  • ファイル名には日付をつける。
  • 圧縮率は最強の xz を使用。
  • 書き込み中のトラブルを防ぐ。

設定例 (/etc/logrotate.d/myapp)

/var/log/myapp/*.log {
    daily
    missingok
    rotate 60
    notifempty
    
    # 日付付与
    dateext
    dateformat -%Y-%m-%d
    
    # 圧縮設定(xz使用)
    compress
    compresscmd /usr/bin/xz
    uncompresscmd /usr/bin/unxz
    compressext .xz
    compressoptions -9
    
    # 安全対策
    delaycompress
    
    # 権限まわり
    create 640 appuser appgroup
    sharedscripts
    postrotate
        /bin/systemctl reload myapp.service > /dev/null 2>/dev/null || true
    endscript
}

まとめ:ログは小さく、賢く残せ

お疲れ様でした!
これで、あなたのサーバーのログは、美しく整理され、極限まで小さく圧縮されるようになりました。

今回の重要ポイント:

  • compress でログサイズは1/10以下になる。
  • create モードを使うなら delaycompress は必須セット。
  • xz 形式を使えばさらに圧縮できるが、CPU負荷に注意。
  • dateext は便利だが、1日複数回のローテーションには向かない。
  • 圧縮ログは zgrepzcat でそのまま読める。

ここまでで、「ログをどう回すか」「どう保存するか」は完璧です。
しかし、logrotateにはもう一つ重要な役割があります。
それは、ログを回した後に「アプリケーションに何らかのアクションをさせる」ことです。

次回、第5回は「再起動を自動化せよ!postrotateスクリプトによるプロセス制御」です。
「Apacheをリロードする」「古いログをS3にアップロードする」「管理者にSlack通知を送る」といった、ローテーション後の処理をスクリプトで自動化するテクニックを深掘りします。
運用自動化の真髄に迫ります。お楽しみに!

▼ エンジニアとしての引き出しを増やす ▼

圧縮効率を試す
「VPS」で自分専用環境

おすすめVPSを見る

サーバー運用スキルを年収に
「ITエンジニア転職」

転職エージェントを見る

コメント