LogrotateによるLinuxでのログローテーション: 深夜のディスク救出作戦

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

背景と必要性:ログが午前2時にサーバーをクラッシュさせる時

午前2時にシステムエラーの電話を受け、ハードディスクが一杯でデータを書き込めないという経験はありませんか?私はその感覚を経験しました。プロダクションサーバー、特に私が過去3年間管理してきたVPSでは、ログファイルが非常に速く肥大化する可能性があります。これらはシステムとアプリケーションの貴重な記録であり、活動の追跡、エラーの発見、イベントの理解に役立ちます。

しかし、注意深く管理しないと、これらのログファイルはすぐにディスク容量を使い果たします。私はまだ覚えています、WordPressとNginxを実行しているサーバーが絶えず502エラーを報告していました。確認すると、Nginxのログファイルは数十GBに達しており、syslogも同様でした。

結果としてディスクが一杯になり、システムはセッションやキャッシュを含め、これ以上データを書き込めなくなり、長時間のダウンタイムを引き起こしました。3年間で10以上のLinux VPSを管理してきた経験から、プロダクション環境に適用する前にすべての変更を注意深く確認する必要があると結論付けました。特にログのような細かい点においては重要です。**Logrotate**こそが、この問題の解決策です。

Logrotateは、ログファイルを自動的にローテーション (rotate)、圧縮 (compress)、削除 (remove)、そして送信 (mail) するように設計されたユーティリティです。これにより、古くて過度に大きなログファイルによるシステムへの過負荷を防ぎ、同時に検査に必要なログ履歴を保持します。Logrotateがなければ、同様のインシデントのために再び徹夜することになるかもしれません。

LinuxでのLogrotateのインストール

通常、ほとんどの人気のあるLinuxディストリビューションには、すでにlogrotateがインストールされています。もしサーバーにまだインストールされていない場合は、インストールは非常に簡単です。

Debian/Ubuntuの場合:


sudo apt update
sudo apt install logrotate

CentOS/RHEL/Fedoraの場合:


sudo yum install logrotate
# または新しいバージョンでは
sudo dnf install logrotate

インストール後、logrotateは通常、cronjobまたはsystemdタイマーを介して自動的にアクティブになります。その定期的な活動は、/etc/cron.daily/または/etc/systemd/system/timers.target.wants/(systemdの場合)にある設定ファイルを見ることで確認できます。

Logrotateの詳細設定

Logrotateは主に2種類の構成ファイルを使用します。

  • /etc/logrotate.conf: 全体的な設定ファイルで、デフォルト設定と他の個々の設定ファイルへの参照が含まれます。
  • /etc/logrotate.d/: 各アプリケーションまたはサービス用の個別の構成ファイルを含むディレクトリです。NginxApache、MySQL、またはPythonアプリケーションなどのカスタム構成ファイルを作成するのに理想的な場所です。

全体的な設定ファイル: /etc/logrotate.conf

このファイルを開くと、デフォルトの構成行が表示されます。


sudo cat /etc/logrotate.conf

# Logrotate.confはシステム全体のデフォルト構成ファイルです。
# 詳細については man logrotate を参照してください。

monthly             # ログを毎月ローテーションする
rotate 4            # 古いローテーションされたバージョンを4つ保持する
create              # ローテーション後に新しいログファイルを作成する
include /etc/logrotate.d  # このディレクトリ内の設定ファイルを含める

/var/log/wtmp {
    missingok
    monthly
    create 0664 root utmp
    rotate 1
}

/var/log/btmp {
    missingok
    monthly
    create 0600 root utmp
    rotate 1
}

# その他...

以下に、いくつかの重要なディレクティブについて説明します。

  • daily, weekly, monthly, yearly: ログのローテーション頻度を定義します。必要に応じてオプションを選択してください。
  • rotate N: 保持するローテーションされたログの数を指定します。例えば、rotate 4は最も古い4つのバージョンを保持します。
  • create [mode owner group]: 古いファイルがローテーションされた後、パーミッション (mode)、所有者 (owner)、グループ (group) を指定して新しい空のログファイルを作成します。指定しない場合、元のファイルのパーミッションが保持されます。
  • include /path/to/directory: Logrotateに、指定されたディレクトリから追加の構成ファイルを読み込むように指示します。

アプリケーションごとの設定: /etc/logrotate.d/

ここでは、logrotateを各特定のアプリケーションに合わせてカスタマイズします。このディレクトリ内の各ファイルは、1つ以上のファイルのログをローテーションする方法を定義します。例えば、Nginxの設定ファイルを作成します。


sudo nano /etc/logrotate.d/nginx

