症状

nginxのログファイルが肥大化し続け、ディスク容量が圧迫される。または df -h/var/log が100%近くになっている。

結論:まずこれを確認

  1. ls -lh /var/log/nginx/ でログファイルのサイズを確認
  2. cat /etc/logrotate.d/nginx でlogrotate設定の存在を確認
  3. systemctl status logrotate または /var/lib/logrotate/status で最終実行日時を確認

トラブルシューティングフロー

    flowchart TD
    A[ディスク容量が逼迫] --> B{nginxログが原因?}
    B -->|No| Z[他のログを確認]
    B -->|Yes| C{logrotate設定あり?}
    C -->|No| D[logrotate設定を作成]
    C -->|Yes| E{logrotateは実行されている?}
    E -->|No| F[cronまたはtimerを確認]
    E -->|Yes| G{ログは圧縮・削除されている?}
    G -->|No| H[postrotateを確認]
    G -->|Yes| I[rotateの世代数を確認]
    H --> J[nginx再読み込みを確認]
  

よくある原因

  • logrotate設定ファイルがない - パッケージインストール時に作成されないケースがある
  • postrotateでnginx再読み込みが失敗 - nginxがログファイルを掴み続け、新しいファイルに書き込まれない
  • logrotateのcron/timerが無効 - systemdのlogrotate.timerが停止している
  • copytruncateとpostrotateの混在 - 設定の矛盾でローテーションが中途半端になる
  • 権限の問題 - ローテーション後のファイルにnginxが書き込めない
  • sharedscriptsの指定漏れ - 複数ログファイルで毎回postrotateが実行されエラーになる
  • ディスクIOが高くローテーション処理がタイムアウト - 大容量ログで処理が完了しない

確認手順

ステップ1: ログファイルのサイズを確認する

    ls -lh /var/log/nginx/
du -sh /var/log/nginx/
  

🔍 チェックポイント: access.logやerror.logが数GB以上ある場合は異常

ステップ2: logrotate設定ファイルを確認する

    cat /etc/logrotate.d/nginx
  

🔍 チェックポイント: ファイルが存在し、以下の要素が含まれているか

  • 対象パス(/var/log/nginx/*.log
  • rotate の世代数
  • daily / weekly などの頻度
  • postrotate セクション

ステップ3: logrotateの最終実行日時を確認する

    # Debian/Ubuntu系
cat /var/lib/logrotate/status | grep nginx

# RHEL/CentOS系
cat /var/lib/logrotate/logrotate.status | grep nginx
  

🔍 チェックポイント: 日付が古い(1日以上前)場合はlogrotate自体が動いていない可能性

ステップ4: logrotateを手動実行してテストする

    # ドライラン(実際には実行しない)
logrotate -d /etc/logrotate.d/nginx

# 強制実行(テスト環境のみ)
logrotate -f /etc/logrotate.d/nginx
  

🔍 チェックポイント: エラーメッセージが出力されないか確認

ステップ5: postrotateの動作を確認する

    # nginx設定テスト
nginx -t

# nginx再読み込み(postrotateで実行されるコマンド)
systemctl reload nginx
# または
kill -USR1 $(cat /var/run/nginx.pid)
  

🔍 チェックポイント: エラーなく完了するか。pidファイルのパスが正しいか

ステップ6: cronまたはsystemd timerを確認する

    # systemdの場合
systemctl status logrotate.timer
systemctl list-timers | grep logrotate

# cronの場合
ls -la /etc/cron.daily/logrotate
  

🔍 チェックポイント: timerがactiveか、cronファイルに実行権限があるか

ステップ7: 緊急対応としてログを削除する

    # ディスクが満杯で緊急の場合
# 注意: 削除前にnginxを再読み込みする必要がある

# 古いログを圧縮
gzip /var/log/nginx/access.log.1

# または現在のログを切り詰め(nginx再読み込み不要)
truncate -s 0 /var/log/nginx/access.log
  

🔍 チェックポイント: df -h で容量が回復したか確認

NG行動(やってはいけないこと)

  • ログファイルを直接rm -fで削除する - nginxが削除されたファイルを掴み続け、ディスク容量が解放されない
  • nginx停止中に大量のログを削除する - 再起動時にエラーログが書けずnginxが起動しない可能性
  • logrotate設定を変更後にテストせずに放置 - 次回のローテーションまで問題に気づかない
  • copytruncateを安易に追加する - ログの欠損が発生する可能性がある

よくある質問(FAQ)

Q1: ログローテーション後も古いファイルのディスク容量が解放されない

A: nginxプロセスがファイルを掴み続けている可能性がある。lsof | grep deleted で確認し、該当プロセスを再読み込みまたは再起動する。

Q2: copytruncateとpostrotateのどちらを使うべき?

A: postrotate(デフォルト)を推奨。copytruncateはコピー中のログが欠損する可能性がある。postrotateでnginxに kill -USR1 または systemctl reload を送る方式が一般的。

Q3: ログローテーションの頻度や保持世代数の目安は?

A: トラフィック量による。一般的には daily + rotate 14(2週間保持)+ compress が目安。ディスク容量と調査時に必要なログ期間のバランスで決定する。

関連するエラー・症状

  • (関連記事準備中)
  • (関連記事準備中)
  • (関連記事準備中)

解決しない場合

  • nginx公式ドキュメント: https://nginx.org/en/docs/control.html
  • logrotate manページ: man logrotate
  • 確認すべきログ:
    • /var/log/syslog または /var/log/messages(logrotateのエラー)
    • journalctl -u logrotate(systemd環境)
  • 次に調べるキーワード: nginx log rotation not working, logrotate postrotate failed, lsof deleted files disk space