/var/log/nginx/*.log {
    daily             # ログを毎日ローテーションする
    missingok         # ログファイルが存在しない場合はエラーを報告しない
    rotate 7          # 古いログファイルを7つ保持する(1週間相当)
    compress          # ディスク容量を節約するために古いログファイルを圧縮する
    delaycompress     # 最新のログファイルの圧縮を次のサイクルまで遅らせる
    notifempty        # ファイルが空の場合はログをローテーションしない
    create 0640 www-data adm # 0640のパーミッション、所有者www-data、グループadmで新しいログファイルを作成する
    sharedscripts     # 設定されたすべてのファイルに対してpostrotate/prerotateスクリプトを一度だけ実行する
    postrotate        # ログローテーション後に実行するスクリプトを開始する
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript         # postrotateスクリプトの終了
}

重要なディレクティブに関する追加の説明:

  • /var/log/nginx/*.log: ローテーションするログファイルへのパスです。ワイルドカード*を使用できます。
  • missingok: ログファイルが存在しない場合、logrotateはエラーを報告せずにスキップします。これは、常にログを生成するわけではないアプリケーションに役立ちます。
  • compress: ローテーションされたログファイルをgzip (デフォルト) で圧縮し、大幅なディスク容量の節約に役立ちます。例: access.log.1access.log.1.gzになります。
  • delaycompress: compressを使用する場合、最新のログファイル (.1で終わる) はすぐに圧縮されず、次のローテーションサイクルまで待機します。これは、ローテーション後にアプリケーションがまだ.1ファイルを読み込んでいる場合に有利です。
  • notifempty: 空のログファイルをLogrotateがローテーションするのを防ぎます。
  • postrotate / endscript: このブロック内のコマンドは、logrotateがファイルのローテーションを完了したに実行されます。Nginxの場合、ローテーション後に新しいログファイルを開くためにUSR1シグナルを送信する必要があります。そうしないと、Nginxは名前が変更された古いログファイルへの書き込みを続行します。
  • prerotate / endscript: postrotateと同様ですが、これらのコマンドはログローテーションのに実行されます。
  • dateext: ローテーションされたログファイル名に日付を追加します。例: access.log-20240310.gz。この機能は、ログファイルの日付を簡単に特定するのに役立ちます。
  • mail [email protected]: ローテーションされたログファイルを指定されたメールアドレスに送信します。
  • olddir /path/to/archive: ローテーションされたログファイルを元のファイルと同じディレクトリに保持する代わりに、別のアーカイブディレクトリに移動します。

prerotateおよびpostrotateスクリプトには特に注意が必要です。新しいログファイルを認識するためにリロードまたは再起動を必要とするアプリケーション (例: Nginx、Apache、PHP-FPM…) の場合、シグナルを送信したり、再起動コマンドを実行したりすることは非常に重要です。これらを無視すると、ログは名前が変更された古いファイルに書き込みを続けるか、さらに悪いことに、ログの記録を完全に停止する可能性があります!

Logrotateのテストと監視

ドライランの実行

これは、新しい構成をプロダクション環境にデプロイする前にスキップできないステップです。システムに影響を与えることなく、すべてが期待どおりに機能することを確認するために、常にドライランを実行してください。


sudo logrotate -d /etc/logrotate.conf

このコマンドは、logrotateの動作をシミュレートしますが、実際にファイルは変更しません。各チェック、ログローテーションの決定、および実行されるコマンドの詳細が表示されます。

個別の構成ファイル、例えばNginxの設定をテストするには:


sudo logrotate -d /etc/logrotate.d/nginx

強制実行

直ちに確認する必要がある場合や、緊急にディスク容量を解放する必要がある場合:


sudo logrotate -f /etc/logrotate.conf

このコマンドは、頻度条件 (daily, weekly) が満たされているかどうかに関係なく、logrotateに強制的にログローテーションを実行させます。プロダクション環境で-fを使用する場合は、特に多くのログがアクティブなシステムでは注意が必要です。サービスの中断を避けるために、postrotateスクリプトを常に慎重に確認してください。

ステータスとスケジュールの確認

Logrotateは通常、cronまたはsystemdタイマーを介して定期的に実行されます。その活動履歴は以下で確認できます。

  • /var/lib/logrotate/status: このファイルには、各ログファイルが最後にローテーションされた日時に関する情報が保存されます。

sudo cat /var/lib/logrotate/status

logrotateがどのように実行され、完了したかを知るために、システムのログを確認することもできます。


journalctl -u logrotate.timer
journalctl -u logrotate.service

古いシステムまたは従来のcronjobの場合:


sudo grep logrotate /var/log/syslog

または、CentOS/RHELで/var/log/cronファイルを確認します。

監視とトラブルシューティング

logrotateが期待どおりに機能しない場合は、次の手順を実行します。

  1. ステータスファイルを確認: /var/lib/logrotate/statusを見て、ログが最後にローテーションされた日時を確認します。
  2. 権限を確認: logrotateがログを含むディレクトリに読み書きする権限を持ち、postrotate/prerotateスクリプトを実行する権限があることを確認します。
  3. logrotateのログを確認: journalctlまたはシステムログのgrepを使用してエラーを探します。
  4. ドライランを実行: これは、実際の問題がシステムに影響を与える前に問題をシミュレートし、検出するための最も効果的な方法です。

ログ管理は、システム運用における不可欠な部分です。logrotateを正しく理解して構成することで、サーバーの安定性を維持するだけでなく、ディスクがいっぱいになることによるトラブルシューティングの徹夜を避けることができます。

Share: